From 6e4a9b999ba40e77bbd449bb5feaf6332335b6bb Mon Sep 17 00:00:00 2001 From: Robert Fratto Date: Thu, 4 Jan 2024 08:45:07 -0500 Subject: [PATCH 01/68] prometheus.exporter.kafka: use correct secret type (#6046) Use rivertypes.Secret for sensitive fields instead of Prometheus' secret type. Fixes #6044. --- CHANGELOG.md | 16 +++--- component/prometheus/exporter/kafka/kafka.go | 49 ++++++++++--------- .../prometheus/exporter/kafka/kafka_test.go | 12 +++++ .../internal/build/kafka_exporter.go | 3 +- 4 files changed, 48 insertions(+), 32 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b83ee4d268c..a86d9b1960f6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,8 +14,8 @@ Main (unreleased) - `otelcol.receiver.prometheus` will drop all `otel_scope_info` metrics when converting them to OTLP. (@wildum) - If the `otel_scope_info` metric has labels `otel_scope_name` and `otel_scope_version`, - their values will be used to set OTLP Instrumentation Scope name and version respectively. - - Labels of `otel_scope_info` metrics other than `otel_scope_name` and `otel_scope_version` + their values will be used to set OTLP Instrumentation Scope name and version respectively. + - Labels of `otel_scope_info` metrics other than `otel_scope_name` and `otel_scope_version` are added as scope attributes with the matching name and version. - The `target` block in `prometheus.exporter.blackbox` requires a mandatory `name` @@ -57,7 +57,7 @@ Main (unreleased) - Added links between compatible components in the documentation to make it easier to discover them. (@thampiotr) - + - Allow defining `HTTPClientConfig` for `discovery.ec2`. (@cmbrad) - The `remote.http` component can optionally define a request body. (@tpaschalis) @@ -71,8 +71,8 @@ Main (unreleased) - Added 'country' mmdb-type to log pipeline-stage geoip. (@superstes) - Azure exporter enhancements for flow and static mode, (@kgeckhart) - - Allows for pulling metrics at the Azure subscription level instead of resource by resource - - Disable dimension validation by default to reduce the number of exporter instances needed for full dimension coverage + - Allows for pulling metrics at the Azure subscription level instead of resource by resource + - Disable dimension validation by default to reduce the number of exporter instances needed for full dimension coverage - Add `max_cache_size` to `prometheus.relabel` to allow configurability instead of hard coded 100,000. (@mattdurham) @@ -81,11 +81,11 @@ Main (unreleased) ### Bugfixes - Update `pyroscope.ebpf` to fix a logical bug causing to profile to many kthreads instead of regular processes https://github.com/grafana/pyroscope/pull/2778 (@korniltsev) - + - Update `pyroscope.ebpf` to produce more optimal pprof profiles for python processes https://github.com/grafana/pyroscope/pull/2788 (@korniltsev) - In Static mode's `traces` subsystem, `spanmetrics` used to be generated prior to load balancing. - This could lead to inaccurate metrics. This issue only affects Agents using both `spanmetrics` and + This could lead to inaccurate metrics. This issue only affects Agents using both `spanmetrics` and `load_balancing`, when running in a load balanced cluster with more than one Agent instance. (@ptodev) - Fixes `loki.source.docker` a behavior that synced an incomplete list of targets to the tailer manager. (@FerdinandvHagen) @@ -94,6 +94,8 @@ Main (unreleased) - Add staleness tracking to labelstore to reduce memory usage. (@mattdurham) +- Fix issue where `prometheus.exporter.kafka` would crash when configuring `sasl_password`. (@rfratto) + ### Other changes - Bump github.com/IBM/sarama from v1.41.2 to v1.42.1 diff --git a/component/prometheus/exporter/kafka/kafka.go b/component/prometheus/exporter/kafka/kafka.go index f146c40bae3c..f68985b50d2c 100644 --- a/component/prometheus/exporter/kafka/kafka.go +++ b/component/prometheus/exporter/kafka/kafka.go @@ -9,7 +9,8 @@ import ( "github.com/grafana/agent/component/prometheus/exporter" "github.com/grafana/agent/pkg/integrations" "github.com/grafana/agent/pkg/integrations/kafka_exporter" - config_util "github.com/prometheus/common/config" + "github.com/grafana/river/rivertypes" + "github.com/prometheus/common/config" ) var DefaultArguments = Arguments{ @@ -24,28 +25,28 @@ var DefaultArguments = Arguments{ } type Arguments struct { - Instance string `river:"instance,attr,optional"` - KafkaURIs []string `river:"kafka_uris,attr,optional"` - UseSASL bool `river:"use_sasl,attr,optional"` - UseSASLHandshake bool `river:"use_sasl_handshake,attr,optional"` - SASLUsername string `river:"sasl_username,attr,optional"` - SASLPassword config_util.Secret `river:"sasl_password,attr,optional"` - SASLMechanism string `river:"sasl_mechanism,attr,optional"` - UseTLS bool `river:"use_tls,attr,optional"` - CAFile string `river:"ca_file,attr,optional"` - CertFile string `river:"cert_file,attr,optional"` - KeyFile string `river:"key_file,attr,optional"` - InsecureSkipVerify bool `river:"insecure_skip_verify,attr,optional"` - KafkaVersion string `river:"kafka_version,attr,optional"` - UseZooKeeperLag bool `river:"use_zookeeper_lag,attr,optional"` - ZookeeperURIs []string `river:"zookeeper_uris,attr,optional"` - ClusterName string `river:"kafka_cluster_name,attr,optional"` - MetadataRefreshInterval string `river:"metadata_refresh_interval,attr,optional"` - AllowConcurrent bool `river:"allow_concurrency,attr,optional"` - MaxOffsets int `river:"max_offsets,attr,optional"` - PruneIntervalSeconds int `river:"prune_interval_seconds,attr,optional"` - TopicsFilter string `river:"topics_filter_regex,attr,optional"` - GroupFilter string `river:"groups_filter_regex,attr,optional"` + Instance string `river:"instance,attr,optional"` + KafkaURIs []string `river:"kafka_uris,attr,optional"` + UseSASL bool `river:"use_sasl,attr,optional"` + UseSASLHandshake bool `river:"use_sasl_handshake,attr,optional"` + SASLUsername string `river:"sasl_username,attr,optional"` + SASLPassword rivertypes.Secret `river:"sasl_password,attr,optional"` + SASLMechanism string `river:"sasl_mechanism,attr,optional"` + UseTLS bool `river:"use_tls,attr,optional"` + CAFile string `river:"ca_file,attr,optional"` + CertFile string `river:"cert_file,attr,optional"` + KeyFile string `river:"key_file,attr,optional"` + InsecureSkipVerify bool `river:"insecure_skip_verify,attr,optional"` + KafkaVersion string `river:"kafka_version,attr,optional"` + UseZooKeeperLag bool `river:"use_zookeeper_lag,attr,optional"` + ZookeeperURIs []string `river:"zookeeper_uris,attr,optional"` + ClusterName string `river:"kafka_cluster_name,attr,optional"` + MetadataRefreshInterval string `river:"metadata_refresh_interval,attr,optional"` + AllowConcurrent bool `river:"allow_concurrency,attr,optional"` + MaxOffsets int `river:"max_offsets,attr,optional"` + PruneIntervalSeconds int `river:"prune_interval_seconds,attr,optional"` + TopicsFilter string `river:"topics_filter_regex,attr,optional"` + GroupFilter string `river:"groups_filter_regex,attr,optional"` } func init() { @@ -93,7 +94,7 @@ func (a *Arguments) Convert() *kafka_exporter.Config { UseSASL: a.UseSASL, UseSASLHandshake: a.UseSASLHandshake, SASLUsername: a.SASLUsername, - SASLPassword: a.SASLPassword, + SASLPassword: config.Secret(a.SASLPassword), SASLMechanism: a.SASLMechanism, UseTLS: a.UseTLS, CAFile: a.CAFile, diff --git a/component/prometheus/exporter/kafka/kafka_test.go b/component/prometheus/exporter/kafka/kafka_test.go index 26f321dc39fa..4209da21cb7d 100644 --- a/component/prometheus/exporter/kafka/kafka_test.go +++ b/component/prometheus/exporter/kafka/kafka_test.go @@ -107,3 +107,15 @@ func TestCustomizeTarget(t *testing.T) { require.Equal(t, 1, len(newTargets)) require.Equal(t, "example", newTargets[0]["instance"]) } + +func TestSASLPassword(t *testing.T) { // #6044 + var exampleRiverConfig = ` + kafka_uris = ["broker1"] + use_sasl = true + sasl_password = "foobar" + ` + + var args Arguments + err := river.Unmarshal([]byte(exampleRiverConfig), &args) + require.NoError(t, err) +} diff --git a/converter/internal/staticconvert/internal/build/kafka_exporter.go b/converter/internal/staticconvert/internal/build/kafka_exporter.go index 25310e35a5f4..16be4275ddce 100644 --- a/converter/internal/staticconvert/internal/build/kafka_exporter.go +++ b/converter/internal/staticconvert/internal/build/kafka_exporter.go @@ -4,6 +4,7 @@ import ( "github.com/grafana/agent/component/discovery" "github.com/grafana/agent/component/prometheus/exporter/kafka" "github.com/grafana/agent/pkg/integrations/kafka_exporter" + "github.com/grafana/river/rivertypes" ) func (b *IntegrationsConfigBuilder) appendKafkaExporter(config *kafka_exporter.Config, instanceKey *string) discovery.Exports { @@ -17,7 +18,7 @@ func toKafkaExporter(config *kafka_exporter.Config) *kafka.Arguments { UseSASL: config.UseSASL, UseSASLHandshake: config.UseSASLHandshake, SASLUsername: config.SASLUsername, - SASLPassword: config.SASLPassword, + SASLPassword: rivertypes.Secret(config.SASLPassword), SASLMechanism: config.SASLMechanism, UseTLS: config.UseTLS, CAFile: config.CAFile, From 900a0352d86d5f5e6890041516a2f2f9e20e89c0 Mon Sep 17 00:00:00 2001 From: Piotr <17101802+thampiotr@users.noreply.github.com> Date: Thu, 4 Jan 2024 14:59:45 +0100 Subject: [PATCH 02/68] Fix incorrect CPU calculation (#6047) --- docs/sources/flow/monitoring/agent-resource-usage.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/sources/flow/monitoring/agent-resource-usage.md b/docs/sources/flow/monitoring/agent-resource-usage.md index f7a44c638555..21b16106d5a3 100644 --- a/docs/sources/flow/monitoring/agent-resource-usage.md +++ b/docs/sources/flow/monitoring/agent-resource-usage.md @@ -33,7 +33,7 @@ series that need to be scraped and the scrape interval. As a rule of thumb, **per each 1 million active series** and with the default scrape interval, you can expect to use approximately: -* 1.5 CPU cores +* 0.4 CPU cores * 11 GiB of memory * 1.5 MiB/s of total network bandwidth, send and receive From cce5b03b141d8bf43ca4ab473c8f07d6d9136b3d Mon Sep 17 00:00:00 2001 From: Erik Baranowski <39704712+erikbaranowski@users.noreply.github.com> Date: Thu, 4 Jan 2024 09:20:44 -0500 Subject: [PATCH 03/68] Wire up for eventhandler integration in the static to flow converter (#6039) --- .../staticconvert/internal/build/builder.go | 7 +- .../internal/build/eventhandler.go | 98 +++++++++++++++++++ .../testdata-v2/integrations_v2.river | 20 ++++ .../testdata-v2/integrations_v2.yaml | 6 ++ .../testdata-v2/unsupported.diags | 5 +- .../testdata-v2/unsupported.river | 11 +++ .../testdata-v2/unsupported.yaml | 13 ++- converter/internal/staticconvert/validate.go | 6 +- 8 files changed, 160 insertions(+), 6 deletions(-) create mode 100644 converter/internal/staticconvert/internal/build/eventhandler.go diff --git a/converter/internal/staticconvert/internal/build/builder.go b/converter/internal/staticconvert/internal/build/builder.go index 0f92fa327363..58fedf6225c2 100644 --- a/converter/internal/staticconvert/internal/build/builder.go +++ b/converter/internal/staticconvert/internal/build/builder.go @@ -42,7 +42,8 @@ import ( app_agent_receiver_v2 "github.com/grafana/agent/pkg/integrations/v2/app_agent_receiver" blackbox_exporter_v2 "github.com/grafana/agent/pkg/integrations/v2/blackbox_exporter" common_v2 "github.com/grafana/agent/pkg/integrations/v2/common" - "github.com/grafana/agent/pkg/integrations/v2/metricsutils" + eventhandler_v2 "github.com/grafana/agent/pkg/integrations/v2/eventhandler" + metricsutils_v2 "github.com/grafana/agent/pkg/integrations/v2/metricsutils" snmp_exporter_v2 "github.com/grafana/agent/pkg/integrations/v2/snmp_exporter" vmware_exporter_v2 "github.com/grafana/agent/pkg/integrations/v2/vmware_exporter" "github.com/grafana/agent/pkg/integrations/windows_exporter" @@ -229,13 +230,15 @@ func (b *IntegrationsConfigBuilder) appendV2Integrations() { case *blackbox_exporter_v2.Config: exports = b.appendBlackboxExporterV2(itg) commonConfig = itg.Common + case *eventhandler_v2.Config: + b.appendEventHandlerV2(itg) case *snmp_exporter_v2.Config: exports = b.appendSnmpExporterV2(itg) commonConfig = itg.Common case *vmware_exporter_v2.Config: exports = b.appendVmwareExporterV2(itg) commonConfig = itg.Common - case *metricsutils.ConfigShim: + case *metricsutils_v2.ConfigShim: commonConfig = itg.Common switch v1_itg := itg.Orig.(type) { case *azure_exporter.Config: diff --git a/converter/internal/staticconvert/internal/build/eventhandler.go b/converter/internal/staticconvert/internal/build/eventhandler.go new file mode 100644 index 000000000000..bf816d6d451a --- /dev/null +++ b/converter/internal/staticconvert/internal/build/eventhandler.go @@ -0,0 +1,98 @@ +package build + +import ( + "fmt" + + "github.com/grafana/agent/component/common/loki" + flow_relabel "github.com/grafana/agent/component/common/relabel" + "github.com/grafana/agent/component/loki/relabel" + "github.com/grafana/agent/component/loki/source/kubernetes_events" + "github.com/grafana/agent/converter/diag" + "github.com/grafana/agent/converter/internal/common" + eventhandler_v2 "github.com/grafana/agent/pkg/integrations/v2/eventhandler" + "github.com/grafana/river/scanner" +) + +func (b *IntegrationsConfigBuilder) appendEventHandlerV2(config *eventhandler_v2.Config) { + compLabel, err := scanner.SanitizeIdentifier(b.formatJobName(config.Name(), nil)) + if err != nil { + b.diags.Add(diag.SeverityLevelCritical, fmt.Sprintf("failed to sanitize job name: %s", err)) + } + + b.diags.AddAll(common.ValidateSupported(common.NotDeepEquals, config.SendTimeout, eventhandler_v2.DefaultConfig.SendTimeout, "eventhandler send_timeout", "this field is not configurable in flow mode")) + b.diags.AddAll(common.ValidateSupported(common.NotDeepEquals, config.CachePath, eventhandler_v2.DefaultConfig.CachePath, "eventhandler cache_path", "this field is not configurable in flow mode")) + b.diags.AddAll(common.ValidateSupported(common.NotDeepEquals, config.InformerResync, eventhandler_v2.DefaultConfig.InformerResync, "eventhandler informer_resync", "this field is not configurable in flow mode")) + b.diags.AddAll(common.ValidateSupported(common.NotDeepEquals, config.FlushInterval, eventhandler_v2.DefaultConfig.FlushInterval, "eventhandler flush_interval", "this field is not configurable in flow mode")) + + receiver := getLogsReceiver(config) + if len(config.ExtraLabels) > 0 { + receiver = b.injectExtraLabels(config, receiver, compLabel) + } + + args := toEventHandlerV2(config, receiver) + + b.f.Body().AppendBlock(common.NewBlockWithOverride( + []string{"loki", "source", "kubernetes_events"}, + compLabel, + args, + )) +} + +func (b *IntegrationsConfigBuilder) injectExtraLabels(config *eventhandler_v2.Config, receiver common.ConvertLogsReceiver, compLabel string) common.ConvertLogsReceiver { + var relabelConfigs []*flow_relabel.Config + for _, extraLabel := range config.ExtraLabels { + defaultConfig := flow_relabel.DefaultRelabelConfig + relabelConfig := &defaultConfig + relabelConfig.SourceLabels = []string{"__address__"} + relabelConfig.TargetLabel = extraLabel.Name + relabelConfig.Replacement = extraLabel.Value + + relabelConfigs = append(relabelConfigs, relabelConfig) + } + + relabelArgs := relabel.Arguments{ + ForwardTo: []loki.LogsReceiver{receiver}, + RelabelConfigs: relabelConfigs, + MaxCacheSize: relabel.DefaultArguments.MaxCacheSize, + } + + b.f.Body().AppendBlock(common.NewBlockWithOverride( + []string{"loki", "relabel"}, + compLabel, + relabelArgs, + )) + + return common.ConvertLogsReceiver{ + Expr: fmt.Sprintf("loki.relabel.%s.receiver", compLabel), + } +} + +func getLogsReceiver(config *eventhandler_v2.Config) common.ConvertLogsReceiver { + logsReceiver := common.ConvertLogsReceiver{} + if config.LogsInstance != "" { + compLabel, err := scanner.SanitizeIdentifier("logs_" + config.LogsInstance) + if err != nil { + panic(fmt.Errorf("failed to sanitize job name: %s", err)) + } + + logsReceiver.Expr = fmt.Sprintf("loki.write.%s.receiver", compLabel) + } + + return logsReceiver +} + +func toEventHandlerV2(config *eventhandler_v2.Config, receiver common.ConvertLogsReceiver) *kubernetes_events.Arguments { + defaultOverrides := kubernetes_events.DefaultArguments + defaultOverrides.Client.KubeConfig = config.KubeconfigPath + if config.Namespace != "" { + defaultOverrides.Namespaces = []string{config.Namespace} + } + + return &kubernetes_events.Arguments{ + ForwardTo: []loki.LogsReceiver{receiver}, + JobName: kubernetes_events.DefaultArguments.JobName, + Namespaces: defaultOverrides.Namespaces, + LogFormat: config.LogFormat, + Client: defaultOverrides.Client, + } +} diff --git a/converter/internal/staticconvert/testdata-v2/integrations_v2.river b/converter/internal/staticconvert/testdata-v2/integrations_v2.river index 5908cd4f0f5b..d6306565d9e2 100644 --- a/converter/internal/staticconvert/testdata-v2/integrations_v2.river +++ b/converter/internal/staticconvert/testdata-v2/integrations_v2.river @@ -21,6 +21,26 @@ logging { format = "json" } +loki.relabel "integrations_eventhandler" { + forward_to = [loki.write.logs_log_config.receiver] + + rule { + source_labels = ["__address__"] + target_label = "test_label" + replacement = "test_label_value" + } + + rule { + source_labels = ["__address__"] + target_label = "test_label_2" + replacement = "test_label_value_2" + } +} + +loki.source.kubernetes_events "integrations_eventhandler" { + forward_to = [loki.relabel.integrations_eventhandler.receiver] +} + prometheus.exporter.azure "integrations_azure1" { subscriptions = ["subId"] resource_type = "Microsoft.Dashboard/grafana" diff --git a/converter/internal/staticconvert/testdata-v2/integrations_v2.yaml b/converter/internal/staticconvert/testdata-v2/integrations_v2.yaml index a335c87de163..cd0c497d15cc 100644 --- a/converter/internal/staticconvert/testdata-v2/integrations_v2.yaml +++ b/converter/internal/staticconvert/testdata-v2/integrations_v2.yaml @@ -117,6 +117,12 @@ integrations: elasticsearch_configs: - autoscrape: metrics_instance: "default" + eventhandler: + cache_path: "./.eventcache/eventhandler.cache" + logs_instance: "log_config" + extra_labels: + test_label: test_label_value + test_label_2: test_label_value_2 gcp_configs: - project_ids: - diff --git a/converter/internal/staticconvert/testdata-v2/unsupported.diags b/converter/internal/staticconvert/testdata-v2/unsupported.diags index 6337d505766f..cf356c13c1da 100644 --- a/converter/internal/staticconvert/testdata-v2/unsupported.diags +++ b/converter/internal/staticconvert/testdata-v2/unsupported.diags @@ -1,3 +1,6 @@ +(Error) The converter does not support converting the provided eventhandler send_timeout config: this field is not configurable in flow mode +(Error) The converter does not support converting the provided eventhandler cache_path config: this field is not configurable in flow mode +(Error) The converter does not support converting the provided eventhandler informer_resync config: this field is not configurable in flow mode +(Error) The converter does not support converting the provided eventhandler flush_interval config: this field is not configurable in flow mode (Warning) Please review your agent command line flags and ensure they are set in your Flow mode config file where necessary. -(Error) The converter does not support converting the provided eventhandler integration. (Error) The converter does not support converting the provided app_agent_receiver traces_instance config. \ No newline at end of file diff --git a/converter/internal/staticconvert/testdata-v2/unsupported.river b/converter/internal/staticconvert/testdata-v2/unsupported.river index 4b78abf71b43..0dcdb9ac79a6 100644 --- a/converter/internal/staticconvert/testdata-v2/unsupported.river +++ b/converter/internal/staticconvert/testdata-v2/unsupported.river @@ -9,6 +9,17 @@ prometheus.remote_write "metrics_default" { } } +loki.write "logs_log_config" { + endpoint { + url = "http://localhost/loki/api/v1/push" + } + external_labels = {} +} + +loki.source.kubernetes_events "integrations_eventhandler" { + forward_to = [loki.write.logs_log_config.receiver] +} + faro.receiver "integrations_app_agent_receiver" { extra_log_labels = {} diff --git a/converter/internal/staticconvert/testdata-v2/unsupported.yaml b/converter/internal/staticconvert/testdata-v2/unsupported.yaml index 13b6c44998ad..dfce6ed22e45 100644 --- a/converter/internal/staticconvert/testdata-v2/unsupported.yaml +++ b/converter/internal/staticconvert/testdata-v2/unsupported.yaml @@ -6,6 +6,13 @@ metrics: configs: - name: default +logs: + positions_directory: /path + configs: + - name: log_config + clients: + - url: http://localhost/loki/api/v1/push + integrations: app_agent_receiver_configs: - instance: "default" @@ -14,4 +21,8 @@ integrations: host: "localhost" port: 55678 eventhandler: - cache_path: "/etc/eventhandler/eventhandler.cache" \ No newline at end of file + cache_path: "/etc/eventhandler/not_default.cache" + logs_instance: "log_config" + send_timeout: 30 + informer_resync: 30 + flush_interval: 30 \ No newline at end of file diff --git a/converter/internal/staticconvert/validate.go b/converter/internal/staticconvert/validate.go index fb714af9d555..2c5aeb87c1d0 100644 --- a/converter/internal/staticconvert/validate.go +++ b/converter/internal/staticconvert/validate.go @@ -37,7 +37,8 @@ import ( apache_exporter_v2 "github.com/grafana/agent/pkg/integrations/v2/apache_http" app_agent_receiver_v2 "github.com/grafana/agent/pkg/integrations/v2/app_agent_receiver" blackbox_exporter_v2 "github.com/grafana/agent/pkg/integrations/v2/blackbox_exporter" - "github.com/grafana/agent/pkg/integrations/v2/metricsutils" + eventhandler_v2 "github.com/grafana/agent/pkg/integrations/v2/eventhandler" + metricsutils_v2 "github.com/grafana/agent/pkg/integrations/v2/metricsutils" snmp_exporter_v2 "github.com/grafana/agent/pkg/integrations/v2/snmp_exporter" vmware_exporter_v2 "github.com/grafana/agent/pkg/integrations/v2/vmware_exporter" "github.com/grafana/agent/pkg/integrations/windows_exporter" @@ -171,9 +172,10 @@ func validateIntegrationsV2(integrationsConfig *v2.SubsystemOptions) diag.Diagno case *app_agent_receiver_v2.Config: diags.AddAll(common.ValidateSupported(common.NotEquals, itg.TracesInstance, "", "app_agent_receiver traces_instance", "")) case *blackbox_exporter_v2.Config: + case *eventhandler_v2.Config: case *snmp_exporter_v2.Config: case *vmware_exporter_v2.Config: - case *metricsutils.ConfigShim: + case *metricsutils_v2.ConfigShim: switch v1_itg := itg.Orig.(type) { case *azure_exporter.Config: case *cadvisor.Config: From 50d16208d1c2f30851212b97ef1fe6e106d499e8 Mon Sep 17 00:00:00 2001 From: Craig Peterson <192540+captncraig@users.noreply.github.com> Date: Thu, 4 Jan 2024 13:47:26 -0500 Subject: [PATCH 04/68] helm: clean up logic for autodelete pvcs (#6042) * helm: clean up logic for autodelete pvcs * remove flag * changelog --- operations/helm/charts/grafana-agent/CHANGELOG.md | 4 ++++ .../ci/create-statefulset-autoscaling-values.yaml | 1 + .../grafana-agent/templates/controllers/statefulset.yaml | 7 +++++-- operations/helm/scripts/rebuild-tests.sh | 2 +- .../grafana-agent/templates/controllers/statefulset.yaml | 3 +++ 5 files changed, 14 insertions(+), 3 deletions(-) diff --git a/operations/helm/charts/grafana-agent/CHANGELOG.md b/operations/helm/charts/grafana-agent/CHANGELOG.md index 70b612d74572..d14525031740 100644 --- a/operations/helm/charts/grafana-agent/CHANGELOG.md +++ b/operations/helm/charts/grafana-agent/CHANGELOG.md @@ -14,6 +14,10 @@ Unreleased - Update `rbac` to include necessary rules for the `otelcol.processor.k8sattributes` component. (@rlankfo) +### Bugfixes + +- Statefulset should use value `.controller.enableStatefulSetAutoDeletePVC` instead of just `.enableStatefulSetAutoDeletePVC`. (@captncraig) + 0.29.0 (2023-11-30) ------------------- diff --git a/operations/helm/charts/grafana-agent/ci/create-statefulset-autoscaling-values.yaml b/operations/helm/charts/grafana-agent/ci/create-statefulset-autoscaling-values.yaml index 89b51fc31c78..eedf5411b31c 100644 --- a/operations/helm/charts/grafana-agent/ci/create-statefulset-autoscaling-values.yaml +++ b/operations/helm/charts/grafana-agent/ci/create-statefulset-autoscaling-values.yaml @@ -3,6 +3,7 @@ controller: type: statefulset autoscaling: enabled: true + enableStatefulSetAutoDeletePVC: true agent: resources: requests: diff --git a/operations/helm/charts/grafana-agent/templates/controllers/statefulset.yaml b/operations/helm/charts/grafana-agent/templates/controllers/statefulset.yaml index c4ef55024a22..a4965d14205d 100644 --- a/operations/helm/charts/grafana-agent/templates/controllers/statefulset.yaml +++ b/operations/helm/charts/grafana-agent/templates/controllers/statefulset.yaml @@ -1,4 +1,7 @@ {{- if eq .Values.controller.type "statefulset" }} +{{- if .Values.enableStatefulSetAutoDeletePVC }} +{{- fail "Value 'enableStatefulSetAutoDeletePVC' should be nested inside 'controller' options." }} +{{- end }} apiVersion: apps/v1 kind: StatefulSet metadata: @@ -35,8 +38,8 @@ spec: - {{ toYaml . | nindent 6 }} {{- end }} {{- end }} - {{- if and (semverCompare ">= 1.23-0" .Capabilities.KubeVersion.Version) (.Values.enableStatefulSetAutoDeletePVC) }} - {{/* + {{- if and (semverCompare ">= 1.23-0" .Capabilities.KubeVersion.Version) (.Values.controller.enableStatefulSetAutoDeletePVC) }} + {{- /* Data on the read nodes is easy to replace, so we want to always delete PVCs to make operation easier, and will rely on re-fetching data when needed. */}} diff --git a/operations/helm/scripts/rebuild-tests.sh b/operations/helm/scripts/rebuild-tests.sh index af82eef8b12d..66ce2dfaaff6 100755 --- a/operations/helm/scripts/rebuild-tests.sh +++ b/operations/helm/scripts/rebuild-tests.sh @@ -17,7 +17,7 @@ for chart_file in $(find * -name Chart.yaml -print | sort); do FILENAME=$(basename ${FILE_PATH}) TESTNAME=${FILENAME%-values.yaml} # Render chart - helm template --namespace default --debug ${CHART_NAME} ${CHART_DIR} -f ${FILE_PATH} --output-dir ${TEST_DIR}/${TESTNAME} --set '$chart_tests=true' + helm template --namespace default --kube-version 1.26 --debug ${CHART_NAME} ${CHART_DIR} -f ${FILE_PATH} --output-dir ${TEST_DIR}/${TESTNAME} --set '$chart_tests=true' done fi done diff --git a/operations/helm/tests/create-statefulset-autoscaling/grafana-agent/templates/controllers/statefulset.yaml b/operations/helm/tests/create-statefulset-autoscaling/grafana-agent/templates/controllers/statefulset.yaml index 65ce63ce8c00..06151482680e 100644 --- a/operations/helm/tests/create-statefulset-autoscaling/grafana-agent/templates/controllers/statefulset.yaml +++ b/operations/helm/tests/create-statefulset-autoscaling/grafana-agent/templates/controllers/statefulset.yaml @@ -76,3 +76,6 @@ spec: - name: config configMap: name: grafana-agent + persistentVolumeClaimRetentionPolicy: + whenDeleted: Delete + whenScaled: Delete From 35b803906c6e37c59cef7dd4ff09c6a6cd24de75 Mon Sep 17 00:00:00 2001 From: Piotr <17101802+thampiotr@users.noreply.github.com> Date: Fri, 5 Jan 2024 11:41:33 +0100 Subject: [PATCH 05/68] Move 'Getting started' to 'Tasks' (#6043) * Move 'Getting started' to 'Tasks' * fix aliases --- docs/sources/about.md | 12 ++++----- .../loki-config.png | Bin .../otlp-lgtm-graph.png | Bin .../prometheus-config.png | Bin .../tempo-config.png | Bin docs/sources/flow/_index.md | 6 ++--- docs/sources/flow/getting-started/_index.md | 19 ------------- docs/sources/flow/reference/cli/convert.md | 6 ++--- docs/sources/flow/tasks/_index.md | 25 ++++++++++++++++++ .../collect-opentelemetry-data.md | 8 +++++- .../collect-prometheus-metrics.md | 8 +++++- .../configure-agent-clustering.md | 8 +++++- .../distribute-prometheus-scrape-load.md | 16 +++++++---- .../migrating-from-operator.md | 6 ++++- .../migrating-from-prometheus.md | 8 +++++- .../migrating-from-promtail.md | 8 +++++- .../migrating-from-static.md | 16 +++++++---- .../opentelemetry-to-lgtm-stack.md | 24 ++++++++++------- 18 files changed, 114 insertions(+), 56 deletions(-) rename docs/sources/assets/{getting-started => tasks}/loki-config.png (100%) rename docs/sources/assets/{getting-started => tasks}/otlp-lgtm-graph.png (100%) rename docs/sources/assets/{getting-started => tasks}/prometheus-config.png (100%) rename docs/sources/assets/{getting-started => tasks}/tempo-config.png (100%) delete mode 100644 docs/sources/flow/getting-started/_index.md create mode 100644 docs/sources/flow/tasks/_index.md rename docs/sources/flow/{getting-started => tasks}/collect-opentelemetry-data.md (95%) rename docs/sources/flow/{getting-started => tasks}/collect-prometheus-metrics.md (96%) rename docs/sources/flow/{getting-started => tasks}/configure-agent-clustering.md (83%) rename docs/sources/flow/{getting-started => tasks}/distribute-prometheus-scrape-load.md (78%) rename docs/sources/flow/{getting-started => tasks}/migrating-from-operator.md (97%) rename docs/sources/flow/{getting-started => tasks}/migrating-from-prometheus.md (95%) rename docs/sources/flow/{getting-started => tasks}/migrating-from-promtail.md (95%) rename docs/sources/flow/{getting-started => tasks}/migrating-from-static.md (95%) rename docs/sources/flow/{getting-started => tasks}/opentelemetry-to-lgtm-stack.md (93%) diff --git a/docs/sources/about.md b/docs/sources/about.md index 0737815b61d6..c33d73087408 100644 --- a/docs/sources/about.md +++ b/docs/sources/about.md @@ -29,12 +29,12 @@ Grafana Agent is available in three different variants: [Static mode Kubernetes operator]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/operator" [Flow mode]: "/docs/agent/ -> /docs/agent//flow" [Flow mode]: "/docs/grafana-cloud/ -> /docs/agent//flow" -[Prometheus]: "/docs/agent/ -> /docs/agent//flow/getting-started/collect-prometheus-metrics.md" -[Prometheus]: "/docs/grafana-cloud/ -> /docs/agent//flow/getting-started/collect-prometheus-metrics.md" -[OTel]: "/docs/agent/ -> /docs/agent//flow/getting-started/collect-opentelemetry-data.md" -[OTel]: "/docs/grafana-cloud/ -> /docs/agent//flow/getting-started/collect-opentelemetry-data.md" -[Loki]: "/docs/agent/ -> /docs/agent//flow/getting-started/migrating-from-promtail.md" -[Loki]: "/docs/grafana-cloud/ -> /docs/agent//flow/getting-started/migrating-from-promtail.md" +[Prometheus]: "/docs/agent/ -> /docs/agent//flow/tasks/collect-prometheus-metrics.md" +[Prometheus]: "/docs/grafana-cloud/ -> /docs/agent//flow/tasks/collect-prometheus-metrics.md" +[OTel]: "/docs/agent/ -> /docs/agent//flow/tasks/collect-opentelemetry-data.md" +[OTel]: "/docs/grafana-cloud/ -> /docs/agent//flow/tasks/collect-opentelemetry-data.md" +[Loki]: "/docs/agent/ -> /docs/agent//flow/tasks/migrating-from-promtail.md" +[Loki]: "/docs/grafana-cloud/ -> /docs/agent//flow/tasks/migrating-from-promtail.md" [clustering]: "/docs/agent/ -> /docs/agent//flow/concepts/clustering/_index.md" [clustering]: "/docs/grafana-cloud/ -> /docs/agent//flow/concepts/clustering/_index.md" [rules]: "/docs/agent/ -> /docs/agent/latest/flow/reference/components/mimir.rules.kubernetes.md" diff --git a/docs/sources/assets/getting-started/loki-config.png b/docs/sources/assets/tasks/loki-config.png similarity index 100% rename from docs/sources/assets/getting-started/loki-config.png rename to docs/sources/assets/tasks/loki-config.png diff --git a/docs/sources/assets/getting-started/otlp-lgtm-graph.png b/docs/sources/assets/tasks/otlp-lgtm-graph.png similarity index 100% rename from docs/sources/assets/getting-started/otlp-lgtm-graph.png rename to docs/sources/assets/tasks/otlp-lgtm-graph.png diff --git a/docs/sources/assets/getting-started/prometheus-config.png b/docs/sources/assets/tasks/prometheus-config.png similarity index 100% rename from docs/sources/assets/getting-started/prometheus-config.png rename to docs/sources/assets/tasks/prometheus-config.png diff --git a/docs/sources/assets/getting-started/tempo-config.png b/docs/sources/assets/tasks/tempo-config.png similarity index 100% rename from docs/sources/assets/getting-started/tempo-config.png rename to docs/sources/assets/tasks/tempo-config.png diff --git a/docs/sources/flow/_index.md b/docs/sources/flow/_index.md index 7458fd016b03..4262238f9020 100644 --- a/docs/sources/flow/_index.md +++ b/docs/sources/flow/_index.md @@ -80,14 +80,14 @@ This feature is experimental, and it doesn't support all River components. * [Install][] {{< param "PRODUCT_NAME" >}}. * Learn about the core [Concepts][] of {{< param "PRODUCT_NAME" >}}. -* Follow our [Getting started][] guides for {{< param "PRODUCT_NAME" >}}. -* Follow our [Tutorials][] to get started with {{< param "PRODUCT_NAME" >}}. +* Follow our [Tutorials][] for hands-on learning of {{< param "PRODUCT_NAME" >}}. +* Consult our [Tasks][] instructions to accomplish common objectives with {{< param "PRODUCT_NAME" >}}. * Check out our [Reference][] documentation to find specific information you might be looking for. [Install]: {{< relref "./setup/install/" >}} [Concepts]: {{< relref "./concepts/" >}} -[Getting started]: {{< relref "./getting-started/" >}} +[Tasks]: {{< relref "./tasks/" >}} [Tutorials]: {{< relref "./tutorials/ ">}} [Reference]: {{< relref "./reference" >}} diff --git a/docs/sources/flow/getting-started/_index.md b/docs/sources/flow/getting-started/_index.md deleted file mode 100644 index bc989084f42b..000000000000 --- a/docs/sources/flow/getting-started/_index.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -aliases: -- /docs/grafana-cloud/agent/flow/getting-started/ -- /docs/grafana-cloud/monitor-infrastructure/agent/flow/getting-started/ -- /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/getting-started/ -- /docs/grafana-cloud/send-data/agent/flow/getting-started/ -- getting_started/ -canonical: https://grafana.com/docs/agent/latest/flow/getting-started/ -description: Learn how to use Grafana Agent Flow -menuTitle: Get started -title: Get started with Grafana Agent Flow -weight: 200 ---- - -# Get started with {{% param "PRODUCT_NAME" %}} - -This section details guides for getting started with {{< param "PRODUCT_NAME" >}}. - -{{< section >}} diff --git a/docs/sources/flow/reference/cli/convert.md b/docs/sources/flow/reference/cli/convert.md index 88c9628fde31..833341b47752 100644 --- a/docs/sources/flow/reference/cli/convert.md +++ b/docs/sources/flow/reference/cli/convert.md @@ -82,7 +82,7 @@ This includes Prometheus features such as and many supported *_sd_configs. Unsupported features in a source configuration result in [errors]. -Refer to [Migrate from Prometheus to {{< param "PRODUCT_NAME" >}}]({{< relref "../../getting-started/migrating-from-prometheus/" >}}) for a detailed migration guide. +Refer to [Migrate from Prometheus to {{< param "PRODUCT_NAME" >}}]({{< relref "../../tasks/migrating-from-prometheus/" >}}) for a detailed migration guide. ### Promtail @@ -96,7 +96,7 @@ are supported and can be converted to {{< param "PRODUCT_NAME" >}} configuration If you have unsupported features in a source configuration, you will receive [errors] when you convert to a flow configuration. The converter will also raise warnings for configuration options that may require your attention. -Refer to [Migrate from Promtail to {{< param "PRODUCT_NAME" >}}]({{< relref "../../getting-started/migrating-from-promtail/" >}}) for a detailed migration guide. +Refer to [Migrate from Promtail to {{< param "PRODUCT_NAME" >}}]({{< relref "../../tasks/migrating-from-promtail/" >}}) for a detailed migration guide. ### Static @@ -113,4 +113,4 @@ flags with a space between each flag, for example `--extra-args="-enable-feature If you have unsupported features in a Static mode source configuration, you will receive [errors][] when you convert to a Flow mode configuration. The converter will also raise warnings for configuration options that may require your attention. -Refer to [Migrate from Grafana Agent Static to {{< param "PRODUCT_NAME" >}}]({{< relref "../../getting-started/migrating-from-static/" >}}) for a detailed migration guide. \ No newline at end of file +Refer to [Migrate from Grafana Agent Static to {{< param "PRODUCT_NAME" >}}]({{< relref "../../tasks/migrating-from-static/" >}}) for a detailed migration guide. \ No newline at end of file diff --git a/docs/sources/flow/tasks/_index.md b/docs/sources/flow/tasks/_index.md new file mode 100644 index 000000000000..4ca62e8c1331 --- /dev/null +++ b/docs/sources/flow/tasks/_index.md @@ -0,0 +1,25 @@ +--- +aliases: +- /docs/grafana-cloud/agent/flow/tasks/ +- /docs/grafana-cloud/monitor-infrastructure/agent/flow/tasks/ +- /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/tasks/ +- /docs/grafana-cloud/send-data/agent/flow/tasks/ +# Previous page aliases for backwards compatibility: +- /docs/grafana-cloud/agent/flow/getting-started/ +- /docs/grafana-cloud/monitor-infrastructure/agent/flow/getting-started/ +- /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/getting-started/ +- /docs/grafana-cloud/send-data/agent/flow/getting-started/ +- getting_started/ # /docs/agent/latest/flow/getting_started/ +- getting-started/ # /docs/agent/latest/flow/getting-started/ +canonical: https://grafana.com/docs/agent/latest/flow/tasks/ +description: How to perform common tasks with Grafana Agent Flow +menuTitle: Tasks +title: Tasks with Grafana Agent Flow +weight: 200 +--- + +# Tasks with {{% param "PRODUCT_NAME" %}} + +This section details how to perform common tasks with {{< param "PRODUCT_NAME" >}}. + +{{< section >}} diff --git a/docs/sources/flow/getting-started/collect-opentelemetry-data.md b/docs/sources/flow/tasks/collect-opentelemetry-data.md similarity index 95% rename from docs/sources/flow/getting-started/collect-opentelemetry-data.md rename to docs/sources/flow/tasks/collect-opentelemetry-data.md index 70dee8041d9f..22248f9f70f9 100644 --- a/docs/sources/flow/getting-started/collect-opentelemetry-data.md +++ b/docs/sources/flow/tasks/collect-opentelemetry-data.md @@ -1,10 +1,16 @@ --- aliases: +- /docs/grafana-cloud/agent/flow/tasks/collect-opentelemetry-data/ +- /docs/grafana-cloud/monitor-infrastructure/agent/flow/tasks/collect-opentelemetry-data/ +- /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/tasks/collect-opentelemetry-data/ +- /docs/grafana-cloud/send-data/agent/flow/tasks/collect-opentelemetry-data/ +# Previous page aliases for backwards compatibility: - /docs/grafana-cloud/agent/flow/getting-started/collect-opentelemetry-data/ - /docs/grafana-cloud/monitor-infrastructure/agent/flow/getting-started/collect-opentelemetry-data/ - /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/getting-started/collect-opentelemetry-data/ - /docs/grafana-cloud/send-data/agent/flow/getting-started/collect-opentelemetry-data/ -canonical: https://grafana.com/docs/agent/latest/flow/getting-started/collect-opentelemetry-data/ +- ../getting-started/collect-opentelemetry-data/ # /docs/agent/latest/flow/getting-started/collect-opentelemetry-data/ +canonical: https://grafana.com/docs/agent/latest/flow/tasks/collect-opentelemetry-data/ description: Learn how to collect OpenTelemetry data title: Collect OpenTelemetry data weight: 300 diff --git a/docs/sources/flow/getting-started/collect-prometheus-metrics.md b/docs/sources/flow/tasks/collect-prometheus-metrics.md similarity index 96% rename from docs/sources/flow/getting-started/collect-prometheus-metrics.md rename to docs/sources/flow/tasks/collect-prometheus-metrics.md index be6d2ce71e01..350ce1ccfd4d 100644 --- a/docs/sources/flow/getting-started/collect-prometheus-metrics.md +++ b/docs/sources/flow/tasks/collect-prometheus-metrics.md @@ -1,10 +1,16 @@ --- aliases: +- /docs/grafana-cloud/agent/flow/tasks/collect-prometheus-metrics/ +- /docs/grafana-cloud/monitor-infrastructure/agent/flow/tasks/collect-prometheus-metrics/ +- /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/tasks/collect-prometheus-metrics/ +- /docs/grafana-cloud/send-data/agent/flow/tasks/collect-prometheus-metrics/ +# Previous page aliases for backwards compatibility: - /docs/grafana-cloud/agent/flow/getting-started/collect-prometheus-metrics/ - /docs/grafana-cloud/monitor-infrastructure/agent/flow/getting-started/collect-prometheus-metrics/ - /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/getting-started/collect-prometheus-metrics/ - /docs/grafana-cloud/send-data/agent/flow/getting-started/collect-prometheus-metrics/ -canonical: https://grafana.com/docs/agent/latest/flow/getting-started/collect-prometheus-metrics/ +- ../getting-started/collect-prometheus-metrics/ # /docs/agent/latest/flow/getting-started/collect-prometheus-metrics/ +canonical: https://grafana.com/docs/agent/latest/flow/tasks/collect-prometheus-metrics/ description: Learn how to collect and forward Prometheus metrics title: Collect and forward Prometheus metrics weight: 200 diff --git a/docs/sources/flow/getting-started/configure-agent-clustering.md b/docs/sources/flow/tasks/configure-agent-clustering.md similarity index 83% rename from docs/sources/flow/getting-started/configure-agent-clustering.md rename to docs/sources/flow/tasks/configure-agent-clustering.md index eacc61407986..b1ab444d4ebb 100644 --- a/docs/sources/flow/getting-started/configure-agent-clustering.md +++ b/docs/sources/flow/tasks/configure-agent-clustering.md @@ -1,10 +1,16 @@ --- aliases: +- /docs/grafana-cloud/agent/flow/tasks/configure-agent-clustering/ +- /docs/grafana-cloud/monitor-infrastructure/agent/flow/tasks/configure-agent-clustering/ +- /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/tasks/configure-agent-clustering/ +- /docs/grafana-cloud/send-data/agent/flow/tasks/configure-agent-clustering/ +# Previous page aliases for backwards compatibility: - /docs/grafana-cloud/agent/flow/getting-started/configure-agent-clustering/ - /docs/grafana-cloud/monitor-infrastructure/agent/flow/getting-started/configure-agent-clustering/ - /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/getting-started/configure-agent-clustering/ - /docs/grafana-cloud/send-data/agent/flow/getting-started/configure-agent-clustering/ -canonical: https://grafana.com/docs/agent/latest/flow/getting-started/configure-agent-clustering/ +- ../getting-started/configure-agent-clustering/ # /docs/agent/latest/flow/getting-started/configure-agent-clustering/ +canonical: https://grafana.com/docs/agent/latest/flow/tasks/configure-agent-clustering/ description: Learn how to configure Grafana Agent clustering in an existing installation menuTitle: Configure Grafana Agent clustering title: Configure Grafana Agent clustering in an existing installation diff --git a/docs/sources/flow/getting-started/distribute-prometheus-scrape-load.md b/docs/sources/flow/tasks/distribute-prometheus-scrape-load.md similarity index 78% rename from docs/sources/flow/getting-started/distribute-prometheus-scrape-load.md rename to docs/sources/flow/tasks/distribute-prometheus-scrape-load.md index d881b2f0a34b..961c98543b98 100644 --- a/docs/sources/flow/getting-started/distribute-prometheus-scrape-load.md +++ b/docs/sources/flow/tasks/distribute-prometheus-scrape-load.md @@ -1,10 +1,16 @@ --- aliases: +- /docs/grafana-cloud/agent/flow/tasks/distribute-prometheus-scrape-load/ +- /docs/grafana-cloud/monitor-infrastructure/agent/flow/tasks/distribute-prometheus-scrape-load/ +- /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/tasks/distribute-prometheus-scrape-load/ +- /docs/grafana-cloud/send-data/agent/flow/tasks/distribute-prometheus-scrape-load/ +# Previous page aliases for backwards compatibility: - /docs/grafana-cloud/agent/flow/getting-started/distribute-prometheus-scrape-load/ - /docs/grafana-cloud/monitor-infrastructure/agent/flow/getting-started/distribute-prometheus-scrape-load/ - /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/getting-started/distribute-prometheus-scrape-load/ - /docs/grafana-cloud/send-data/agent/flow/getting-started/distribute-prometheus-scrape-load/ -canonical: https://grafana.com/docs/agent/latest/flow/getting-started/distribute-prometheus-scrape-load/ +- ../getting-started/distribute-prometheus-scrape-load/ # /docs/agent/latest/flow/getting-started/distribute-prometheus-scrape-load/ +canonical: https://grafana.com/docs/agent/latest/flow/tasks/distribute-prometheus-scrape-load/ description: Learn how to distribute your Prometheus metrics scrape load menuTitle: Distribute Prometheus metrics scrape load title: Distribute Prometheus metrics scrape load @@ -53,10 +59,10 @@ To distribute Prometheus metrics scrape load with clustering: [beta]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/stability.md#beta" [configure-grafana-agent]: "/docs/agent/ -> /docs/agent//flow/setup/configure" [configure-grafana-agent]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/setup/configure" -[Configure Prometheus metrics collection]: "/docs/agent/ -> /docs/agent//flow/getting-started/collect-prometheus-metrics.md" -[Configure Prometheus metrics collection]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/getting-started/collect-prometheus-metrics.md" -[Configure clustering]: "/docs/agent/ -> /docs/agent//flow/getting-started/configure-agent-clustering.md" -[Configure clustering]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/getting-started/configure-agent-clustering.md" +[Configure Prometheus metrics collection]: "/docs/agent/ -> /docs/agent//flow/tasks/collect-prometheus-metrics.md" +[Configure Prometheus metrics collection]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/tasks/collect-prometheus-metrics.md" +[Configure clustering]: "/docs/agent/ -> /docs/agent//flow/tasks/configure-agent-clustering.md" +[Configure clustering]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/tasks/configure-agent-clustering.md" [UI]: "/docs/agent/ -> /docs/agent//flow/monitoring/debugging.md#component-detail-page" [UI]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/monitoring/debugging.md#component-detail-page" {{% /docs/reference %}} diff --git a/docs/sources/flow/getting-started/migrating-from-operator.md b/docs/sources/flow/tasks/migrating-from-operator.md similarity index 97% rename from docs/sources/flow/getting-started/migrating-from-operator.md rename to docs/sources/flow/tasks/migrating-from-operator.md index 5985488c2915..375ffec59e51 100644 --- a/docs/sources/flow/getting-started/migrating-from-operator.md +++ b/docs/sources/flow/tasks/migrating-from-operator.md @@ -1,8 +1,12 @@ --- aliases: +- /docs/grafana-cloud/monitor-infrastructure/agent/flow/tasks/migrating-from-operator/ +- /docs/grafana-cloud/send-data/agent/flow/tasks/migrating-from-operator/ +# Previous page aliases for backwards compatibility: - /docs/grafana-cloud/monitor-infrastructure/agent/flow/getting-started/migrating-from-operator/ - /docs/grafana-cloud/send-data/agent/flow/getting-started/migrating-from-operator/ -canonical: https://grafana.com/docs/agent/latest/flow/getting-started/migrating-from-operator/ +- ../getting-started/migrating-from-operator/ # /docs/agent/latest/flow/getting-started/migrating-from-operator/ +canonical: https://grafana.com/docs/agent/latest/flow/tasks/migrating-from-operator/ description: Migrating from Grafana Agent Operator to Grafana Agent Flow menuTitle: Migrate from Operator title: Migrating from Grafana Agent Operator to Grafana Agent Flow diff --git a/docs/sources/flow/getting-started/migrating-from-prometheus.md b/docs/sources/flow/tasks/migrating-from-prometheus.md similarity index 95% rename from docs/sources/flow/getting-started/migrating-from-prometheus.md rename to docs/sources/flow/tasks/migrating-from-prometheus.md index 8d77d6914340..837ca9da1e07 100644 --- a/docs/sources/flow/getting-started/migrating-from-prometheus.md +++ b/docs/sources/flow/tasks/migrating-from-prometheus.md @@ -1,10 +1,16 @@ --- aliases: +- /docs/grafana-cloud/agent/flow/tasks/migrating-from-prometheus/ +- /docs/grafana-cloud/monitor-infrastructure/agent/flow/tasks/migrating-from-prometheus/ +- /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/tasks/migrating-from-prometheus/ +- /docs/grafana-cloud/send-data/agent/flow/tasks/migrating-from-prometheus/ +# Previous page aliases for backwards compatibility: - /docs/grafana-cloud/agent/flow/getting-started/migrating-from-prometheus/ - /docs/grafana-cloud/monitor-infrastructure/agent/flow/getting-started/migrating-from-prometheus/ - /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/getting-started/migrating-from-prometheus/ - /docs/grafana-cloud/send-data/agent/flow/getting-started/migrating-from-prometheus/ -canonical: https://grafana.com/docs/agent/latest/flow/getting-started/migrating-from-prometheus/ +- ../getting-started/migrating-from-prometheus/ # /docs/agent/latest/flow/getting-started/migrating-from-prometheus/ +canonical: https://grafana.com/docs/agent/latest/flow/tasks/migrating-from-prometheus/ description: Learn how to migrate from Prometheus to Grafana Agent Flow menuTitle: Migrate from Prometheus title: Migrate from Prometheus to Grafana Agent Flow diff --git a/docs/sources/flow/getting-started/migrating-from-promtail.md b/docs/sources/flow/tasks/migrating-from-promtail.md similarity index 95% rename from docs/sources/flow/getting-started/migrating-from-promtail.md rename to docs/sources/flow/tasks/migrating-from-promtail.md index 4799e0e20b5f..d38e9b904697 100644 --- a/docs/sources/flow/getting-started/migrating-from-promtail.md +++ b/docs/sources/flow/tasks/migrating-from-promtail.md @@ -1,10 +1,16 @@ --- aliases: +- /docs/grafana-cloud/agent/flow/tasks/migrating-from-promtail/ +- /docs/grafana-cloud/monitor-infrastructure/agent/flow/tasks/migrating-from-promtail/ +- /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/tasks/migrating-from-promtail/ +- /docs/grafana-cloud/send-data/agent/flow/tasks/migrating-from-promtail/ +# Previous page aliases for backwards compatibility: - /docs/grafana-cloud/agent/flow/getting-started/migrating-from-promtail/ - /docs/grafana-cloud/monitor-infrastructure/agent/flow/getting-started/migrating-from-promtail/ - /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/getting-started/migrating-from-promtail/ - /docs/grafana-cloud/send-data/agent/flow/getting-started/migrating-from-promtail/ -canonical: https://grafana.com/docs/agent/latest/flow/getting-started/migrating-from-promtail/ +- ../getting-started/migrating-from-promtail/ # /docs/agent/latest/flow/getting-started/migrating-from-promtail/ +canonical: https://grafana.com/docs/agent/latest/flow/tasks/migrating-from-promtail/ description: Learn how to migrate from Promtail to Grafana Agent Flow menuTitle: Migrate from Promtail title: Migrate from Promtail to Grafana Agent Flow diff --git a/docs/sources/flow/getting-started/migrating-from-static.md b/docs/sources/flow/tasks/migrating-from-static.md similarity index 95% rename from docs/sources/flow/getting-started/migrating-from-static.md rename to docs/sources/flow/tasks/migrating-from-static.md index 8b7b1f98721e..a4033dab096a 100644 --- a/docs/sources/flow/getting-started/migrating-from-static.md +++ b/docs/sources/flow/tasks/migrating-from-static.md @@ -1,10 +1,16 @@ --- aliases: +- /docs/grafana-cloud/agent/flow/tasks/migrating-from-static/ +- /docs/grafana-cloud/monitor-infrastructure/agent/flow/tasks/migrating-from-static/ +- /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/tasks/migrating-from-static/ +- /docs/grafana-cloud/send-data/agent/flow/tasks/migrating-from-static/ +# Previous page aliases for backwards compatibility: - /docs/grafana-cloud/agent/flow/getting-started/migrating-from-static/ - /docs/grafana-cloud/monitor-infrastructure/agent/flow/getting-started/migrating-from-static/ - /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/getting-started/migrating-from-static/ - /docs/grafana-cloud/send-data/agent/flow/getting-started/migrating-from-static/ -canonical: https://grafana.com/docs/agent/latest/flow/getting-started/migrating-from-static/ +- ../getting-started/migrating-from-static/ # /docs/agent/latest/flow/getting-started/migrating-from-static/ +canonical: https://grafana.com/docs/agent/latest/flow/tasks/migrating-from-static/ description: Learn how to migrate your configuration from Grafana Agent Static to Grafana Agent Flow menuTitle: Migrate from Static to Flow title: Migrate Grafana Agent Static to Grafana Agent Flow @@ -382,10 +388,10 @@ The following list is specific to the convert command and not {{< param "PRODUCT [Agent Management]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/static/configuration/agent-management.md" [env]: "/docs/agent/ -> /docs/agent//flow/reference/stdlib/env.md" [env]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/reference/stdlib/env.md" -[Prometheus Limitations]: "/docs/agent/ -> /docs/agent//flow/getting-started/migrating-from-prometheus.md#limitations" -[Prometheus Limitations]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/getting-started/migrating-from-prometheus.md#limitations" -[Promtail Limitations]: "/docs/agent/ -> /docs/agent//flow/getting-started/migrating-from-promtail.md#limitations" -[Promtail Limitations]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/getting-started/migrating-from-promtail.md#limitations" +[Prometheus Limitations]: "/docs/agent/ -> /docs/agent//flow/tasks/migrating-from-prometheus.md#limitations" +[Prometheus Limitations]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/tasks/migrating-from-prometheus.md#limitations" +[Promtail Limitations]: "/docs/agent/ -> /docs/agent//flow/tasks/migrating-from-promtail.md#limitations" +[Promtail Limitations]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/tasks/migrating-from-promtail.md#limitations" [Metrics]: "/docs/agent/ -> /docs/agent//static/configuration/metrics-config.md" [Metrics]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/static/configuration/metrics-config.md" [Logs]: "/docs/agent/ -> /docs/agent//static/configuration/logs-config.md" diff --git a/docs/sources/flow/getting-started/opentelemetry-to-lgtm-stack.md b/docs/sources/flow/tasks/opentelemetry-to-lgtm-stack.md similarity index 93% rename from docs/sources/flow/getting-started/opentelemetry-to-lgtm-stack.md rename to docs/sources/flow/tasks/opentelemetry-to-lgtm-stack.md index 279960d79fe0..2da979078336 100644 --- a/docs/sources/flow/getting-started/opentelemetry-to-lgtm-stack.md +++ b/docs/sources/flow/tasks/opentelemetry-to-lgtm-stack.md @@ -1,10 +1,16 @@ --- aliases: +- /docs/grafana-cloud/agent/flow/tasks/opentelemetry-to-lgtm-stack/ +- /docs/grafana-cloud/monitor-infrastructure/agent/flow/tasks/opentelemetry-to-lgtm-stack/ +- /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/tasks/opentelemetry-to-lgtm-stack/ +- /docs/grafana-cloud/send-data/agent/flow/tasks/opentelemetry-to-lgtm-stack/ +# Previous page aliases for backwards compatibility: - /docs/grafana-cloud/agent/flow/getting-started/opentelemetry-to-lgtm-stack/ - /docs/grafana-cloud/monitor-infrastructure/agent/flow/getting-started/opentelemetry-to-lgtm-stack/ - /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/getting-started/opentelemetry-to-lgtm-stack/ - /docs/grafana-cloud/send-data/agent/flow/getting-started/opentelemetry-to-lgtm-stack/ -canonical: https://grafana.com/docs/agent/latest/flow/getting-started/opentelemetry-to-lgtm-stack/ +- ../getting-started/opentelemetry-to-lgtm-stack/ # /docs/agent/latest/flow/getting-started/opentelemetry-to-lgtm-stack/ +canonical: https://grafana.com/docs/agent/latest/flow/tasks/opentelemetry-to-lgtm-stack/ description: Learn how to collect OpenTelemetry data and forward it to the Grafana stack title: OpenTelemetry to Grafana stack @@ -38,11 +44,11 @@ This topic describes how to: * Have a set of OpenTelemetry applications ready to push telemetry data to {{< param "PRODUCT_NAME" >}}. * Identify where {{< param "PRODUCT_NAME" >}} will write received telemetry data. * Be familiar with the concept of [Components][] in {{< param "PRODUCT_NAME" >}}. -* Complete the [Collect open telemetry data][] getting started guide. You will pick up from where that guide ended. +* Complete the [Collect open telemetry data][] task. You will pick up from where that guide ended. ## The pipeline -You can start with the {{< param "PRODUCT_NAME" >}} configuration you created in the [Collect open telemetry data][] Getting Started guide. +You can start with the {{< param "PRODUCT_NAME" >}} configuration you created in the [Collect open telemetry data][] task. ```river otelcol.receiver.otlp "example" { @@ -108,7 +114,7 @@ loki.write "default" { To use Loki with basic-auth, which is required with Grafana Cloud Loki, you must configure the [loki.write][] component. You can get the Loki configuration from the Loki **Details** page in the [Grafana Cloud Portal][]: -![](../../../assets/getting-started/loki-config.png) +![](../../../assets/tasks/loki-config.png) ```river otelcol.exporter.loki "grafana_cloud_loki" { @@ -143,7 +149,7 @@ otelcol.exporter.otlp "default" { To use Tempo with basic-auth, which is required with Grafana Cloud Tempo, you must use the [otelcol.auth.basic][] component. You can get the Tempo configuration from the Tempo **Details** page in the [Grafana Cloud Portal][]: -![](../../../assets/getting-started/tempo-config.png) +![](../../../assets/tasks/tempo-config.png) ```river otelcol.exporter.otlp "grafana_cloud_tempo" { @@ -180,7 +186,7 @@ prometheus.remote_write "default" { To use Prometheus with basic-auth, which is required with Grafana Cloud Prometheus, you must configure the [prometheus.remote_write][] component. You can get the Prometheus configuration from the Prometheus **Details** page in the [Grafana Cloud Portal][]: -![](../../../assets/getting-started/prometheus-config.png) +![](../../../assets/tasks/prometheus-config.png) ```river otelcol.exporter.prometheus "grafana_cloud_prometheus" { @@ -306,7 +312,7 @@ ts=2023-05-09T09:37:15.304234Z component=otelcol.receiver.otlp.default level=inf You can now check the pipeline graphically by visiting http://localhost:12345/graph -![](../../../assets/getting-started/otlp-lgtm-graph.png) +![](../../../assets/tasks/otlp-lgtm-graph.png) [OpenTelemetry]: https://opentelemetry.io [Grafana Loki]: https://grafana.com/oss/loki/ @@ -316,8 +322,8 @@ You can now check the pipeline graphically by visiting http://localhost:12345/gr [Grafana Mimir]: https://grafana.com/oss/mimir/ {{% docs/reference %}} -[Collect open telemetry data]: "/docs/agent/ -> /docs/agent//flow/getting-started/collect-opentelemetry-data.md" -[Collect open telemetry data]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/getting-started/collect-opentelemetry-data.md" +[Collect open telemetry data]: "/docs/agent/ -> /docs/agent//flow/tasks/collect-opentelemetry-data.md" +[Collect open telemetry data]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/tasks/collect-opentelemetry-data.md" [Components]: "/docs/agent/ -> /docs/agent//flow/concepts/components.md" [Components]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/concepts/components.md" [loki.write]: "/docs/agent/ -> /docs/agent//flow/reference/components/loki.write.md" From 404423b7a0d393d53b0adaf1d4e1ddf92f4850a8 Mon Sep 17 00:00:00 2001 From: Paulin Todev Date: Fri, 5 Jan 2024 10:53:34 +0000 Subject: [PATCH 06/68] Remove replace directive for golang.org/x/exp (#5972) * Remove replace directive for golang.org/x/exp * Update pyroscope/ebpf from 0.4.0 to 0.4.1 * Fill in missing docs about HTTP client options. Fix missing defaults. Add an "unsupported" converter diagnostic for keep_dropped_targets. Add HTTP client options to AWS Lightsail SD. * Add discovery.ovhcloud * Add a converter for discovery.ovhcloud * Update cloudwatch_exporter docs * Fix converter tests * Mention Prometheus update in the changelog. --------- Co-authored-by: William Dumont --- CHANGELOG.md | 11 +- component/all/all.go | 1 + component/discovery/aws/ec2.go | 5 +- component/discovery/aws/lightsail.go | 40 +++-- component/discovery/azure/azure.go | 2 + component/discovery/consul/consul.go | 11 +- .../discovery/digitalocean/digitalocean.go | 2 + component/discovery/ovhcloud/ovhcloud.go | 94 ++++++++++ component/discovery/ovhcloud/ovhcloud_test.go | 135 ++++++++++++++ .../prometheusconvert/component/ec2.go | 42 ++--- .../prometheusconvert/component/lightsail.go | 40 ++--- .../prometheusconvert/component/ovhcloud.go | 40 +++++ .../prometheusconvert/component/scrape.go | 5 + .../component/service_discovery.go | 6 + .../prometheusconvert/testdata/azure.river | 6 +- .../prometheusconvert/testdata/consul.river | 8 +- .../testdata/digitalocean.river | 10 +- .../testdata/discovery.river | 4 - .../testdata/discovery_relabel.river | 2 - .../prometheusconvert/testdata/ec2.diags | 1 - .../prometheusconvert/testdata/ec2.river | 5 + .../testdata/lightsail.diags | 1 - .../testdata/lightsail.river | 5 + .../prometheusconvert/testdata/ovhcloud.river | 43 +++++ .../prometheusconvert/testdata/ovhcloud.yaml | 21 +++ .../prometheusconvert/testdata/scrape.diags | 1 + .../prometheusconvert/testdata/scrape.yaml | 2 + .../testdata/unsupported.diags | 1 + .../testdata/unsupported.yaml | 1 + .../promtailconvert/testdata/azure.river | 2 - .../promtailconvert/testdata/consul.river | 2 - .../testdata/digitalocean.river | 2 - .../testdata/prom_remote_write.river | 4 +- .../staticconvert/testdata/prom_scrape.river | 8 +- .../testdata/promtail_prom.river | 8 +- .../flow/reference/compatibility/_index.md | 1 + .../reference/components/discovery.consul.md | 1 + .../reference/components/discovery.docker.md | 1 + .../components/discovery.dockerswarm.md | 1 + .../reference/components/discovery.ec2.md | 29 +++ .../reference/components/discovery.eureka.md | 13 ++ .../reference/components/discovery.hetzner.md | 1 + .../reference/components/discovery.http.md | 15 ++ .../reference/components/discovery.ionos.md | 14 +- .../components/discovery.kubernetes.md | 1 + .../reference/components/discovery.kuma.md | 1 + .../reference/components/discovery.linode.md | 1 + .../components/discovery.marathon.md | 1 + .../reference/components/discovery.nomad.md | 1 + .../components/discovery.ovhcloud.md | 165 ++++++++++++++++++ .../components/discovery.puppetdb.md | 1 + .../prometheus.exporter.cloudwatch.md | 2 + .../reference/components/prometheus.scrape.md | 46 ++--- .../cloudwatch-exporter-config.md | 2 + go.mod | 49 ++---- go.sum | 149 +++++++++------- pkg/metrics/instance/configstore/api_test.go | 1 + pkg/metrics/instance/host_filter_test.go | 1 + pkg/metrics/instance/marshal_test.go | 2 + 59 files changed, 822 insertions(+), 248 deletions(-) create mode 100644 component/discovery/ovhcloud/ovhcloud.go create mode 100644 component/discovery/ovhcloud/ovhcloud_test.go create mode 100644 converter/internal/prometheusconvert/component/ovhcloud.go delete mode 100644 converter/internal/prometheusconvert/testdata/ec2.diags delete mode 100644 converter/internal/prometheusconvert/testdata/lightsail.diags create mode 100644 converter/internal/prometheusconvert/testdata/ovhcloud.river create mode 100644 converter/internal/prometheusconvert/testdata/ovhcloud.yaml create mode 100644 converter/internal/prometheusconvert/testdata/scrape.diags create mode 100644 docs/sources/flow/reference/components/discovery.ovhcloud.md diff --git a/CHANGELOG.md b/CHANGELOG.md index a86d9b1960f6..4d008e4ab023 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,10 @@ Main (unreleased) - This change will not break any existing configurations and you can opt in to validation via the `validate_dimensions` configuration option. - Before this change, pulling metrics for azure resources with variable dimensions required one configuration per metric + dimension combination to avoid an error. - After this change, you can include all metrics and dimensions in a single configuration and the Azure APIs will only return dimensions which are valid for the various metrics. + +### Features + +- A new `discovery.ovhcloud` component for discovering scrape targets on OVHcloud. (@ptodev) ### Enhancements @@ -77,6 +81,7 @@ Main (unreleased) - Add `max_cache_size` to `prometheus.relabel` to allow configurability instead of hard coded 100,000. (@mattdurham) - Add support for `http_sd_config` within a `scrape_config` for prometheus to flow config conversion. (@erikbaranowski) +- `discovery.lightsail` now supports additional parameters for configuring HTTP client settings. (@ptodev) ### Bugfixes @@ -100,7 +105,11 @@ Main (unreleased) - Bump github.com/IBM/sarama from v1.41.2 to v1.42.1 -- Attatch unique Agent ID header to remote-write requests. (@captncraig) +- Attach unique Agent ID header to remote-write requests. (@captncraig) + +- Update to v2.48.1 of `github.com/prometheus/prometheus`. + Previously, a custom fork of v2.47.2 was used. + The custom fork of v2.47.2 also contained prometheus#12729 and prometheus#12677. v0.38.1 (2023-11-30) -------------------- diff --git a/component/all/all.go b/component/all/all.go index 3822deee7c9c..b404f27ad4eb 100644 --- a/component/all/all.go +++ b/component/all/all.go @@ -24,6 +24,7 @@ import ( _ "github.com/grafana/agent/component/discovery/nerve" // Import discovery.nerve _ "github.com/grafana/agent/component/discovery/nomad" // Import discovery.nomad _ "github.com/grafana/agent/component/discovery/openstack" // Import discovery.openstack + _ "github.com/grafana/agent/component/discovery/ovhcloud" // Import discovery.ovhcloud _ "github.com/grafana/agent/component/discovery/puppetdb" // Import discovery.puppetdb _ "github.com/grafana/agent/component/discovery/relabel" // Import discovery.relabel _ "github.com/grafana/agent/component/discovery/scaleway" // Import discovery.scaleway diff --git a/component/discovery/aws/ec2.go b/component/discovery/aws/ec2.go index 7672165e05e0..dfc6d00f5d53 100644 --- a/component/discovery/aws/ec2.go +++ b/component/discovery/aws/ec2.go @@ -69,8 +69,9 @@ func (args EC2Arguments) Convert() *promaws.EC2SDConfig { } var DefaultEC2SDConfig = EC2Arguments{ - Port: 80, - RefreshInterval: 60 * time.Second, + Port: 80, + RefreshInterval: 60 * time.Second, + HTTPClientConfig: config.DefaultHTTPClientConfig, } // SetToDefault implements river.Defaulter. diff --git a/component/discovery/aws/lightsail.go b/component/discovery/aws/lightsail.go index 3f47366cc8b7..2b414a54faff 100644 --- a/component/discovery/aws/lightsail.go +++ b/component/discovery/aws/lightsail.go @@ -7,6 +7,7 @@ import ( "github.com/aws/aws-sdk-go/aws/ec2metadata" "github.com/aws/aws-sdk-go/aws/session" "github.com/grafana/agent/component" + "github.com/grafana/agent/component/common/config" "github.com/grafana/agent/component/discovery" "github.com/grafana/river/rivertypes" promcfg "github.com/prometheus/common/config" @@ -27,34 +28,37 @@ func init() { // LightsailArguments is the configuration for AWS Lightsail based service discovery. type LightsailArguments struct { - Endpoint string `river:"endpoint,attr,optional"` - Region string `river:"region,attr,optional"` - AccessKey string `river:"access_key,attr,optional"` - SecretKey rivertypes.Secret `river:"secret_key,attr,optional"` - Profile string `river:"profile,attr,optional"` - RoleARN string `river:"role_arn,attr,optional"` - RefreshInterval time.Duration `river:"refresh_interval,attr,optional"` - Port int `river:"port,attr,optional"` + Endpoint string `river:"endpoint,attr,optional"` + Region string `river:"region,attr,optional"` + AccessKey string `river:"access_key,attr,optional"` + SecretKey rivertypes.Secret `river:"secret_key,attr,optional"` + Profile string `river:"profile,attr,optional"` + RoleARN string `river:"role_arn,attr,optional"` + RefreshInterval time.Duration `river:"refresh_interval,attr,optional"` + Port int `river:"port,attr,optional"` + HTTPClientConfig config.HTTPClientConfig `river:",squash"` } func (args LightsailArguments) Convert() *promaws.LightsailSDConfig { cfg := &promaws.LightsailSDConfig{ - Endpoint: args.Endpoint, - Region: args.Region, - AccessKey: args.AccessKey, - SecretKey: promcfg.Secret(args.SecretKey), - Profile: args.Profile, - RoleARN: args.RoleARN, - RefreshInterval: model.Duration(args.RefreshInterval), - Port: args.Port, + Endpoint: args.Endpoint, + Region: args.Region, + AccessKey: args.AccessKey, + SecretKey: promcfg.Secret(args.SecretKey), + Profile: args.Profile, + RoleARN: args.RoleARN, + RefreshInterval: model.Duration(args.RefreshInterval), + Port: args.Port, + HTTPClientConfig: *args.HTTPClientConfig.Convert(), } return cfg } // DefaultLightsailSDConfig is the default Lightsail SD configuration. var DefaultLightsailSDConfig = LightsailArguments{ - Port: 80, - RefreshInterval: 60 * time.Second, + Port: 80, + RefreshInterval: 60 * time.Second, + HTTPClientConfig: config.DefaultHTTPClientConfig, } // SetToDefault implements river.Defaulter. diff --git a/component/discovery/azure/azure.go b/component/discovery/azure/azure.go index 3e1ef563625c..9ed1363f5250 100644 --- a/component/discovery/azure/azure.go +++ b/component/discovery/azure/azure.go @@ -55,6 +55,8 @@ var DefaultArguments = Arguments{ Environment: azure.PublicCloud.Name, Port: 80, RefreshInterval: 5 * time.Minute, + FollowRedirects: true, + EnableHTTP2: true, } // SetToDefault implements river.Defaulter. diff --git a/component/discovery/consul/consul.go b/component/discovery/consul/consul.go index 1192bae6c6d2..de6aae2d4510 100644 --- a/component/discovery/consul/consul.go +++ b/component/discovery/consul/consul.go @@ -45,11 +45,12 @@ type Arguments struct { } var DefaultArguments = Arguments{ - Server: "localhost:8500", - TagSeparator: ",", - Scheme: "http", - AllowStale: true, - RefreshInterval: 30 * time.Second, + Server: "localhost:8500", + TagSeparator: ",", + Scheme: "http", + AllowStale: true, + RefreshInterval: 30 * time.Second, + HTTPClientConfig: config.DefaultHTTPClientConfig, } // SetToDefault implements river.Defaulter. diff --git a/component/discovery/digitalocean/digitalocean.go b/component/discovery/digitalocean/digitalocean.go index 360ef70ce818..bde15337da88 100644 --- a/component/discovery/digitalocean/digitalocean.go +++ b/component/discovery/digitalocean/digitalocean.go @@ -39,6 +39,8 @@ type Arguments struct { var DefaultArguments = Arguments{ Port: 80, RefreshInterval: time.Minute, + FollowRedirects: true, + EnableHTTP2: true, } // SetToDefault implements river.Defaulter. diff --git a/component/discovery/ovhcloud/ovhcloud.go b/component/discovery/ovhcloud/ovhcloud.go new file mode 100644 index 000000000000..e3479f45a5f7 --- /dev/null +++ b/component/discovery/ovhcloud/ovhcloud.go @@ -0,0 +1,94 @@ +package ovhcloud + +import ( + "fmt" + "time" + + "github.com/grafana/agent/component" + "github.com/grafana/agent/component/discovery" + "github.com/grafana/river/rivertypes" + "github.com/prometheus/common/config" + "github.com/prometheus/common/model" + prom_discovery "github.com/prometheus/prometheus/discovery/ovhcloud" +) + +func init() { + component.Register(component.Registration{ + Name: "discovery.ovhcloud", + Args: Arguments{}, + Exports: discovery.Exports{}, + + Build: func(opts component.Options, args component.Arguments) (component.Component, error) { + return New(opts, args.(Arguments)) + }, + }) +} + +// Arguments configure the discovery.ovhcloud component. +type Arguments struct { + Endpoint string `river:"endpoint,attr,optional"` + ApplicationKey string `river:"application_key,attr"` + ApplicationSecret rivertypes.Secret `river:"application_secret,attr"` + ConsumerKey rivertypes.Secret `river:"consumer_key,attr"` + RefreshInterval time.Duration `river:"refresh_interval,attr,optional"` + Service string `river:"service,attr"` +} + +// DefaultArguments is used to initialize default values for Arguments. +var DefaultArguments = Arguments{ + Endpoint: "ovh-eu", + RefreshInterval: 60 * time.Second, +} + +// SetToDefault implements river.Defaulter. +func (args *Arguments) SetToDefault() { + *args = DefaultArguments +} + +// Validate implements river.Validator. +func (args *Arguments) Validate() error { + if args.Endpoint == "" { + return fmt.Errorf("endpoint cannot be empty") + } + + if args.ApplicationKey == "" { + return fmt.Errorf("application_key cannot be empty") + } + + if args.ApplicationSecret == "" { + return fmt.Errorf("application_secret cannot be empty") + } + + if args.ConsumerKey == "" { + return fmt.Errorf("consumer_key cannot be empty") + } + + switch args.Service { + case "dedicated_server", "vps": + // Valid value - do nothing. + default: + return fmt.Errorf("unknown service: %v", args.Service) + } + + return nil +} + +// Convert returns the upstream configuration struct. +func (args *Arguments) Convert() *prom_discovery.SDConfig { + return &prom_discovery.SDConfig{ + Endpoint: args.Endpoint, + ApplicationKey: args.ApplicationKey, + ApplicationSecret: config.Secret(args.ApplicationSecret), + ConsumerKey: config.Secret(args.ConsumerKey), + RefreshInterval: model.Duration(args.RefreshInterval), + Service: args.Service, + } +} + +// New returns a new instance of a discovery.ovhcloud component. +func New(opts component.Options, args Arguments) (*discovery.Component, error) { + return discovery.New(opts, args, func(args component.Arguments) (discovery.Discoverer, error) { + newArgs := args.(Arguments) + return prom_discovery.NewDiscovery(newArgs.Convert(), opts.Logger) + }) +} diff --git a/component/discovery/ovhcloud/ovhcloud_test.go b/component/discovery/ovhcloud/ovhcloud_test.go new file mode 100644 index 000000000000..8e579574fc67 --- /dev/null +++ b/component/discovery/ovhcloud/ovhcloud_test.go @@ -0,0 +1,135 @@ +package ovhcloud_test + +import ( + "testing" + "time" + + "github.com/grafana/agent/component/discovery/ovhcloud" + "github.com/grafana/river" + "github.com/prometheus/common/model" + prom_ovh "github.com/prometheus/prometheus/discovery/ovhcloud" + "github.com/stretchr/testify/require" +) + +func TestUnmarshal(t *testing.T) { + tests := []struct { + testName string + cfg string + expected *prom_ovh.SDConfig + errorMsg string + }{ + { + testName: "defaults", + cfg: ` + application_key = "appkey" + application_secret = "appsecret" + consumer_key = "consumerkey" + service = "dedicated_server" + `, + expected: &prom_ovh.SDConfig{ + Endpoint: ovhcloud.DefaultArguments.Endpoint, + ApplicationKey: "appkey", + ApplicationSecret: "appsecret", + ConsumerKey: "consumerkey", + RefreshInterval: model.Duration(ovhcloud.DefaultArguments.RefreshInterval), + Service: "dedicated_server", + }, + }, + { + testName: "explicit", + cfg: ` + endpoint = "custom-endpoint" + refresh_interval = "11m" + application_key = "appkey" + application_secret = "appsecret" + consumer_key = "consumerkey" + service = "vps" + `, + expected: &prom_ovh.SDConfig{ + Endpoint: "custom-endpoint", + ApplicationKey: "appkey", + ApplicationSecret: "appsecret", + ConsumerKey: "consumerkey", + RefreshInterval: model.Duration(11 * time.Minute), + Service: "vps", + }, + }, + { + testName: "empty application key", + cfg: ` + endpoint = "custom-endpoint" + refresh_interval = "11m" + application_key = "" + application_secret = "appsecret" + consumer_key = "consumerkey" + service = "vps" + `, + errorMsg: "application_key cannot be empty", + }, + { + testName: "empty application secret", + cfg: ` + endpoint = "custom-endpoint" + refresh_interval = "11m" + application_key = "appkey" + application_secret = "" + consumer_key = "consumerkey" + service = "vps" + `, + errorMsg: "application_secret cannot be empty", + }, + { + testName: "empty consumer key", + cfg: ` + endpoint = "custom-endpoint" + refresh_interval = "11m" + application_key = "appkey" + application_secret = "appsecret" + consumer_key = "" + service = "vps" + `, + errorMsg: "consumer_key cannot be empty", + }, + { + testName: "empty endpoint", + cfg: ` + endpoint = "" + refresh_interval = "11m" + application_key = "appkey" + application_secret = "appsecret" + consumer_key = "consumerkey" + service = "vps" + `, + errorMsg: "endpoint cannot be empty", + }, + { + testName: "unknown service", + cfg: ` + endpoint = "custom-endpoint" + refresh_interval = "11m" + application_key = "appkey" + application_secret = "appsecret" + consumer_key = "consumerkey" + service = "asdf" + `, + errorMsg: "unknown service: asdf", + }, + } + + for _, tc := range tests { + t.Run(tc.testName, func(t *testing.T) { + var args ovhcloud.Arguments + err := river.Unmarshal([]byte(tc.cfg), &args) + if tc.errorMsg != "" { + require.ErrorContains(t, err, tc.errorMsg) + return + } + + require.NoError(t, err) + + promArgs := args.Convert() + + require.Equal(t, tc.expected, promArgs) + }) + } +} diff --git a/converter/internal/prometheusconvert/component/ec2.go b/converter/internal/prometheusconvert/component/ec2.go index acd89755d165..5edf6ec0bac3 100644 --- a/converter/internal/prometheusconvert/component/ec2.go +++ b/converter/internal/prometheusconvert/component/ec2.go @@ -9,7 +9,6 @@ import ( "github.com/grafana/agent/converter/internal/common" "github.com/grafana/agent/converter/internal/prometheusconvert/build" "github.com/grafana/river/rivertypes" - prom_config "github.com/prometheus/common/config" prom_aws "github.com/prometheus/prometheus/discovery/aws" ) @@ -22,27 +21,7 @@ func appendDiscoveryEC2(pb *build.PrometheusBlocks, label string, sdConfig *prom } func ValidateDiscoveryEC2(sdConfig *prom_aws.EC2SDConfig) diag.Diagnostics { - var diags diag.Diagnostics - - var nilBasicAuth *prom_config.BasicAuth - var nilAuthorization *prom_config.Authorization - var nilOAuth2 *prom_config.OAuth2 - - diags.AddAll(common.ValidateSupported(common.NotEquals, sdConfig.HTTPClientConfig.BasicAuth, nilBasicAuth, "ec2_sd_configs basic_auth", "")) - diags.AddAll(common.ValidateSupported(common.NotEquals, sdConfig.HTTPClientConfig.Authorization, nilAuthorization, "ec2_sd_configs authorization", "")) - diags.AddAll(common.ValidateSupported(common.NotEquals, sdConfig.HTTPClientConfig.OAuth2, nilOAuth2, "ec2_sd_configs oauth2", "")) - diags.AddAll(common.ValidateSupported(common.NotDeepEquals, sdConfig.HTTPClientConfig.BearerToken, prom_config.DefaultHTTPClientConfig.BearerToken, "ec2_sd_configs bearer_token", "")) - diags.AddAll(common.ValidateSupported(common.NotDeepEquals, sdConfig.HTTPClientConfig.BearerTokenFile, prom_config.DefaultHTTPClientConfig.BearerTokenFile, "ec2_sd_configs bearer_token_file", "")) - diags.AddAll(common.ValidateSupported(common.NotDeepEquals, sdConfig.HTTPClientConfig.FollowRedirects, prom_config.DefaultHTTPClientConfig.FollowRedirects, "ec2_sd_configs follow_redirects", "")) - diags.AddAll(common.ValidateSupported(common.NotDeepEquals, sdConfig.HTTPClientConfig.EnableHTTP2, prom_config.DefaultHTTPClientConfig.EnableHTTP2, "ec2_sd_configs enable_http2", "")) - diags.AddAll(common.ValidateSupported(common.NotDeepEquals, sdConfig.HTTPClientConfig.ProxyConfig, prom_config.DefaultHTTPClientConfig.ProxyConfig, "ec2_sd_configs proxy", "")) - - // Do a last check in case any of the specific checks missed anything. - if len(diags) == 0 { - diags.AddAll(common.ValidateSupported(common.NotDeepEquals, sdConfig.HTTPClientConfig, prom_config.DefaultHTTPClientConfig, "ec2_sd_configs http_client_config", "")) - } - - return diags + return common.ValidateHttpClientConfig(&sdConfig.HTTPClientConfig) } func toDiscoveryEC2(sdConfig *prom_aws.EC2SDConfig) *aws.EC2Arguments { @@ -51,15 +30,16 @@ func toDiscoveryEC2(sdConfig *prom_aws.EC2SDConfig) *aws.EC2Arguments { } return &aws.EC2Arguments{ - Endpoint: sdConfig.Endpoint, - Region: sdConfig.Region, - AccessKey: sdConfig.AccessKey, - SecretKey: rivertypes.Secret(sdConfig.SecretKey), - Profile: sdConfig.Profile, - RoleARN: sdConfig.RoleARN, - RefreshInterval: time.Duration(sdConfig.RefreshInterval), - Port: sdConfig.Port, - Filters: toEC2Filters(sdConfig.Filters), + Endpoint: sdConfig.Endpoint, + Region: sdConfig.Region, + AccessKey: sdConfig.AccessKey, + SecretKey: rivertypes.Secret(sdConfig.SecretKey), + Profile: sdConfig.Profile, + RoleARN: sdConfig.RoleARN, + RefreshInterval: time.Duration(sdConfig.RefreshInterval), + Port: sdConfig.Port, + Filters: toEC2Filters(sdConfig.Filters), + HTTPClientConfig: *common.ToHttpClientConfig(&sdConfig.HTTPClientConfig), } } diff --git a/converter/internal/prometheusconvert/component/lightsail.go b/converter/internal/prometheusconvert/component/lightsail.go index 10480bd082ff..9a97c2f506b4 100644 --- a/converter/internal/prometheusconvert/component/lightsail.go +++ b/converter/internal/prometheusconvert/component/lightsail.go @@ -9,7 +9,6 @@ import ( "github.com/grafana/agent/converter/internal/common" "github.com/grafana/agent/converter/internal/prometheusconvert/build" "github.com/grafana/river/rivertypes" - prom_config "github.com/prometheus/common/config" prom_aws "github.com/prometheus/prometheus/discovery/aws" ) @@ -22,27 +21,7 @@ func appendDiscoveryLightsail(pb *build.PrometheusBlocks, label string, sdConfig } func ValidateDiscoveryLightsail(sdConfig *prom_aws.LightsailSDConfig) diag.Diagnostics { - var diags diag.Diagnostics - - var nilBasicAuth *prom_config.BasicAuth - var nilAuthorization *prom_config.Authorization - var nilOAuth2 *prom_config.OAuth2 - - diags.AddAll(common.ValidateSupported(common.NotEquals, sdConfig.HTTPClientConfig.BasicAuth, nilBasicAuth, "lightsail_sd_configs basic_auth", "")) - diags.AddAll(common.ValidateSupported(common.NotEquals, sdConfig.HTTPClientConfig.Authorization, nilAuthorization, "lightsail_sd_configs authorization", "")) - diags.AddAll(common.ValidateSupported(common.NotEquals, sdConfig.HTTPClientConfig.OAuth2, nilOAuth2, "lightsail_sd_configs oauth2", "")) - diags.AddAll(common.ValidateSupported(common.NotDeepEquals, sdConfig.HTTPClientConfig.BearerToken, prom_config.DefaultHTTPClientConfig.BearerToken, "lightsail_sd_configs bearer_token", "")) - diags.AddAll(common.ValidateSupported(common.NotDeepEquals, sdConfig.HTTPClientConfig.BearerTokenFile, prom_config.DefaultHTTPClientConfig.BearerTokenFile, "lightsail_sd_configs bearer_token_file", "")) - diags.AddAll(common.ValidateSupported(common.NotDeepEquals, sdConfig.HTTPClientConfig.FollowRedirects, prom_config.DefaultHTTPClientConfig.FollowRedirects, "lightsail_sd_configs follow_redirects", "")) - diags.AddAll(common.ValidateSupported(common.NotDeepEquals, sdConfig.HTTPClientConfig.EnableHTTP2, prom_config.DefaultHTTPClientConfig.EnableHTTP2, "lightsail_sd_configs enable_http2", "")) - diags.AddAll(common.ValidateSupported(common.NotDeepEquals, sdConfig.HTTPClientConfig.ProxyConfig, prom_config.DefaultHTTPClientConfig.ProxyConfig, "lightsail_sd_configs proxy", "")) - - // Do a last check in case any of the specific checks missed anything. - if len(diags) == 0 { - diags.AddAll(common.ValidateSupported(common.NotDeepEquals, sdConfig.HTTPClientConfig, prom_config.DefaultHTTPClientConfig, "lightsail_sd_configs http_client_config", "")) - } - - return diags + return common.ValidateHttpClientConfig(&sdConfig.HTTPClientConfig) } func toDiscoveryLightsail(sdConfig *prom_aws.LightsailSDConfig) *aws.LightsailArguments { @@ -51,13 +30,14 @@ func toDiscoveryLightsail(sdConfig *prom_aws.LightsailSDConfig) *aws.LightsailAr } return &aws.LightsailArguments{ - Endpoint: sdConfig.Endpoint, - Region: sdConfig.Region, - AccessKey: sdConfig.AccessKey, - SecretKey: rivertypes.Secret(sdConfig.SecretKey), - Profile: sdConfig.Profile, - RoleARN: sdConfig.RoleARN, - RefreshInterval: time.Duration(sdConfig.RefreshInterval), - Port: sdConfig.Port, + Endpoint: sdConfig.Endpoint, + Region: sdConfig.Region, + AccessKey: sdConfig.AccessKey, + SecretKey: rivertypes.Secret(sdConfig.SecretKey), + Profile: sdConfig.Profile, + RoleARN: sdConfig.RoleARN, + RefreshInterval: time.Duration(sdConfig.RefreshInterval), + Port: sdConfig.Port, + HTTPClientConfig: *common.ToHttpClientConfig(&sdConfig.HTTPClientConfig), } } diff --git a/converter/internal/prometheusconvert/component/ovhcloud.go b/converter/internal/prometheusconvert/component/ovhcloud.go new file mode 100644 index 000000000000..f4a59fd525cf --- /dev/null +++ b/converter/internal/prometheusconvert/component/ovhcloud.go @@ -0,0 +1,40 @@ +package component + +import ( + "time" + + "github.com/grafana/agent/component/discovery" + "github.com/grafana/agent/component/discovery/ovhcloud" + "github.com/grafana/agent/converter/diag" + "github.com/grafana/agent/converter/internal/common" + "github.com/grafana/agent/converter/internal/prometheusconvert/build" + "github.com/grafana/river/rivertypes" + prom_discovery "github.com/prometheus/prometheus/discovery/ovhcloud" +) + +func appendDiscoveryOvhcloud(pb *build.PrometheusBlocks, label string, sdConfig *prom_discovery.SDConfig) discovery.Exports { + discoveryOvhcloudArgs := toDiscoveryOvhcloud(sdConfig) + name := []string{"discovery", "ovhcloud"} + block := common.NewBlockWithOverride(name, label, discoveryOvhcloudArgs) + pb.DiscoveryBlocks = append(pb.DiscoveryBlocks, build.NewPrometheusBlock(block, name, label, "", "")) + return common.NewDiscoveryExports("discovery.ovhcloud." + label + ".targets") +} + +func ValidateDiscoveryOvhcloud(sdConfig *prom_discovery.SDConfig) diag.Diagnostics { + return nil +} + +func toDiscoveryOvhcloud(sdConfig *prom_discovery.SDConfig) *ovhcloud.Arguments { + if sdConfig == nil { + return nil + } + + return &ovhcloud.Arguments{ + Endpoint: sdConfig.Endpoint, + ApplicationKey: sdConfig.ApplicationKey, + ApplicationSecret: rivertypes.Secret(sdConfig.ApplicationSecret), + ConsumerKey: rivertypes.Secret(sdConfig.ConsumerKey), + RefreshInterval: time.Duration(sdConfig.RefreshInterval), + Service: sdConfig.Service, + } +} diff --git a/converter/internal/prometheusconvert/component/scrape.go b/converter/internal/prometheusconvert/component/scrape.go index 651e4e2c5bc1..a2005cf85fbb 100644 --- a/converter/internal/prometheusconvert/component/scrape.go +++ b/converter/internal/prometheusconvert/component/scrape.go @@ -30,7 +30,12 @@ func AppendPrometheusScrape(pb *build.PrometheusBlocks, scrapeConfig *prom_confi func ValidatePrometheusScrape(scrapeConfig *prom_config.ScrapeConfig) diag.Diagnostics { var diags diag.Diagnostics + // https://github.com/grafana/agent/pull/5972#discussion_r1441980155 + diags.AddAll(common.ValidateSupported(common.NotEquals, scrapeConfig.TrackTimestampsStaleness, false, "scrape_configs track_timestamps_staleness", "")) + // https://github.com/prometheus/prometheus/commit/40240c9c1cb290fe95f1e61886b23fab860aeacd diags.AddAll(common.ValidateSupported(common.NotEquals, scrapeConfig.NativeHistogramBucketLimit, uint(0), "scrape_configs native_histogram_bucket_limit", "")) + // https://github.com/prometheus/prometheus/pull/12647 + diags.AddAll(common.ValidateSupported(common.NotEquals, scrapeConfig.KeepDroppedTargets, uint(0), "scrape_configs keep_dropped_targets", "")) diags.AddAll(common.ValidateHttpClientConfig(&scrapeConfig.HTTPClientConfig)) return diags diff --git a/converter/internal/prometheusconvert/component/service_discovery.go b/converter/internal/prometheusconvert/component/service_discovery.go index 52780475e63a..69c179f1ef9a 100644 --- a/converter/internal/prometheusconvert/component/service_discovery.go +++ b/converter/internal/prometheusconvert/component/service_discovery.go @@ -25,6 +25,7 @@ import ( prom_marathon "github.com/prometheus/prometheus/discovery/marathon" prom_docker "github.com/prometheus/prometheus/discovery/moby" prom_openstack "github.com/prometheus/prometheus/discovery/openstack" + prom_ovhcloud "github.com/prometheus/prometheus/discovery/ovhcloud" prom_scaleway "github.com/prometheus/prometheus/discovery/scaleway" prom_triton "github.com/prometheus/prometheus/discovery/triton" prom_xds "github.com/prometheus/prometheus/discovery/xds" @@ -100,6 +101,9 @@ func AppendServiceDiscoveryConfig(pb *build.PrometheusBlocks, serviceDiscoveryCo case *prom_docker.DockerSwarmSDConfig: labelCounts["dockerswarm"]++ return appendDiscoveryDockerswarm(pb, common.LabelWithIndex(labelCounts["dockerswarm"]-1, label), sdc) + case *prom_ovhcloud.SDConfig: + labelCounts["ovhcloud"]++ + return appendDiscoveryOvhcloud(pb, common.LabelWithIndex(labelCounts["ovhcloud"]-1, label), sdc) default: return discovery.Exports{} } @@ -151,6 +155,8 @@ func ValidateServiceDiscoveryConfig(serviceDiscoveryConfig prom_discover.Config) return ValidateDiscoveryOpenstack(sdc) case *prom_docker.DockerSwarmSDConfig: return ValidateDiscoveryDockerswarm(sdc) + case *prom_ovhcloud.SDConfig: + return ValidateDiscoveryOvhcloud(sdc) default: var diags diag.Diagnostics diags.Add(diag.SeverityLevelError, fmt.Sprintf("The converter does not support converting the provided %s service discovery.", serviceDiscoveryConfig.Name())) diff --git a/converter/internal/prometheusconvert/testdata/azure.river b/converter/internal/prometheusconvert/testdata/azure.river index 368673474b22..e1bc751bf05d 100644 --- a/converter/internal/prometheusconvert/testdata/azure.river +++ b/converter/internal/prometheusconvert/testdata/azure.river @@ -10,8 +10,6 @@ discovery.azure "prometheus1" { managed_identity { client_id = "client" } - follow_redirects = true - enable_http2 = true } discovery.azure "prometheus2" { @@ -26,8 +24,8 @@ discovery.azure "prometheus2" { managed_identity { client_id = "client" } - proxy_url = "proxy" - enable_http2 = true + proxy_url = "proxy" + follow_redirects = false } prometheus.scrape "prometheus1" { diff --git a/converter/internal/prometheusconvert/testdata/consul.river b/converter/internal/prometheusconvert/testdata/consul.river index b3d7879ed47e..ccf9e8c189c3 100644 --- a/converter/internal/prometheusconvert/testdata/consul.river +++ b/converter/internal/prometheusconvert/testdata/consul.river @@ -1,13 +1,9 @@ discovery.consul "prometheus1" { - services = ["myapp"] - follow_redirects = true - enable_http2 = true + services = ["myapp"] } discovery.consul "prometheus2" { - services = ["otherapp"] - follow_redirects = true - enable_http2 = true + services = ["otherapp"] } prometheus.scrape "prometheus1" { diff --git a/converter/internal/prometheusconvert/testdata/digitalocean.river b/converter/internal/prometheusconvert/testdata/digitalocean.river index 4e39bf9be2c6..27b0629afc15 100644 --- a/converter/internal/prometheusconvert/testdata/digitalocean.river +++ b/converter/internal/prometheusconvert/testdata/digitalocean.river @@ -1,12 +1,6 @@ -discovery.digitalocean "prometheus1" { - follow_redirects = true - enable_http2 = true -} +discovery.digitalocean "prometheus1" { } -discovery.digitalocean "prometheus2" { - follow_redirects = true - enable_http2 = true -} +discovery.digitalocean "prometheus2" { } prometheus.scrape "prometheus1" { targets = concat( diff --git a/converter/internal/prometheusconvert/testdata/discovery.river b/converter/internal/prometheusconvert/testdata/discovery.river index 4ff3cc509ce3..f2c59fa7a4f6 100644 --- a/converter/internal/prometheusconvert/testdata/discovery.river +++ b/converter/internal/prometheusconvert/testdata/discovery.river @@ -10,8 +10,6 @@ discovery.azure "prometheus1" { managed_identity { client_id = "client1" } - follow_redirects = true - enable_http2 = true } discovery.azure "prometheus1_2" { @@ -26,8 +24,6 @@ discovery.azure "prometheus1_2" { managed_identity { client_id = "client2" } - follow_redirects = true - enable_http2 = true } discovery.relabel "prometheus1" { diff --git a/converter/internal/prometheusconvert/testdata/discovery_relabel.river b/converter/internal/prometheusconvert/testdata/discovery_relabel.river index 8d37e5c3a9ad..4b1009886810 100644 --- a/converter/internal/prometheusconvert/testdata/discovery_relabel.river +++ b/converter/internal/prometheusconvert/testdata/discovery_relabel.river @@ -10,8 +10,6 @@ discovery.azure "prometheus2" { managed_identity { client_id = "client" } - follow_redirects = true - enable_http2 = true } discovery.relabel "prometheus1" { diff --git a/converter/internal/prometheusconvert/testdata/ec2.diags b/converter/internal/prometheusconvert/testdata/ec2.diags deleted file mode 100644 index 3301a9ad2213..000000000000 --- a/converter/internal/prometheusconvert/testdata/ec2.diags +++ /dev/null @@ -1 +0,0 @@ -(Error) The converter does not support converting the provided ec2_sd_configs bearer_token_file config. \ No newline at end of file diff --git a/converter/internal/prometheusconvert/testdata/ec2.river b/converter/internal/prometheusconvert/testdata/ec2.river index 22775efe8ed2..d07d133a659b 100644 --- a/converter/internal/prometheusconvert/testdata/ec2.river +++ b/converter/internal/prometheusconvert/testdata/ec2.river @@ -3,6 +3,11 @@ discovery.ec2 "prometheus1" { access_key = "YOUR_ACCESS_KEY" secret_key = "YOUR_SECRET_KEY" port = 8080 + + authorization { + type = "Bearer" + credentials_file = "/tmp/token.file" + } } discovery.ec2 "prometheus2" { diff --git a/converter/internal/prometheusconvert/testdata/lightsail.diags b/converter/internal/prometheusconvert/testdata/lightsail.diags deleted file mode 100644 index 0a96d20e3985..000000000000 --- a/converter/internal/prometheusconvert/testdata/lightsail.diags +++ /dev/null @@ -1 +0,0 @@ -(Error) The converter does not support converting the provided lightsail_sd_configs bearer_token_file config. \ No newline at end of file diff --git a/converter/internal/prometheusconvert/testdata/lightsail.river b/converter/internal/prometheusconvert/testdata/lightsail.river index 754d9c5d39ea..4e1966490532 100644 --- a/converter/internal/prometheusconvert/testdata/lightsail.river +++ b/converter/internal/prometheusconvert/testdata/lightsail.river @@ -3,6 +3,11 @@ discovery.lightsail "prometheus1" { access_key = "YOUR_ACCESS_KEY" secret_key = "YOUR_SECRET_KEY" port = 8080 + + authorization { + type = "Bearer" + credentials_file = "/tmp/token.file" + } } discovery.lightsail "prometheus2" { diff --git a/converter/internal/prometheusconvert/testdata/ovhcloud.river b/converter/internal/prometheusconvert/testdata/ovhcloud.river new file mode 100644 index 000000000000..dff1e85bcee3 --- /dev/null +++ b/converter/internal/prometheusconvert/testdata/ovhcloud.river @@ -0,0 +1,43 @@ +discovery.ovhcloud "prometheus1" { + application_key = "app_key" + application_secret = "app_secret" + consumer_key = "cons_key" + service = "vps" +} + +discovery.ovhcloud "prometheus2" { + endpoint = "ovh-us" + application_key = "app_key_2" + application_secret = "app_secret_2" + consumer_key = "cons_key_2" + refresh_interval = "14m0s" + service = "dedicated_server" +} + +prometheus.scrape "prometheus1" { + targets = concat( + discovery.ovhcloud.prometheus1.targets, + [{ + __address__ = "localhost:9090", + }], + ) + forward_to = [prometheus.remote_write.default.receiver] + job_name = "prometheus1" +} + +prometheus.scrape "prometheus2" { + targets = discovery.ovhcloud.prometheus2.targets + forward_to = [prometheus.remote_write.default.receiver] + job_name = "prometheus2" +} + +prometheus.remote_write "default" { + endpoint { + name = "remote1" + url = "http://remote-write-url1" + + queue_config { } + + metadata_config { } + } +} diff --git a/converter/internal/prometheusconvert/testdata/ovhcloud.yaml b/converter/internal/prometheusconvert/testdata/ovhcloud.yaml new file mode 100644 index 000000000000..2201686989fc --- /dev/null +++ b/converter/internal/prometheusconvert/testdata/ovhcloud.yaml @@ -0,0 +1,21 @@ +scrape_configs: + - job_name: "prometheus1" + static_configs: + - targets: ["localhost:9090"] + ovhcloud_sd_configs: + - application_key: "app_key" + application_secret: "app_secret" + consumer_key: "cons_key" + service: "vps" + - job_name: "prometheus2" + ovhcloud_sd_configs: + - application_key: "app_key_2" + application_secret: "app_secret_2" + consumer_key: "cons_key_2" + service: "dedicated_server" + endpoint: "ovh-us" + refresh_interval: "14m" + +remote_write: + - name: "remote1" + url: "http://remote-write-url1" \ No newline at end of file diff --git a/converter/internal/prometheusconvert/testdata/scrape.diags b/converter/internal/prometheusconvert/testdata/scrape.diags new file mode 100644 index 000000000000..de85de6536cf --- /dev/null +++ b/converter/internal/prometheusconvert/testdata/scrape.diags @@ -0,0 +1 @@ +(Error) The converter does not support converting the provided scrape_configs track_timestamps_staleness config. \ No newline at end of file diff --git a/converter/internal/prometheusconvert/testdata/scrape.yaml b/converter/internal/prometheusconvert/testdata/scrape.yaml index d4b1e7e203c7..54496f296005 100644 --- a/converter/internal/prometheusconvert/testdata/scrape.yaml +++ b/converter/internal/prometheusconvert/testdata/scrape.yaml @@ -6,6 +6,7 @@ global: scrape_configs: - job_name: "prometheus-1" honor_timestamps: false + track_timestamps_staleness: true scrape_interval: 10s scrape_timeout: 5s static_configs: @@ -16,6 +17,7 @@ scrape_configs: username: 'user' password: 'pass' - job_name: "prometheus2" + track_timestamps_staleness: false static_configs: - targets: ["localhost:9091"] - targets: ["localhost:9092"] diff --git a/converter/internal/prometheusconvert/testdata/unsupported.diags b/converter/internal/prometheusconvert/testdata/unsupported.diags index ccdf9bd3da88..966bd0d1e5bf 100644 --- a/converter/internal/prometheusconvert/testdata/unsupported.diags +++ b/converter/internal/prometheusconvert/testdata/unsupported.diags @@ -5,6 +5,7 @@ (Error) The converter does not support converting the provided HTTP Client no_proxy config. (Error) The converter does not support converting the provided nomad service discovery. (Error) The converter does not support converting the provided scrape_configs native_histogram_bucket_limit config. +(Error) The converter does not support converting the provided scrape_configs keep_dropped_targets config. (Error) The converter does not support converting the provided storage config. (Error) The converter does not support converting the provided tracing config. (Error) The converter does not support converting the provided HTTP Client proxy_from_environment config. diff --git a/converter/internal/prometheusconvert/testdata/unsupported.yaml b/converter/internal/prometheusconvert/testdata/unsupported.yaml index bf677c030a39..5d174c36cb8e 100644 --- a/converter/internal/prometheusconvert/testdata/unsupported.yaml +++ b/converter/internal/prometheusconvert/testdata/unsupported.yaml @@ -44,6 +44,7 @@ scrape_configs: - targets: ["localhost:9091"] scrape_classic_histograms: true native_histogram_bucket_limit: 2 + keep_dropped_targets: 1000 remote_write: - name: "remote1" diff --git a/converter/internal/promtailconvert/testdata/azure.river b/converter/internal/promtailconvert/testdata/azure.river index bfbe087b6de4..90a652e05dab 100644 --- a/converter/internal/promtailconvert/testdata/azure.river +++ b/converter/internal/promtailconvert/testdata/azure.river @@ -10,8 +10,6 @@ discovery.azure "fun" { managed_identity { client_id = "client" } - follow_redirects = true - enable_http2 = true } local.file_match "fun" { diff --git a/converter/internal/promtailconvert/testdata/consul.river b/converter/internal/promtailconvert/testdata/consul.river index 20b07e0900b3..72563a502d95 100644 --- a/converter/internal/promtailconvert/testdata/consul.river +++ b/converter/internal/promtailconvert/testdata/consul.river @@ -17,8 +17,6 @@ discovery.consul "fun" { username = "toby" password = "this_password_is_safe_innit?" } - follow_redirects = true - enable_http2 = true } discovery.relabel "fun" { diff --git a/converter/internal/promtailconvert/testdata/digitalocean.river b/converter/internal/promtailconvert/testdata/digitalocean.river index 7308cfa33489..fb71e471c56f 100644 --- a/converter/internal/promtailconvert/testdata/digitalocean.river +++ b/converter/internal/promtailconvert/testdata/digitalocean.river @@ -1,8 +1,6 @@ discovery.digitalocean "fun" { refresh_interval = "10m0s" port = 1234 - follow_redirects = true - enable_http2 = true } local.file_match "fun" { diff --git a/converter/internal/staticconvert/testdata/prom_remote_write.river b/converter/internal/staticconvert/testdata/prom_remote_write.river index df5a9848a234..bc9edcd50834 100644 --- a/converter/internal/staticconvert/testdata/prom_remote_write.river +++ b/converter/internal/staticconvert/testdata/prom_remote_write.river @@ -77,7 +77,7 @@ prometheus.remote_write "metrics_test5_sigv4_explicit" { prometheus.remote_write "metrics_test6_azuread_defaults" { endpoint { - name = "test6_azuread_defaults-50e17f" + name = "test6_azuread_defaults-fbed02" url = "http://localhost:9012/api/prom/push" queue_config { } @@ -94,7 +94,7 @@ prometheus.remote_write "metrics_test6_azuread_defaults" { prometheus.remote_write "metrics_test7_azuread_explicit" { endpoint { - name = "test7_azuread_explicit-0f55f1" + name = "test7_azuread_explicit-416842" url = "http://localhost:9012/api/prom/push" queue_config { } diff --git a/converter/internal/staticconvert/testdata/prom_scrape.river b/converter/internal/staticconvert/testdata/prom_scrape.river index c7db1090e90f..e73fd76733e3 100644 --- a/converter/internal/staticconvert/testdata/prom_scrape.river +++ b/converter/internal/staticconvert/testdata/prom_scrape.river @@ -10,9 +10,7 @@ discovery.azure "metrics_agent_promobee" { managed_identity { client_id = "client" } - proxy_url = "proxy" - follow_redirects = true - enable_http2 = true + proxy_url = "proxy" } discovery.azure "metrics_agent_promobee_2" { @@ -27,9 +25,7 @@ discovery.azure "metrics_agent_promobee_2" { managed_identity { client_id = "client" } - proxy_url = "proxy" - follow_redirects = true - enable_http2 = true + proxy_url = "proxy" } discovery.relabel "metrics_agent_promobee" { diff --git a/converter/internal/staticconvert/testdata/promtail_prom.river b/converter/internal/staticconvert/testdata/promtail_prom.river index f3b810dbe704..e31469f5267b 100644 --- a/converter/internal/staticconvert/testdata/promtail_prom.river +++ b/converter/internal/staticconvert/testdata/promtail_prom.river @@ -1,7 +1,5 @@ discovery.consul "metrics_name_jobName" { - services = ["myapp"] - follow_redirects = true - enable_http2 = true + services = ["myapp"] } prometheus.scrape "metrics_name_jobName" { @@ -48,8 +46,6 @@ discovery.consul "logs_name_jobName" { username = "toby" password = "this_password_is_safe_innit?" } - follow_redirects = true - enable_http2 = true } discovery.relabel "logs_name_jobName" { @@ -101,8 +97,6 @@ discovery.consul "logs_name2_jobName" { username = "toby" password = "this_password_is_safe_innit?" } - follow_redirects = true - enable_http2 = true } discovery.relabel "logs_name2_jobName" { diff --git a/docs/sources/flow/reference/compatibility/_index.md b/docs/sources/flow/reference/compatibility/_index.md index 9e225aa74b71..96539228f434 100644 --- a/docs/sources/flow/reference/compatibility/_index.md +++ b/docs/sources/flow/reference/compatibility/_index.md @@ -68,6 +68,7 @@ The following components, grouped by namespace, _export_ Targets. - [discovery.nerve]({{< relref "../components/discovery.nerve.md" >}}) - [discovery.nomad]({{< relref "../components/discovery.nomad.md" >}}) - [discovery.openstack]({{< relref "../components/discovery.openstack.md" >}}) +- [discovery.ovhcloud]({{< relref "../components/discovery.ovhcloud.md" >}}) - [discovery.puppetdb]({{< relref "../components/discovery.puppetdb.md" >}}) - [discovery.relabel]({{< relref "../components/discovery.relabel.md" >}}) - [discovery.scaleway]({{< relref "../components/discovery.scaleway.md" >}}) diff --git a/docs/sources/flow/reference/components/discovery.consul.md b/docs/sources/flow/reference/components/discovery.consul.md index 7737131a6aa8..c63f94b8017c 100644 --- a/docs/sources/flow/reference/components/discovery.consul.md +++ b/docs/sources/flow/reference/components/discovery.consul.md @@ -70,6 +70,7 @@ basic_auth | [basic_auth][] | Configure basic_auth for authenticating to the end authorization | [authorization][] | Configure generic authorization to the endpoint. | no oauth2 | [oauth2][] | Configure OAuth2 for authenticating to the endpoint. | no oauth2 > tls_config | [tls_config][] | Configure TLS settings for connecting to the endpoint. | no +tls_config | [tls_config][] | Configure TLS settings for connecting to the endpoint. | no The `>` symbol indicates deeper levels of nesting. For example, `oauth2 > tls_config` refers to a `tls_config` block defined inside diff --git a/docs/sources/flow/reference/components/discovery.docker.md b/docs/sources/flow/reference/components/discovery.docker.md index a9143373e12b..4d6ce94d557f 100644 --- a/docs/sources/flow/reference/components/discovery.docker.md +++ b/docs/sources/flow/reference/components/discovery.docker.md @@ -60,6 +60,7 @@ basic_auth | [basic_auth][] | Configure basic_auth for authenticating to the end authorization | [authorization][] | Configure generic authorization to the endpoint. | no oauth2 | [oauth2][] | Configure OAuth2 for authenticating to the endpoint. | no oauth2 > tls_config | [tls_config][] | Configure TLS settings for connecting to the endpoint. | no +tls_config | [tls_config][] | Configure TLS settings for connecting to the endpoint. | no The `>` symbol indicates deeper levels of nesting. For example, `oauth2 > tls_config` refers to a `tls_config` block defined inside diff --git a/docs/sources/flow/reference/components/discovery.dockerswarm.md b/docs/sources/flow/reference/components/discovery.dockerswarm.md index f6db10bd440c..58c065fb06eb 100644 --- a/docs/sources/flow/reference/components/discovery.dockerswarm.md +++ b/docs/sources/flow/reference/components/discovery.dockerswarm.md @@ -48,6 +48,7 @@ The following blocks are supported inside the definition of | authorization | [authorization][] | Configure generic authorization to the endpoint. | no | | oauth2 | [oauth2][] | Configure OAuth2 for authenticating to the endpoint. | no | | oauth2 > tls_config | [tls_config][] | Configure TLS settings for connecting to the endpoint. | no | +| tls_config | [tls_config][] | Configure TLS settings for connecting to the endpoint. | no | The `>` symbol indicates deeper levels of nesting. For example, `oauth2 > tls_config` refers to a `tls_config` block defined inside diff --git a/docs/sources/flow/reference/components/discovery.ec2.md b/docs/sources/flow/reference/components/discovery.ec2.md index e2964d2df0a3..7f01ae48c6e0 100644 --- a/docs/sources/flow/reference/components/discovery.ec2.md +++ b/docs/sources/flow/reference/components/discovery.ec2.md @@ -39,6 +39,15 @@ Name | Type | Description | Default | Required `proxy_url` | `string` | HTTP proxy to proxy requests through. | | no `follow_redirects` | `bool` | Whether redirects returned by the server should be followed. | `true` | no `enable_http2` | `bool` | Whether HTTP2 is supported for requests. | `true` | no +`bearer_token` | `secret` | Bearer token to authenticate with. | | no +`bearer_token_file` | `string` | File containing a bearer token to authenticate with. | | no + + At most one of the following can be provided: + - [`bearer_token` argument](#arguments). + - [`bearer_token_file` argument](#arguments). + - [`basic_auth` block][basic_auth]. + - [`authorization` block][authorization]. + - [`oauth2` block][oauth2]. ## Blocks @@ -47,9 +56,21 @@ The following blocks are supported inside the definition of Hierarchy | Block | Description | Required --------- | ----- | ----------- | -------- +basic_auth | [basic_auth][] | Configure basic_auth for authenticating to the endpoint. | no +authorization | [authorization][] | Configure generic authorization to the endpoint. | no filter | [filter][] | Filters discoverable resources. | no +oauth2 | [oauth2][] | Configure OAuth2 for authenticating to the endpoint. | no +oauth2 > tls_config | [tls_config][] | Configure TLS settings for connecting to the endpoint. | no +tls_config | [tls_config][] | Configure TLS settings for connecting to the endpoint. | no [filter]: #filter-block +[authorization]: #authorization-block +[oauth2]: #oauth2-block +[tls_config]: #tls_config-block + +### authorization block + +{{< docs/shared lookup="flow/reference/components/authorization-block.md" source="agent" version="" >}} ### filter block @@ -65,6 +86,14 @@ Refer to the [Filter API AWS EC2 documentation][filter api] for the list of supp [filter api]: https://docs.aws.amazon.com/AWSEC2/latest/APIReference/API_Filter.html +### oauth2 block + +{{< docs/shared lookup="flow/reference/components/oauth2-block.md" source="agent" version="" >}} + +### tls_config block + +{{< docs/shared lookup="flow/reference/components/tls-config-block.md" source="agent" version="" >}} + ## Exported fields The following fields are exported and can be referenced by other components: diff --git a/docs/sources/flow/reference/components/discovery.eureka.md b/docs/sources/flow/reference/components/discovery.eureka.md index 952e90af1ce4..70ab3f8f666d 100644 --- a/docs/sources/flow/reference/components/discovery.eureka.md +++ b/docs/sources/flow/reference/components/discovery.eureka.md @@ -32,8 +32,20 @@ Name | Type | Description `server` | `string` | Eureka server URL. | | yes `refresh_interval` | `duration` | Interval at which to refresh the list of targets. | `30s` | no `enable_http2` | `bool` | Whether HTTP2 is supported for requests. | `true` | no +`bearer_token` | `secret` | Bearer token to authenticate with. | | no +`bearer_token_file` | `string` | File containing a bearer token to authenticate with. | | no +`proxy_url` | `string` | HTTP proxy to proxy requests through. | | no `follow_redirects` | `bool` | Whether redirects returned by the server should be followed. | `true` | no + At most one of the following can be provided: + - [`bearer_token` argument](#arguments). + - [`bearer_token_file` argument](#arguments). + - [`basic_auth` block][basic_auth]. + - [`authorization` block][authorization]. + - [`oauth2` block][oauth2]. + +[arguments]: #arguments + ## Blocks The following blocks are supported inside the definition of `discovery.eureka`: @@ -44,6 +56,7 @@ basic_auth | [basic_auth][] | Configure basic_auth for authenticating to the end authorization | [authorization][] | Configure generic authorization to the endpoint. | no oauth2 | [oauth2][] | Configure OAuth2 for authenticating to the endpoint. | no oauth2 > tls_config | [tls_config][] | Configure TLS settings for connecting to the endpoint. | no +tls_config | [tls_config][] | Configure TLS settings for connecting to the endpoint. | no The `>` symbol indicates deeper levels of nesting. For example, `oauth2 > tls_config` refers to a `tls_config` block defined inside diff --git a/docs/sources/flow/reference/components/discovery.hetzner.md b/docs/sources/flow/reference/components/discovery.hetzner.md index ce92bda3cb2d..c6922e685f66 100644 --- a/docs/sources/flow/reference/components/discovery.hetzner.md +++ b/docs/sources/flow/reference/components/discovery.hetzner.md @@ -62,6 +62,7 @@ basic_auth | [basic_auth][] | Configure basic_auth for authenticating to the end authorization | [authorization][] | Configure generic authorization to the endpoint. | no oauth2 | [oauth2][] | Configure OAuth2 for authenticating to the endpoint. | no oauth2 > tls_config | [tls_config][] | Configure TLS settings for connecting to the endpoint. | no +tls_config | [tls_config][] | Configure TLS settings for connecting to the endpoint. | no The `>` symbol indicates deeper levels of nesting. For example, `oauth2 > tls_config` refers to a `tls_config` block defined inside diff --git a/docs/sources/flow/reference/components/discovery.http.md b/docs/sources/flow/reference/components/discovery.http.md index 17be475edbc9..50ecf42dcc06 100644 --- a/docs/sources/flow/reference/components/discovery.http.md +++ b/docs/sources/flow/reference/components/discovery.http.md @@ -94,6 +94,20 @@ Name | Type | Description --------------- | ------------------- | ------------------------------------------------------------------------------------------ |---------| -------- `url` | string | URL to scrape | | yes `refresh_interval` | `duration` | How often to refresh targets. | `"60s"` | no +`bearer_token` | `secret` | Bearer token to authenticate with. | | no +`bearer_token_file` | `string` | File containing a bearer token to authenticate with. | | no +`proxy_url` | `string` | HTTP proxy to proxy requests through. | | no +`follow_redirects` | `bool` | Whether redirects returned by the server should be followed. | `true` | no +`enable_http2` | `bool` | Whether HTTP2 is supported for requests. | `true` | no + + At most one of the following can be provided: + - [`bearer_token` argument](#arguments). + - [`bearer_token_file` argument](#arguments). + - [`basic_auth` block][basic_auth]. + - [`authorization` block][authorization]. + - [`oauth2` block][oauth2]. + +[arguments]: #arguments ## Blocks @@ -106,6 +120,7 @@ basic_auth | [basic_auth][] | Configure basic_auth for authenticating to the end authorization | [authorization][] | Configure generic authorization to the endpoint. | no oauth2 | [oauth2][] | Configure OAuth2 for authenticating to the endpoint. | no oauth2 > tls_config | [tls_config][] | Configure TLS settings for connecting to the endpoint. | no +tls_config | [tls_config][] | Configure TLS settings for connecting to the endpoint. | no The `>` symbol indicates deeper levels of nesting. For example, `oauth2 > tls_config` refers to a `tls_config` block defined inside diff --git a/docs/sources/flow/reference/components/discovery.ionos.md b/docs/sources/flow/reference/components/discovery.ionos.md index e06658b4b5d5..1c619a1641ac 100644 --- a/docs/sources/flow/reference/components/discovery.ionos.md +++ b/docs/sources/flow/reference/components/discovery.ionos.md @@ -31,11 +31,22 @@ The following arguments are supported: | ------------------ | ---------- | ------------------------------------------------------------ | ------- | -------- | | `datacenter_id` | `string` | The unique ID of the data center. | | yes | | `refresh_interval` | `duration` | The time after which the servers are refreshed. | `60s` | no | -| `port` | `int` | The port to scrap metrics from. | 80 | no | +| `port` | `int` | The port to scrape metrics from. | 80 | no | +| `bearer_token` | `secret` | Bearer token to authenticate with. | | no | +| `bearer_token_file`| `string` | File containing a bearer token to authenticate with. | | no | | `proxy_url` | `string` | HTTP proxy to proxy requests through. | | no | | `enable_http2` | `bool` | Whether HTTP2 is supported for requests. | `true` | no | | `follow_redirects` | `bool` | Whether redirects returned by the server should be followed. | `true` | no | + At most one of the following can be provided: + - [`bearer_token` argument](#arguments). + - [`bearer_token_file` argument](#arguments). + - [`basic_auth` block][basic_auth]. + - [`authorization` block][authorization]. + - [`oauth2` block][oauth2]. + +[arguments]: #arguments + ## Blocks The following blocks are supported inside the definition of @@ -47,6 +58,7 @@ The following blocks are supported inside the definition of | authorization | [authorization][] | Configure generic authorization to the endpoint. | no | | oauth2 | [oauth2][] | Configure OAuth2 for authenticating to the endpoint. | no | | oauth2 > tls_config | [tls_config][] | Configure TLS settings for connecting to the endpoint. | no | +| tls_config | [tls_config][] | Configure TLS settings for connecting to the endpoint. | no | The `>` symbol indicates deeper levels of nesting. For example, `oauth2 > tls_config` refers to a `tls_config` block defined inside diff --git a/docs/sources/flow/reference/components/discovery.kubernetes.md b/docs/sources/flow/reference/components/discovery.kubernetes.md index 49ecbd09ea12..1d4b2f9210c5 100644 --- a/docs/sources/flow/reference/components/discovery.kubernetes.md +++ b/docs/sources/flow/reference/components/discovery.kubernetes.md @@ -259,6 +259,7 @@ basic_auth | [basic_auth][] | Configure basic_auth for authenticating to the end authorization | [authorization][] | Configure generic authorization to the endpoint. | no oauth2 | [oauth2][] | Configure OAuth2 for authenticating to the endpoint. | no oauth2 > tls_config | [tls_config][] | Configure TLS settings for connecting to the endpoint. | no +tls_config | [tls_config][] | Configure TLS settings for connecting to the endpoint. | no The `>` symbol indicates deeper levels of nesting. For example, `oauth2 > tls_config` refers to a `tls_config` block defined inside diff --git a/docs/sources/flow/reference/components/discovery.kuma.md b/docs/sources/flow/reference/components/discovery.kuma.md index bef9a8ccee12..c498753f58ab 100644 --- a/docs/sources/flow/reference/components/discovery.kuma.md +++ b/docs/sources/flow/reference/components/discovery.kuma.md @@ -54,6 +54,7 @@ basic_auth | [basic_auth][] | Configure basic_auth for authenticating to the end authorization | [authorization][] | Configure generic authorization to the endpoint. | no oauth2 | [oauth2][] | Configure OAuth2 for authenticating to the endpoint. | no oauth2 > tls_config | [tls_config][] | Configure TLS settings for connecting to the endpoint. | no +tls_config | [tls_config][] | Configure TLS settings for connecting to the endpoint. | no The `>` symbol indicates deeper levels of nesting. For example, `oauth2 > tls_config` refers to a `tls_config` block defined inside diff --git a/docs/sources/flow/reference/components/discovery.linode.md b/docs/sources/flow/reference/components/discovery.linode.md index f9f4b1e4e19a..77d01dbdf4e2 100644 --- a/docs/sources/flow/reference/components/discovery.linode.md +++ b/docs/sources/flow/reference/components/discovery.linode.md @@ -54,6 +54,7 @@ Hierarchy | Block | Description | Required authorization | [authorization][] | Configure generic authorization to the endpoint. | no oauth2 | [oauth2][] | Configure OAuth2 for authenticating to the endpoint. | no oauth2 > tls_config | [tls_config][] | Configure TLS settings for connecting to the endpoint. | no +tls_config | [tls_config][] | Configure TLS settings for connecting to the endpoint. | no The `>` symbol indicates deeper levels of nesting. For example, `oauth2 > tls_config` refers to a `tls_config` block defined inside diff --git a/docs/sources/flow/reference/components/discovery.marathon.md b/docs/sources/flow/reference/components/discovery.marathon.md index 4327dc502fb1..b19ddb321c2c 100644 --- a/docs/sources/flow/reference/components/discovery.marathon.md +++ b/docs/sources/flow/reference/components/discovery.marathon.md @@ -56,6 +56,7 @@ The following blocks are supported inside the definition of | authorization | [authorization][] | Configure generic authorization to the endpoint. | no | | oauth2 | [oauth2][] | Configure OAuth2 for authenticating to the endpoint. | no | | oauth2 > tls_config | [tls_config][] | Configure TLS settings for connecting to the endpoint. | no | +| tls_config | [tls_config][] | Configure TLS settings for connecting to the endpoint. | no | The `>` symbol indicates deeper levels of nesting. For example, `oauth2 > tls_config` refers to a `tls_config` block defined inside diff --git a/docs/sources/flow/reference/components/discovery.nomad.md b/docs/sources/flow/reference/components/discovery.nomad.md index c8bcdae99699..aebd128bb320 100644 --- a/docs/sources/flow/reference/components/discovery.nomad.md +++ b/docs/sources/flow/reference/components/discovery.nomad.md @@ -58,6 +58,7 @@ basic_auth | [basic_auth][] | Configure basic_auth for authenticating to the end authorization | [authorization][] | Configure generic authorization to the endpoint. | no oauth2 | [oauth2][] | Configure OAuth2 for authenticating to the endpoint. | no oauth2 > tls_config | [tls_config][] | Configure TLS settings for connecting to the endpoint. | no +tls_config | [tls_config][] | Configure TLS settings for connecting to the endpoint. | no The `>` symbol indicates deeper levels of nesting. For example, `oauth2 > tls_config` refers to a `tls_config` block defined inside diff --git a/docs/sources/flow/reference/components/discovery.ovhcloud.md b/docs/sources/flow/reference/components/discovery.ovhcloud.md new file mode 100644 index 000000000000..453fcb3c1cfc --- /dev/null +++ b/docs/sources/flow/reference/components/discovery.ovhcloud.md @@ -0,0 +1,165 @@ +--- +aliases: +- /docs/grafana-cloud/agent/flow/reference/components/discovery.ovhcloud/ +- /docs/grafana-cloud/monitor-infrastructure/agent/flow/reference/components/discovery.ovhcloud/ +- /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/reference/components/discovery.ovhcloud/ +- /docs/grafana-cloud/send-data/agent/flow/reference/components/discovery.ovhcloud/ +canonical: https://grafana.com/docs/agent/latest/flow/reference/components/discovery.ovhcloud/ +description: Learn about discovery.ovhcloud +title: discovery.ovhcloud +--- + +# discovery.ovhcloud + +`discovery.ovhcloud` discovers scrape targets from OVHcloud's [dedicated servers][] and [VPS][] using their [API][]. +{{< param "PRODUCT_ROOT_NAME" >}} will periodically check the REST endpoint and create a target for every discovered server. +The public IPv4 address will be used by default - if there's none, the IPv6 address will be used. +This may be changed via relabeling with `discovery.relabel`. +For OVHcloud's [public cloud][] instances you can use `discovery.openstack`. + +[API]: https://api.ovh.com/ +[public cloud]: https://www.ovhcloud.com/en/public-cloud/ +[VPS]: https://www.ovhcloud.com/en/vps/ +[Dedicated servers]: https://www.ovhcloud.com/en/bare-metal/ + +## Usage + +```river +discovery.ovhcloud "LABEL" { + application_key = APPLICATION_KEY + application_secret = APPLICATION_SECRET + consumer_key = CONSUMER_KEY + service = SERVICE +} +``` + +## Arguments + +The following arguments are supported: + +Name | Type | Description | Default | Required +------------------ | -------------- | -------------------------------------------------------------- | ------------- | -------- +application_key | `string` | [API][] application key. | | yes +application_secret | `secret` | [API][] application secret. | | yes +consumer_key | `secret` | [API][] consumer key. | | yes +endpoint | `string` | [API][] endpoint. | "ovh-eu" | no +refresh_interval | `duration` | Refresh interval to re-read the resources list. | "60s" | no +service | `string` | Service of the targets to retrieve. | | yes + +`endpoint` must be one of the [supported API endpoints][supported-apis]. + +`service` must be either `vps` or `dedicated_server`. + +[supported-apis]: https://github.com/ovh/go-ovh#supported-apis + +## Exported fields + +The following fields are exported and can be referenced by other components: + +Name | Type | Description +--------- | ------------------- | ----------- +`targets` | `list(map(string))` | The set of targets discovered from the OVHcloud API. + +Multiple meta labels are available on `targets` and can be used by the `discovery.relabel` component. + +[VPS][] meta labels: +* `__meta_ovhcloud_vps_cluster`: the cluster of the server. +* `__meta_ovhcloud_vps_datacenter`: the datacenter of the server. +* `__meta_ovhcloud_vps_disk`: the disk of the server. +* `__meta_ovhcloud_vps_display_name`: the display name of the server. +* `__meta_ovhcloud_vps_ipv4`: the IPv4 of the server. +* `__meta_ovhcloud_vps_ipv6`: the IPv6 of the server. +* `__meta_ovhcloud_vps_keymap`: the KVM keyboard layout of the server. +* `__meta_ovhcloud_vps_maximum_additional_ip`: the maximum additional IPs of the server. +* `__meta_ovhcloud_vps_memory_limit`: the memory limit of the server. +* `__meta_ovhcloud_vps_memory`: the memory of the server. +* `__meta_ovhcloud_vps_monitoring_ip_blocks`: the monitoring IP blocks of the server. +* `__meta_ovhcloud_vps_name`: the name of the server. +* `__meta_ovhcloud_vps_netboot_mode`: the netboot mode of the server. +* `__meta_ovhcloud_vps_offer_type`: the offer type of the server. +* `__meta_ovhcloud_vps_offer`: the offer of the server. +* `__meta_ovhcloud_vps_state`: the state of the server. +* `__meta_ovhcloud_vps_vcore`: the number of virtual cores of the server. +* `__meta_ovhcloud_vps_version`: the version of the server. +* `__meta_ovhcloud_vps_zone`: the zone of the server. + +[Dedicated servers][] meta labels: +* `__meta_ovhcloud_dedicated_server_commercial_range`: the commercial range of the server. +* `__meta_ovhcloud_dedicated_server_datacenter`: the datacenter of the server. +* `__meta_ovhcloud_dedicated_server_ipv4`: the IPv4 of the server. +* `__meta_ovhcloud_dedicated_server_ipv6`: the IPv6 of the server. +* `__meta_ovhcloud_dedicated_server_link_speed`: the link speed of the server. +* `__meta_ovhcloud_dedicated_server_name`: the name of the server. +* `__meta_ovhcloud_dedicated_server_os`: the operating system of the server. +* `__meta_ovhcloud_dedicated_server_rack`: the rack of the server. +* `__meta_ovhcloud_dedicated_server_reverse`: the reverse DNS name of the server. +* `__meta_ovhcloud_dedicated_server_server_id`: the ID of the server. +* `__meta_ovhcloud_dedicated_server_state`: the state of the server. +* `__meta_ovhcloud_dedicated_server_support_level`: the support level of the server. + +## Component health + +`discovery.ovhcloud` is only reported as unhealthy when given an invalid +configuration. In those cases, exported fields retain their last healthy +values. + +## Debug information + +`discovery.ovhcloud` does not expose any component-specific debug information. + +## Debug metrics + +`discovery.ovhcloud` does not expose any component-specific debug metrics. + +## Example + +```river +discovery.ovhcloud "example" { + application_key = APPLICATION_KEY + application_secret = APPLICATION_SECRET + consumer_key = CONSUMER_KEY + service = SERVICE +} + +prometheus.scrape "demo" { + targets = discovery.ovhcloud.example.targets + forward_to = [prometheus.remote_write.demo.receiver] +} + +prometheus.remote_write "demo" { + endpoint { + url = PROMETHEUS_REMOTE_WRITE_URL + basic_auth { + username = USERNAME + password = PASSWORD + } + } +} +``` + +Replace the following: + - `APPLICATION_KEY`: The OVHcloud [API][] application key. + - `APPLICATION_SECRET`: The OVHcloud [API][] application secret. + - `CONSUMER_KEY`: The OVHcloud [API][] consumer key. + - `SERVICE`: The OVHcloud service of the targets to retrieve. + - `PROMETHEUS_REMOTE_WRITE_URL`: The URL of the Prometheus remote_write-compatible server to send metrics to. + - `USERNAME`: The username to use for authentication to the remote_write API. + - `PASSWORD`: The password to use for authentication to the remote_write API. + + + + +## Compatible components + +`discovery.ovhcloud` has exports that can be consumed by the following components: + +- Components that consume [Targets]({{< relref "../compatibility/#targets-consumers" >}}) + +{{% admonition type="note" %}} + +Connecting some components may not be sensible or components may require further configuration to make the +connection work correctly. Refer to the linked documentation for more details. + +{{% /admonition %}} + + diff --git a/docs/sources/flow/reference/components/discovery.puppetdb.md b/docs/sources/flow/reference/components/discovery.puppetdb.md index 34e6f14db7c3..a83d8454723c 100644 --- a/docs/sources/flow/reference/components/discovery.puppetdb.md +++ b/docs/sources/flow/reference/components/discovery.puppetdb.md @@ -64,6 +64,7 @@ basic_auth | [basic_auth][] | Configure basic_auth for authenticating to the end authorization | [authorization][] | Configure generic authorization to the endpoint. | no oauth2 | [oauth2][] | Configure OAuth2 for authenticating to the endpoint. | no oauth2 > tls_config | [tls_config][] | Configure TLS settings for connecting to the endpoint. | no +tls_config | [tls_config][] | Configure TLS settings for connecting to the endpoint. | no The `>` symbol indicates deeper levels of nesting. For example, `oauth2 > tls_config` refers to a `tls_config` block defined inside diff --git a/docs/sources/flow/reference/components/prometheus.exporter.cloudwatch.md b/docs/sources/flow/reference/components/prometheus.exporter.cloudwatch.md index 10313796d1cb..2c1682a5fccc 100644 --- a/docs/sources/flow/reference/components/prometheus.exporter.cloudwatch.md +++ b/docs/sources/flow/reference/components/prometheus.exporter.cloudwatch.md @@ -429,6 +429,7 @@ discovery job, the `type` field of each `discovery_job` must match either the de - Namespace: `AWS/PrivateLinkEndpoints` or Alias: `vpc-endpoint` - Namespace: `AWS/PrivateLinkServices` or Alias: `vpc-endpoint-service` - Namespace: `AWS/Prometheus` or Alias: `amp` +- Namespace: `AWS/QLDB` or Alias: `qldb` - Namespace: `AWS/RDS` or Alias: `rds` - Namespace: `AWS/Redshift` or Alias: `redshift` - Namespace: `AWS/Route53Resolver` or Alias: `route53-resolver` @@ -442,6 +443,7 @@ discovery job, the `type` field of each `discovery_job` must match either the de - Namespace: `AWS/TransitGateway` or Alias: `tgw` - Namespace: `AWS/TrustedAdvisor` or Alias: `trustedadvisor` - Namespace: `AWS/VPN` or Alias: `vpn` +- Namespace: `AWS/ClientVPN` or Alias: `clientvpn` - Namespace: `AWS/WAFV2` or Alias: `wafv2` - Namespace: `AWS/WorkSpaces` or Alias: `workspaces` - Namespace: `AWS/AOSS` or Alias: `aoss` diff --git a/docs/sources/flow/reference/components/prometheus.scrape.md b/docs/sources/flow/reference/components/prometheus.scrape.md index 08b009c88711..8adf775687f1 100644 --- a/docs/sources/flow/reference/components/prometheus.scrape.md +++ b/docs/sources/flow/reference/components/prometheus.scrape.md @@ -44,30 +44,30 @@ The following arguments are supported: Name | Type | Description | Default | Required ---- | ---- | ----------- | ------- | -------- -`targets` | `list(map(string))` | List of targets to scrape. | | yes -`forward_to` | `list(MetricsReceiver)` | List of receivers to send scraped metrics to. | | yes -`job_name` | `string` | The value to use for the job label if not already set. | component name | no -`extra_metrics` | `bool` | Whether extra metrics should be generated for scrape targets. | `false` | no +`targets` | `list(map(string))` | List of targets to scrape. | | yes +`forward_to` | `list(MetricsReceiver)` | List of receivers to send scraped metrics to. | | yes +`job_name` | `string` | The value to use for the job label if not already set. | component name | no +`extra_metrics` | `bool` | Whether extra metrics should be generated for scrape targets. | `false` | no `enable_protobuf_negotiation` | `bool` | Whether to enable protobuf negotiation with the client. | `false` | no -`honor_labels` | `bool` | Indicator whether the scraped metrics should remain unmodified. | `false` | no -`honor_timestamps` | `bool` | Indicator whether the scraped timestamps should be respected. | `true` | no -`params` | `map(list(string))` | A set of query parameters with which the target is scraped. | | no -`scrape_classic_histograms` | `bool` | Whether to scrape a classic histogram that is also exposed as a native histogram. | `false` | no -`scrape_interval` | `duration` | How frequently to scrape the targets of this scrape configuration. | `"60s"` | no -`scrape_timeout` | `duration` | The timeout for scraping targets of this configuration. | `"10s"` | no -`metrics_path` | `string` | The HTTP resource path on which to fetch metrics from targets. | `/metrics` | no -`scheme` | `string` | The URL scheme with which to fetch metrics from targets. | | no -`body_size_limit` | `int` | An uncompressed response body larger than this many bytes causes the scrape to fail. 0 means no limit. | | no -`sample_limit` | `uint` | More than this many samples post metric-relabeling causes the scrape to fail | | no -`target_limit` | `uint` | More than this many targets after the target relabeling causes the scrapes to fail. | | no -`label_limit` | `uint` | More than this many labels post metric-relabeling causes the scrape to fail. | | no -`label_name_length_limit` | `uint` | More than this label name length post metric-relabeling causes the scrape to fail. | | no -`label_value_length_limit` | `uint` | More than this label value length post metric-relabeling causes the scrape to fail. | | no -`bearer_token` | `secret` | Bearer token to authenticate with. | | no -`bearer_token_file` | `string` | File containing a bearer token to authenticate with. | | no -`proxy_url` | `string` | HTTP proxy to proxy requests through. | | no -`follow_redirects` | `bool` | Whether redirects returned by the server should be followed. | `true` | no -`enable_http2` | `bool` | Whether HTTP2 is supported for requests. | `true` | no +`honor_labels` | `bool` | Indicator whether the scraped metrics should remain unmodified. | `false` | no +`honor_timestamps` | `bool` | Indicator whether the scraped timestamps should be respected. | `true` | no +`params` | `map(list(string))` | A set of query parameters with which the target is scraped. | | no +`scrape_classic_histograms` | `bool` | Whether to scrape a classic histogram that is also exposed as a native histogram. | `false` | no +`scrape_interval` | `duration` | How frequently to scrape the targets of this scrape configuration. | `"60s"` | no +`scrape_timeout` | `duration` | The timeout for scraping targets of this configuration. | `"10s"` | no +`metrics_path` | `string` | The HTTP resource path on which to fetch metrics from targets. | `/metrics` | no +`scheme` | `string` | The URL scheme with which to fetch metrics from targets. | | no +`body_size_limit` | `int` | An uncompressed response body larger than this many bytes causes the scrape to fail. 0 means no limit. | | no +`sample_limit` | `uint` | More than this many samples post metric-relabeling causes the scrape to fail | | no +`target_limit` | `uint` | More than this many targets after the target relabeling causes the scrapes to fail. | | no +`label_limit` | `uint` | More than this many labels post metric-relabeling causes the scrape to fail. | | no +`label_name_length_limit` | `uint` | More than this label name length post metric-relabeling causes the scrape to fail. | | no +`label_value_length_limit` | `uint` | More than this label value length post metric-relabeling causes the scrape to fail. | | no +`bearer_token` | `secret` | Bearer token to authenticate with. | | no +`bearer_token_file` | `string` | File containing a bearer token to authenticate with. | | no +`proxy_url` | `string` | HTTP proxy to proxy requests through. | | no +`follow_redirects` | `bool` | Whether redirects returned by the server should be followed. | `true` | no +`enable_http2` | `bool` | Whether HTTP2 is supported for requests. | `true` | no At most one of the following can be provided: - [`bearer_token` argument](#arguments). diff --git a/docs/sources/static/configuration/integrations/cloudwatch-exporter-config.md b/docs/sources/static/configuration/integrations/cloudwatch-exporter-config.md index 8015bde84bc9..6495625b76c8 100644 --- a/docs/sources/static/configuration/integrations/cloudwatch-exporter-config.md +++ b/docs/sources/static/configuration/integrations/cloudwatch-exporter-config.md @@ -440,6 +440,7 @@ discovery job, the `type` field of each `discovery_job` must match either the de - Namespace: `AWS/PrivateLinkEndpoints` or Alias: `vpc-endpoint` - Namespace: `AWS/PrivateLinkServices` or Alias: `vpc-endpoint-service` - Namespace: `AWS/Prometheus` or Alias: `amp` +- Namespace: `AWS/QLDB` or Alias: `qldb` - Namespace: `AWS/RDS` or Alias: `rds` - Namespace: `AWS/Redshift` or Alias: `redshift` - Namespace: `AWS/Route53Resolver` or Alias: `route53-resolver` @@ -453,6 +454,7 @@ discovery job, the `type` field of each `discovery_job` must match either the de - Namespace: `AWS/TransitGateway` or Alias: `tgw` - Namespace: `AWS/TrustedAdvisor` or Alias: `trustedadvisor` - Namespace: `AWS/VPN` or Alias: `vpn` +- Namespace: `AWS/ClientVPN` or Alias: `clientvpn` - Namespace: `AWS/WAFV2` or Alias: `wafv2` - Namespace: `AWS/WorkSpaces` or Alias: `workspaces` - Namespace: `AWS/AOSS` or Alias: `aoss` diff --git a/go.mod b/go.mod index 4614e9124d44..f8d9059376ab 100644 --- a/go.mod +++ b/go.mod @@ -13,7 +13,7 @@ require ( github.com/PuerkitoBio/rehttp v1.1.0 github.com/alecthomas/kingpin/v2 v2.4.0 github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 - github.com/aws/aws-sdk-go v1.45.24 + github.com/aws/aws-sdk-go v1.45.25 github.com/aws/aws-sdk-go-v2 v1.21.1 github.com/aws/aws-sdk-go-v2/config v1.18.44 github.com/aws/aws-sdk-go-v2/service/s3 v1.34.1 @@ -59,7 +59,7 @@ require ( github.com/grafana/loki v1.6.2-0.20231004111112-07cbef92268a github.com/grafana/pyroscope-go/godeltaprof v0.1.3 github.com/grafana/pyroscope/api v0.2.0 - github.com/grafana/pyroscope/ebpf v0.4.0 + github.com/grafana/pyroscope/ebpf v0.4.1 github.com/grafana/regexp v0.0.0-20221123153739-15dc172cd2db github.com/grafana/river v0.3.0 github.com/grafana/snowflake-prometheus-exporter v0.0.0-20221213150626-862cad8e9538 @@ -89,12 +89,12 @@ require ( github.com/klauspost/compress v1.17.3 github.com/lib/pq v1.10.7 github.com/mackerelio/go-osstat v0.2.3 - github.com/miekg/dns v1.1.55 + github.com/miekg/dns v1.1.56 github.com/mitchellh/mapstructure v1.5.1-0.20220423185008-bf980b35cac4 github.com/mitchellh/reflectwalk v1.0.2 github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f github.com/ncabatoff/process-exporter v0.7.10 - github.com/nerdswords/yet-another-cloudwatch-exporter v0.54.0 + github.com/nerdswords/yet-another-cloudwatch-exporter v0.55.0 github.com/ohler55/ojg v1.20.0 // indirect github.com/oklog/run v1.1.0 github.com/olekukonko/tablewriter v0.0.5 @@ -150,7 +150,7 @@ require ( github.com/prometheus/mysqld_exporter v0.14.0 github.com/prometheus/node_exporter v1.6.0 github.com/prometheus/procfs v0.12.0 - github.com/prometheus/prometheus v1.99.0 + github.com/prometheus/prometheus v0.48.1 github.com/prometheus/snmp_exporter v0.24.1 github.com/prometheus/statsd_exporter v0.22.8 github.com/richardartoul/molecule v1.0.1-0.20221107223329-32cfee06a052 @@ -219,7 +219,7 @@ require ( golang.org/x/sys v0.14.1-0.20231108175955-e4099bfacb8c golang.org/x/text v0.14.0 golang.org/x/time v0.3.0 - google.golang.org/api v0.146.0 + google.golang.org/api v0.147.0 google.golang.org/grpc v1.59.0 google.golang.org/protobuf v1.31.0 gopkg.in/yaml.v2 v2.4.0 @@ -326,7 +326,7 @@ require ( github.com/dennwc/varint v1.0.0 // indirect github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect - github.com/digitalocean/godo v1.99.0 // indirect + github.com/digitalocean/godo v1.104.1 // indirect github.com/dimchansky/utfbom v1.1.1 github.com/docker/cli v23.0.3+incompatible // indirect github.com/docker/distribution v2.8.2+incompatible // indirect @@ -391,11 +391,11 @@ require ( github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect github.com/googleapis/enterprise-certificate-proxy v0.3.1 // indirect github.com/googleapis/gax-go/v2 v2.12.0 // indirect - github.com/gophercloud/gophercloud v1.5.0 // indirect + github.com/gophercloud/gophercloud v1.7.0 // indirect github.com/gorilla/websocket v1.5.0 // indirect github.com/gosnmp/gosnmp v1.36.0 // indirect github.com/grafana/gomemcache v0.0.0-20230316202710-a081dae0aba9 // indirect - github.com/grafana/loki/pkg/push v0.0.0-20230904153656-e4cc2a4f5ec8 // k166 branch + github.com/grafana/loki/pkg/push v0.0.0-20231212100434-384e5c2dc872 // k180 branch github.com/grobie/gomemcache v0.0.0-20230213081705-239240bbc445 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0 // indirect github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c // indirect @@ -415,7 +415,7 @@ require ( github.com/hashicorp/hcl v1.0.0 // indirect github.com/hashicorp/mdns v1.0.4 // indirect github.com/hashicorp/memberlist v0.5.0 // indirect - github.com/hashicorp/nomad/api v0.0.0-20230718173136-3a687930bd3e // indirect + github.com/hashicorp/nomad/api v0.0.0-20230721134942-515895c7690c // indirect github.com/hashicorp/serf v0.10.1 // indirect github.com/hashicorp/vic v1.5.1-0.20190403131502-bbfe86ec9443 // indirect github.com/hodgesds/perf-utils v0.7.0 // indirect @@ -426,7 +426,7 @@ require ( github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/infinityworks/go-common v0.0.0-20170820165359-7f20a140fd37 // indirect github.com/influxdata/telegraf v1.16.3 // indirect - github.com/ionos-cloud/sdk-go/v6 v6.1.8 // indirect + github.com/ionos-cloud/sdk-go/v6 v6.1.9 // indirect github.com/jackc/chunkreader/v2 v2.0.1 // indirect github.com/jackc/pgconn v1.13.0 // indirect github.com/jackc/pgio v1.0.0 // indirect @@ -456,7 +456,7 @@ require ( github.com/krallistic/kazoo-go v0.0.0-20170526135507-a15279744f4e // indirect github.com/kylelemons/godebug v1.1.0 // indirect github.com/leodido/ragel-machinery v0.0.0-20181214104525-299bdde78165 // indirect - github.com/linode/linodego v1.19.0 // indirect + github.com/linode/linodego v1.23.0 // indirect github.com/lufia/iostat v1.2.1 // indirect github.com/lufia/plan9stats v0.0.0-20220913051719-115f729f3c8c // indirect github.com/magiconair/properties v1.8.7 // indirect @@ -506,7 +506,7 @@ require ( github.com/opencontainers/selinux v1.11.0 // indirect github.com/openzipkin/zipkin-go v0.4.2 // indirect github.com/oschwald/maxminddb-golang v1.11.0 - github.com/ovh/go-ovh v1.4.1 // indirect + github.com/ovh/go-ovh v1.4.3 // indirect github.com/packethost/packngo v0.1.1-0.20180711074735-b9cb5096f54c // indirect github.com/patrickmn/go-cache v2.1.0+incompatible // indirect github.com/pelletier/go-toml/v2 v2.0.8 // indirect @@ -525,7 +525,7 @@ require ( github.com/safchain/ethtool v0.3.0 // indirect github.com/samber/lo v1.38.1 // indirect github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da // indirect - github.com/scaleway/scaleway-sdk-go v1.0.0-beta.20 + github.com/scaleway/scaleway-sdk-go v1.0.0-beta.21 github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 // indirect github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646 // indirect github.com/sergi/go-diff v1.2.0 // indirect @@ -590,7 +590,7 @@ require ( gonum.org/v1/gonum v0.14.0 // indirect google.golang.org/appengine v1.6.8 // indirect google.golang.org/genproto v0.0.0-20231012201019-e917dd12ba7a // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20231002182017-d307bd883b97 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20231012201019-e917dd12ba7a // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20231016165738-49dd2c1f3d0b // indirect gopkg.in/alecthomas/kingpin.v2 v2.2.6 // indirect gopkg.in/fsnotify/fsnotify.v1 v1.4.7 // indirect @@ -613,21 +613,22 @@ require ( github.com/open-telemetry/opentelemetry-collector-contrib/processor/filterprocessor v0.87.0 github.com/open-telemetry/opentelemetry-collector-contrib/receiver/prometheusreceiver v0.87.0 github.com/open-telemetry/opentelemetry-collector-contrib/receiver/vcenterreceiver v0.87.0 - github.com/prometheus/tsdb v0.10.0 go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.42.0 k8s.io/apimachinery v0.28.3 ) require ( dario.cat/mergo v1.0.0 // indirect + github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v4 v4.2.1 // indirect + github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v2 v2.2.1 // indirect github.com/Shopify/sarama v1.38.1 // indirect github.com/Workiva/go-datastructures v1.1.0 // indirect github.com/channelmeter/iso8601duration v0.0.0-20150204201828-8da3af7a2a61 // indirect github.com/drone/envsubst v1.0.3 // indirect - github.com/go-jose/go-jose/v3 v3.0.0 // indirect + github.com/go-jose/go-jose/v3 v3.0.1 // indirect github.com/golang-jwt/jwt/v5 v5.0.0 // indirect github.com/google/gnostic-models v0.6.8 // indirect - github.com/hetznercloud/hcloud-go/v2 v2.0.0 // indirect + github.com/hetznercloud/hcloud-go/v2 v2.4.0 // indirect github.com/julienschmidt/httprouter v1.3.0 // indirect github.com/knadh/koanf/v2 v2.0.1 // indirect github.com/lightstep/go-expohisto v1.0.0 // indirect @@ -676,14 +677,6 @@ replace ( k8s.io/klog/v2 => github.com/simonpasquier/klog-gokit/v3 v3.3.0 ) -// TODO(tpaschalis): remove replace directive once: -// -// * There is a release of Prometheus which contains -// prometheus/prometheus#12677 and prometheus/prometheus#12729. -// We use the last v1-related tag as the replace statement does not work for v2 -// tags without the v2 suffix to the module root. -replace github.com/prometheus/prometheus => github.com/grafana/prometheus v1.8.2-0.20231016083943-46550094220d // grafana:prometheus:v0.47.2-retry-improvements - replace gopkg.in/yaml.v2 => github.com/rfratto/go-yaml v0.0.0-20211119180816-77389c3526dc // Replace directives from Loki @@ -745,7 +738,3 @@ exclude ( ) replace github.com/github/smimesign => github.com/grafana/smimesign v0.2.1-0.20220408144937-2a5adf3481d3 - -// This is the last version that used slices.Func with a bool return -// If we upgrade to a newer one then since the signature changed loki will complain. -replace golang.org/x/exp => golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 diff --git a/go.sum b/go.sum index fed259a01614..d966bfea9876 100644 --- a/go.sum +++ b/go.sum @@ -64,6 +64,7 @@ contrib.go.opencensus.io/exporter/prometheus v0.4.2 h1:sqfsYl5GIY/L570iT+l93ehxa contrib.go.opencensus.io/exporter/prometheus v0.4.2/go.mod h1:dvEHbiKmgvbr5pjaF9fpw1KeYcjrnC1J8B+JKjsZyRQ= dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 h1:/vQbFIOMbk2FiG/kXiLl8BRyzTWDw7gX/Hz7Dd5eDMs= github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4/go.mod h1:hN7oaIRCjzsZ2dE+yG5k+rsdt3qcwykqK6HVGcKwsw4= github.com/99designs/keyring v1.2.2 h1:pZd3neh/EmUzWONb35LxQfvuY7kiSXAq3HQd97+XBn0= @@ -89,12 +90,18 @@ github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0/go.mod h1:1fXstnBMas5kzG github.com/Azure/azure-sdk-for-go/sdk/internal v1.0.0/go.mod h1:eWRD7oawr1Mu1sLCawqVc0CUiF43ia3qQMxLscsKQ9w= github.com/Azure/azure-sdk-for-go/sdk/internal v1.4.0 h1:TuEMD+E+1aTjjLICGQOW6vLe8UWES7kopac9mUXL56Y= github.com/Azure/azure-sdk-for-go/sdk/internal v1.4.0/go.mod h1:s4kgfzA0covAXNicZHDMN58jExvcng2mC/DepXiF1EI= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v4 v4.2.1 h1:UPeCRD+XY7QlaGQte2EVI2iOcWvUYA2XY8w5T/8v0NQ= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v4 v4.2.1/go.mod h1:oGV6NlB0cvi1ZbYRR2UN44QHxWFyGk+iylgD0qaMXjA= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal v1.1.2 h1:mLY+pNLjCUeKhgnAJWAKhEUQM+RJQo2H1fuGSw1Ky1E= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/internal v1.1.2/go.mod h1:FbdwsQ2EzwvXxOPcMFYO8ogEc9uMMIj3YkmCdXdAFmk= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/managementgroups/armmanagementgroups v1.0.0 h1:pPvTJ1dY0sA35JOeFq6TsY2xj6Z85Yo23Pj4wCCvu4o= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/managementgroups/armmanagementgroups v1.0.0/go.mod h1:mLfWfj8v3jfWKsL9G4eoBoXVcsqcIUTapmdKy7uGOp0= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/monitor/armmonitor v0.10.2 h1:T3P5KJpcgN0m39dhaNM+JjSqF3Z5VqUlKHlth5FgN+8= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/monitor/armmonitor v0.10.2/go.mod h1:yA8WUvh3K/SABQEtFHg2Bx5D+414FyFqpT5Fu58P3ao= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork v1.1.0 h1:QM6sE5k2ZT/vI5BEe0r7mqjsUSnhVBFbOsVkEuaEfiA= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork v1.1.0/go.mod h1:243D9iHbcQXoFUtgHJwL7gl2zx1aDuDMjvBZVGr2uW0= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v2 v2.2.1 h1:bWh0Z2rOEDfB/ywv/l0iHN1JgyazE6kW/aIA89+CEK0= +github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v2 v2.2.1/go.mod h1:Bzf34hhAE9NSxailk8xVeLEZbUjOXcC+GnU1mMKdhLw= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resourcegraph/armresourcegraph v0.8.2 h1:f9lam+D19V0TDn17+aFhrVhWPpfsF5zaGHeqDGJZAVc= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resourcegraph/armresourcegraph v0.8.2/go.mod h1:29c9+gYpdWhyC4TPANZBPlgoWllMDhguL2AIByPYQtk= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources v1.1.1 h1:7CBQ+Ei8SP2c6ydQTGCCrS35bDxgTMfoP2miAwK++OU= @@ -171,6 +178,7 @@ github.com/AzureAD/microsoft-authentication-library-for-go v1.2.0/go.mod h1:wP83 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak= github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/ClickHouse/clickhouse-go v1.5.4 h1:cKjXeYLNWVJIx2J1K6H2CqyRmfwVJVY1OV1coaaFcI0= github.com/ClickHouse/clickhouse-go v1.5.4/go.mod h1:EaI/sW7Azgz9UATzd5ZdZHRUhHgv5+JMS9NSr2smCJI= github.com/DATA-DOG/go-sqlmock v1.4.1/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= @@ -312,8 +320,8 @@ github.com/aws/aws-sdk-go v1.30.27/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZve github.com/aws/aws-sdk-go v1.34.34/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.38.68/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= -github.com/aws/aws-sdk-go v1.45.24 h1:TZx/CizkmCQn8Rtsb11iLYutEQVGK5PK9wAhwouELBo= -github.com/aws/aws-sdk-go v1.45.24/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= +github.com/aws/aws-sdk-go v1.45.25 h1:c4fLlh5sLdK2DCRTY1z0hyuJZU4ygxX8m1FswL6/nF4= +github.com/aws/aws-sdk-go v1.45.25/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/aws/aws-sdk-go-v2 v1.7.0/go.mod h1:tb9wi5s61kTDA5qCkcDbt3KRVV74GGslQkl/DRdX/P4= github.com/aws/aws-sdk-go-v2 v1.9.2/go.mod h1:cK/D0BBs0b/oWPIcX/Z/obahJK1TT7IPVjy53i/mX/4= @@ -348,20 +356,20 @@ github.com/aws/aws-sdk-go-v2/internal/ini v1.3.44 h1:quOJOqlbSfeJTboXLjYXM1M9T52 github.com/aws/aws-sdk-go-v2/internal/ini v1.3.44/go.mod h1:LNy+P1+1LiRcCsVYr/4zG5n8zWFL0xsvZkOybjbftm8= github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.26 h1:wscW+pnn3J1OYnanMnza5ZVYXLX4cKk5rAvUAl4Qu+c= github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.26/go.mod h1:MtYiox5gvyB+OyP0Mr0Sm/yzbEAIPL9eijj/ouHAPw0= -github.com/aws/aws-sdk-go-v2/service/amp v1.16.14 h1:cak6jLkSwmPqcJ7pcVlkABsYfjCxxiyjBM2xBgjPwmY= -github.com/aws/aws-sdk-go-v2/service/amp v1.16.14/go.mod h1:Tq9wKXE+SPKKkwJSRHE/u+aOdUdvU//AuPfi/w6iNdc= -github.com/aws/aws-sdk-go-v2/service/apigateway v1.16.14 h1:mXf/MQX2zcKpWTfI4YgHrD4UYBh6AzyBCRfVdsxExaU= -github.com/aws/aws-sdk-go-v2/service/apigateway v1.16.14/go.mod h1:KJyzRVA5DkFaU4hVgKDoHiSrCobfmYP8UpRXlybTuTU= -github.com/aws/aws-sdk-go-v2/service/apigatewayv2 v1.13.15 h1:lgTqmtilhObvVhxeBhX/KRC5RaB4A0dQqDDdLmfAP+0= -github.com/aws/aws-sdk-go-v2/service/apigatewayv2 v1.13.15/go.mod h1:lg/1D90DDo2//C84mvygysHF4JRo+Vf/W5YbkHoeUk8= +github.com/aws/aws-sdk-go-v2/service/amp v1.17.5 h1:Wg2vTVYrMrfkNqrCGaggQq1UBdzgrAsorAfavLNpU/E= +github.com/aws/aws-sdk-go-v2/service/amp v1.17.5/go.mod h1:JXkUFaC1ISQYHO535+mgMPF0b1OaSdrsM5FhFfBbbQY= +github.com/aws/aws-sdk-go-v2/service/apigateway v1.18.0 h1:rByriM7T0xvKy7eDiNUhFyVgnGupZ7DIifReKDzfk5E= +github.com/aws/aws-sdk-go-v2/service/apigateway v1.18.0/go.mod h1:OJmEdRP/gDTqY71Cc/eJ/anpvvGHNgf62FyNuah3X48= +github.com/aws/aws-sdk-go-v2/service/apigatewayv2 v1.14.5 h1:pLmOgMUiwXOi3oKx2J3feVb9JGVgwJ78RYnOV9UR0BM= +github.com/aws/aws-sdk-go-v2/service/apigatewayv2 v1.14.5/go.mod h1:4eIs6K6ag6ymoUMOFfjm9dmP9KbuKgC7K5eIqlIBsbY= github.com/aws/aws-sdk-go-v2/service/appconfig v1.4.2/go.mod h1:FZ3HkCe+b10uFZZkFdvf98LHW21k49W8o8J366lqVKY= -github.com/aws/aws-sdk-go-v2/service/autoscaling v1.28.10 h1:moHEk4wbdc8VNvff4UOLuXVHtjh7YtsGdiyB0MrPPKg= -github.com/aws/aws-sdk-go-v2/service/autoscaling v1.28.10/go.mod h1:P3qp1VYVoxHgDhpDDCTre1ee9IKpmgqnUoOb+8RA9qI= +github.com/aws/aws-sdk-go-v2/service/autoscaling v1.30.6 h1:OuxP8FzE3++AjQ8wabMcwJxtS25inpTIblMPNzV3nB8= +github.com/aws/aws-sdk-go-v2/service/autoscaling v1.30.6/go.mod h1:iHCpld+TvQd0odwp6BiwtL9H9LbU41kPW1i9oBy3iOo= github.com/aws/aws-sdk-go-v2/service/cloudwatch v1.5.0/go.mod h1:acH3+MQoiMzozT/ivU+DbRg7Ooo2298RdRaWcOv+4vM= -github.com/aws/aws-sdk-go-v2/service/databasemigrationservice v1.27.0 h1:8ei9YIP3tmLbIX4rh1Hq9MM8/rpb1QBtHreVN/TP7wQ= -github.com/aws/aws-sdk-go-v2/service/databasemigrationservice v1.27.0/go.mod h1:UXh7fjHrDoVd/tRPQyGCSfb04setwR75qxAx7+x1vcU= -github.com/aws/aws-sdk-go-v2/service/ec2 v1.106.0 h1:chzRNw2kwcrosHm0k72Wyf4sbUNcG8+HeCJbSBtsOTk= -github.com/aws/aws-sdk-go-v2/service/ec2 v1.106.0/go.mod h1:/0btVmMZJ0sn9JQ2N96XszlQNeRCJhhXOS/sPZgDeew= +github.com/aws/aws-sdk-go-v2/service/databasemigrationservice v1.30.4 h1:Ir8BEejwSOOrD9juzFSMdXkXPyIdj1DfkFR+FJb0kc8= +github.com/aws/aws-sdk-go-v2/service/databasemigrationservice v1.30.4/go.mod h1:NSAyKko0rDkrZOjcdCPPvMEe+FyIw/aDDQ8X+xAIW44= +github.com/aws/aws-sdk-go-v2/service/ec2 v1.117.0 h1:Yq39vbwQX+Xw+Ubcsg/ElwO+TWAxAIAdrREtpjGnCHw= +github.com/aws/aws-sdk-go-v2/service/ec2 v1.117.0/go.mod h1:0FhI2Rzcv5BNM3dNnbcCx2qa2naFZoAidJi11cQgzL0= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.11 h1:y2+VQzC6Zh2ojtV2LoC0MNwHWc6qXv/j2vrQtlftkdA= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.11/go.mod h1:iV4q2hsqtNECrfmlXyord9u4zyuFEJX9eLgLpSPzWA8= github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.29 h1:zZSLP3v3riMOP14H7b4XP0uyfREDQOYv2cqIrvTXDNQ= @@ -372,12 +380,12 @@ github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.36 h1:YXlm7LxwN github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.36/go.mod h1:ou9ffqJ9hKOVZmjlC6kQ6oROAyG1M4yBKzR+9BKbDwk= github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.14.3 h1:dBL3StFxHtpBzJJ/mNEsjXVgfO+7jR0dAIEwLqMapEA= github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.14.3/go.mod h1:f1QyiAsvIv4B49DmCqrhlXqyaR+0IxMmyX+1P+AnzOM= -github.com/aws/aws-sdk-go-v2/service/resourcegroupstaggingapi v1.14.15 h1:5I9Yi2Ls1q8/VTpRmlLOGilFCtJNsEms+64BhYybm7Y= -github.com/aws/aws-sdk-go-v2/service/resourcegroupstaggingapi v1.14.15/go.mod h1:86l8OObGPcaNgQ2pVaRRdaHTepispGs2UYLp8niWkSM= +github.com/aws/aws-sdk-go-v2/service/resourcegroupstaggingapi v1.15.5 h1:dMsTYzhTpsDMY79IzCh/jq1tHRwgfa15ujhKUjZk0fg= +github.com/aws/aws-sdk-go-v2/service/resourcegroupstaggingapi v1.15.5/go.mod h1:Lh/6ABs1m80bEB36fAW9gEPW5kSsAr7Mdn8dGyWRLp0= github.com/aws/aws-sdk-go-v2/service/s3 v1.34.1 h1:rYYwwsGqbwvGgQHjBkqgDt8MynXk+I8xgS0IEj5gOT0= github.com/aws/aws-sdk-go-v2/service/s3 v1.34.1/go.mod h1:aVbf0sko/TsLWHx30c/uVu7c62+0EAJ3vbxaJga0xCw= -github.com/aws/aws-sdk-go-v2/service/shield v1.18.13 h1:/QqZKWvxShuecy5hZm6P4pJQ2Uzn6TSJtsd9xeaqLG0= -github.com/aws/aws-sdk-go-v2/service/shield v1.18.13/go.mod h1:YcHL79qHynGYok2NKGb3+mrb6EWROWD4gBU3v+tKtUM= +github.com/aws/aws-sdk-go-v2/service/shield v1.19.5 h1:zX/1OHVjTNB2D1xiQ0pByYNLbVgbl84fTj5W4tMKdAk= +github.com/aws/aws-sdk-go-v2/service/shield v1.19.5/go.mod h1:NKqcE1DkD5YSbTAR8MxhFGFDmSkGNo68/Q8hht3Mi5w= github.com/aws/aws-sdk-go-v2/service/sso v1.4.2/go.mod h1:NBvT9R1MEF+Ud6ApJKM0G+IkPchKS7p7c2YPKwHmBOk= github.com/aws/aws-sdk-go-v2/service/sso v1.12.12/go.mod h1:HuCOxYsF21eKrerARYO6HapNeh9GBNq7fius2AcwodY= github.com/aws/aws-sdk-go-v2/service/sso v1.15.1 h1:ZN3bxw9OYC5D6umLw6f57rNJfGfhg1DIAAcKpzyUTOE= @@ -385,8 +393,8 @@ github.com/aws/aws-sdk-go-v2/service/sso v1.15.1/go.mod h1:PieckvBoT5HtyB9AsJRrY github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.12/go.mod h1:E4VrHCPzmVB/KFXtqBGKb3c8zpbNBgKe3fisDNLAW5w= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.17.2 h1:fSCCJuT5i6ht8TqGdZc5Q5K9pz/atrf7qH4iK5C9XzU= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.17.2/go.mod h1:5eNtr+vNc5vVd92q7SJ+U/HszsIdhZBEyi9dkMRKsp8= -github.com/aws/aws-sdk-go-v2/service/storagegateway v1.18.16 h1:Gk+75k6j55fqE+uA/99jAlcZBY4OLT244JuKp+HLXxo= -github.com/aws/aws-sdk-go-v2/service/storagegateway v1.18.16/go.mod h1:l/XhpyuxnJ3s8yKi9h0XDwVqM18iDEFeUVDYGCEcE/g= +github.com/aws/aws-sdk-go-v2/service/storagegateway v1.19.6 h1:DfxHxomSOVAmiYb4I1IkcrKtjFrm4EHUEw/oHPuNgxI= +github.com/aws/aws-sdk-go-v2/service/storagegateway v1.19.6/go.mod h1:o3x7HLasCY8mN914V4611sbXPOE54V8t0pzCtz5bxQ0= github.com/aws/aws-sdk-go-v2/service/sts v1.7.2/go.mod h1:8EzeIqfWt2wWT4rJVu3f21TfrhJ8AEMzVybRNSb/b4g= github.com/aws/aws-sdk-go-v2/service/sts v1.19.2/go.mod h1:dp0yLPsLBOi++WTxzCjA/oZqi6NPIhoR+uF7GeMU9eg= github.com/aws/aws-sdk-go-v2/service/sts v1.23.1 h1:ASNYk1ypWAxRhJjKS0jBnTUeDl7HROOpeSMu1xDA/I8= @@ -559,12 +567,11 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm github.com/dgrijalva/jwt-go/v4 v4.0.0-preview1/go.mod h1:+hnT3ywWDTAFrW5aE+u2Sa/wT555ZqwoCS+pk3p6ry4= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= -github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/digitalocean/godo v1.1.1/go.mod h1:h6faOIcZ8lWIwNQ+DN7b3CgX4Kwby5T+nbpNqkUIozU= github.com/digitalocean/godo v1.7.5/go.mod h1:h6faOIcZ8lWIwNQ+DN7b3CgX4Kwby5T+nbpNqkUIozU= github.com/digitalocean/godo v1.10.0/go.mod h1:h6faOIcZ8lWIwNQ+DN7b3CgX4Kwby5T+nbpNqkUIozU= -github.com/digitalocean/godo v1.99.0 h1:gUHO7n9bDaZFWvbzOum4bXE0/09ZuYA9yA8idQHX57E= -github.com/digitalocean/godo v1.99.0/go.mod h1:SsS2oXo2rznfM/nORlZ/6JaUJZFhmKTib1YhopUc8NA= +github.com/digitalocean/godo v1.104.1 h1:SZNxjAsskM/su0YW9P8Wx3gU0W1Z13b6tZlYNpl5BnA= +github.com/digitalocean/godo v1.104.1/go.mod h1:VAI/L5YDzMuPRU01lEEUSQ/sp5Z//1HnnFv/RBTEdbg= github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi/U= github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE= @@ -715,9 +722,13 @@ github.com/go-git/go-git-fixtures/v4 v4.2.1 h1:n9gGL1Ct/yIw+nfsfr8s4+sbhT+Ncu2Su github.com/go-git/go-git-fixtures/v4 v4.2.1/go.mod h1:K8zd3kDUAykwTdDCr+I0per6Y6vMiRR/nnVTBtavnB0= github.com/go-git/go-git/v5 v5.4.2 h1:BXyZu9t0VkbiHtqrsvdq39UDhGJTl1h55VW6CSC4aY4= github.com/go-git/go-git/v5 v5.4.2/go.mod h1:gQ1kArt6d+n+BGd+/B/I74HwRTLhth2+zti4ihgckDc= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= -github.com/go-jose/go-jose/v3 v3.0.0 h1:s6rrhirfEP/CGIoc6p+PZAeogN2SxKav6Wp7+dyMWVo= github.com/go-jose/go-jose/v3 v3.0.0/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8= +github.com/go-jose/go-jose/v3 v3.0.1 h1:pWmKFVtt+Jl0vBZTIpz/eAKwsm6LkIxDVVbFHKkchhA= +github.com/go-jose/go-jose/v3 v3.0.1/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= @@ -1020,8 +1031,8 @@ github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8 github.com/gopcua/opcua v0.1.12/go.mod h1:a6QH4F9XeODklCmWuvaOdL8v9H0d73CEKUHWVZLQyE8= github.com/gophercloud/gophercloud v0.0.0-20180828235145-f29afc2cceca/go.mod h1:3WdhXV3rUYy9p6AUW8d94kr+HS62Y4VL9mBnFxsD8q4= github.com/gophercloud/gophercloud v0.1.0/go.mod h1:vxM41WHh5uqHVBMZHzuwNOHh8XEoIEcSTewFxm1c5g8= -github.com/gophercloud/gophercloud v1.5.0 h1:cDN6XFCLKiiqvYpjQLq9AiM7RDRbIC9450WpPH+yvXo= -github.com/gophercloud/gophercloud v1.5.0/go.mod h1:aAVqcocTSXh2vYFZ1JTvx4EQmfgzxRcNupUfxZbBNDM= +github.com/gophercloud/gophercloud v1.7.0 h1:fyJGKh0LBvIZKLvBWvQdIgkaV5yTM3Jh9EYUh+UNCAs= +github.com/gophercloud/gophercloud v1.7.0/go.mod h1:aAVqcocTSXh2vYFZ1JTvx4EQmfgzxRcNupUfxZbBNDM= github.com/gopherjs/gopherjs v0.0.0-20180825215210-0210a2f0f73c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v1.17.2 h1:fQnZVsXk8uxXIStYb0N4bGk7jeyTalG/wsZjQ25dO0g= @@ -1057,8 +1068,8 @@ github.com/grafana/gomemcache v0.0.0-20230316202710-a081dae0aba9 h1:WB3bGH2f1UN6 github.com/grafana/gomemcache v0.0.0-20230316202710-a081dae0aba9/go.mod h1:PGk3RjYHpxMM8HFPhKKo+vve3DdlPUELZLSDEFehPuU= github.com/grafana/loki v1.6.2-0.20231004111112-07cbef92268a h1:lvSHlNONeo/H+aWRk86QEfBpRDCEX1yoqpsCK0Tys+g= github.com/grafana/loki v1.6.2-0.20231004111112-07cbef92268a/go.mod h1:a5c5ZTC6FNufKkvF8NeDAb2nCWJpgkVDrejmV+O9hac= -github.com/grafana/loki/pkg/push v0.0.0-20230904153656-e4cc2a4f5ec8 h1:yQK/dX7WBva5QvITvmIcbv4boLwSo65a8zjuZcucnko= -github.com/grafana/loki/pkg/push v0.0.0-20230904153656-e4cc2a4f5ec8/go.mod h1:5ll3An1wAxYejo6aM04+3/lc6N4joYVYLY5U+Z4O6vI= +github.com/grafana/loki/pkg/push v0.0.0-20231212100434-384e5c2dc872 h1:6kPX7bngjBgUlHqADwZ6249UtzMaoQW5n0H8bOtnYeM= +github.com/grafana/loki/pkg/push v0.0.0-20231212100434-384e5c2dc872/go.mod h1:f3JSoxBTPXX5ec4FxxeC19nTBSxoTz+cBgS3cYLMcr0= github.com/grafana/mysqld_exporter v0.12.2-0.20231005125903-364b9c41e595 h1:I9sRknI5ajd8whPOX0nBDXy5B6xUfhItClMy+6R4oqE= github.com/grafana/mysqld_exporter v0.12.2-0.20231005125903-364b9c41e595/go.mod h1:U8ifHC5pT2WuVTO7ki4KZmWLjfEKfktQiU3bh0J8scw= github.com/grafana/node_exporter v0.18.1-grafana-r01.0.20231004161416-702318429731 h1:vyyIYY2sLpmgFIckJ1vSO/oYkvB0thDF6UiFYp5PThM= @@ -1069,14 +1080,12 @@ github.com/grafana/opentelemetry-collector/service v0.0.0-20231018134914-c0109e0 github.com/grafana/opentelemetry-collector/service v0.0.0-20231018134914-c0109e052230/go.mod h1:kBdpzrqR2wJkOdg50yzp4dv+2XBMyeqTgF4lCx0hSpQ= github.com/grafana/postgres_exporter v0.8.1-0.20210722175051-db35d7c2f520 h1:HnFWqxhoSF3WC7sKAdMZ+SRXvHLVZlZ3sbQjuUlTqkw= github.com/grafana/postgres_exporter v0.8.1-0.20210722175051-db35d7c2f520/go.mod h1:+HPXgiOV0InDHcZ2jNijL1SOKvo0eEPege5fQA0+ICI= -github.com/grafana/prometheus v1.8.2-0.20231016083943-46550094220d h1:hr0QEXSfpdakWdHw2sZeT/5GnGwIkHnNO0YBkfRj5zk= -github.com/grafana/prometheus v1.8.2-0.20231016083943-46550094220d/go.mod h1:J/bmOSjgH7lFxz2gZhrWEZs2i64vMS+HIuZfmYNhJ/M= github.com/grafana/pyroscope-go/godeltaprof v0.1.3 h1:eunWpv1B3Z7ZK9o4499EmQGlY+CsDmSZ4FbxjRx37uk= github.com/grafana/pyroscope-go/godeltaprof v0.1.3/go.mod h1:1HSPtjU8vLG0jE9JrTdzjgFqdJ/VgN7fvxBNq3luJko= github.com/grafana/pyroscope/api v0.2.0 h1:TzOxL0s6SiaLEy944ZAKgHcx/JDRJXu4O8ObwkqR6p4= github.com/grafana/pyroscope/api v0.2.0/go.mod h1:nhH+xai9cYFgs6lMy/+L0pKj0d5yCMwji/QAiQFCP+U= -github.com/grafana/pyroscope/ebpf v0.4.0 h1:7fz+5S6MLSc+5cJfmIe7OCvBdooxEm8xy5OAV0s7GA0= -github.com/grafana/pyroscope/ebpf v0.4.0/go.mod h1:eF5+k9lAUBYILVzGccr3hrrvuLy5ZvbDRWGQHDe021w= +github.com/grafana/pyroscope/ebpf v0.4.1 h1:iqQoOsfKen5KpTRe6MfGeBZfgK1s7ROH+Cs/vZs1B3A= +github.com/grafana/pyroscope/ebpf v0.4.1/go.mod h1:W99Mq+yJGP5nZUQWNv+jVytiWWgWXwHjIRmi9k3xHzA= github.com/grafana/regexp v0.0.0-20221123153739-15dc172cd2db h1:7aN5cccjIqCLTzedH7MZzRZt5/lsAHch6Z3L2ZGn5FA= github.com/grafana/regexp v0.0.0-20221123153739-15dc172cd2db/go.mod h1:M5qHK+eWfAv8VR/265dIuEpL3fNfeC21tXXp9itM24A= github.com/grafana/river v0.3.0 h1:6TsaR/vkkcppUM9I0muGbPIUedCtpPu6OWreE5+CE6g= @@ -1224,8 +1233,8 @@ github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOn github.com/hashicorp/memberlist v0.5.0 h1:EtYPN8DpAURiapus508I4n9CzHs2W+8NZGbmmR/prTM= github.com/hashicorp/memberlist v0.5.0/go.mod h1:yvyXLpo0QaGE59Y7hDTsTzDD25JYBZ4mHgHUZ8lrOI0= github.com/hashicorp/net-rpc-msgpackrpc v0.0.0-20151116020338-a14192a58a69/go.mod h1:/z+jUGRBlwVpUZfjute9jWaF6/HuhjuFQuL1YXzVD1Q= -github.com/hashicorp/nomad/api v0.0.0-20230718173136-3a687930bd3e h1:sr4lujmn9heD030xx/Pd4B/JSmvRhFzuotNXaaV0WLs= -github.com/hashicorp/nomad/api v0.0.0-20230718173136-3a687930bd3e/go.mod h1:O23qLAZuCx4htdY9zBaO4cJPXgleSFEdq6D/sezGgYE= +github.com/hashicorp/nomad/api v0.0.0-20230721134942-515895c7690c h1:Nc3Mt2BAnq0/VoLEntF/nipX+K1S7pG+RgwiitSv6v0= +github.com/hashicorp/nomad/api v0.0.0-20230721134942-515895c7690c/go.mod h1:O23qLAZuCx4htdY9zBaO4cJPXgleSFEdq6D/sezGgYE= github.com/hashicorp/raft v1.0.1-0.20190409200437-d9fe23f7d472/go.mod h1:DVSAWItjLjTOkVbSpWQ0j0kUADIvDaCtBxIcbNAQLkI= github.com/hashicorp/raft-boltdb v0.0.0-20150201200839-d1e82c1ec3f1/go.mod h1:pNv7Wc3ycL6F5oOWn+tPGo2gWD4a5X+yp/ntwdKLjRk= github.com/hashicorp/serf v0.8.1/go.mod h1:h/Ru6tmZazX7WO/GDmwdpS975F019L4t5ng5IgwbNrE= @@ -1262,8 +1271,8 @@ github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKe github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= github.com/heroku/x v0.0.61 h1:yfoAAtnFWSFZj+UlS+RZL/h8QYEp1R4wHVEg0G+Hwh4= github.com/heroku/x v0.0.61/go.mod h1:C7xYbpMdond+s6L5VpniDUSVPRwm3kZum1o7XiD5ZHk= -github.com/hetznercloud/hcloud-go/v2 v2.0.0 h1:Sg1DJ+MAKvbYAqaBaq9tPbwXBS2ckPIaMtVdUjKu+4g= -github.com/hetznercloud/hcloud-go/v2 v2.0.0/go.mod h1:4iUG2NG8b61IAwNx6UsMWQ6IfIf/i1RsG0BbsKAyR5Q= +github.com/hetznercloud/hcloud-go/v2 v2.4.0 h1:MqlAE+w125PLvJRCpAJmEwrIxoVdUdOyuFUhE/Ukbok= +github.com/hetznercloud/hcloud-go/v2 v2.4.0/go.mod h1:l7fA5xsncFBzQTyw29/dw5Yr88yEGKKdc6BHf24ONS0= github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= github.com/hjson/hjson-go/v4 v4.0.0/go.mod h1:KaYt3bTw3zhBjYqnXkYywcYctk0A2nxeEFTse3rH13E= @@ -1305,8 +1314,8 @@ github.com/influxdata/telegraf v1.16.3 h1:x0qeuSGGMg5y+YqP/5ZHwXZu3bcBrO8AAQOTNl github.com/influxdata/telegraf v1.16.3/go.mod h1:fX/6k7qpIqzVPWyeIamb0wN5hbwc0ANUaTS80lPYFB8= github.com/influxdata/toml v0.0.0-20190415235208-270119a8ce65/go.mod h1:zApaNFpP/bTpQItGZNNUMISDMDAnTXu9UqJ4yT3ocz8= github.com/influxdata/wlog v0.0.0-20160411224016-7c63b0a71ef8/go.mod h1:/2NMgWB1DHM1ti/gqhOlg+LJeBVk6FqR5aVGYY0hlwI= -github.com/ionos-cloud/sdk-go/v6 v6.1.8 h1:493wE/BkZxJf7x79UCE0cYGPZoqQcPiEBALvt7uVGY0= -github.com/ionos-cloud/sdk-go/v6 v6.1.8/go.mod h1:EzEgRIDxBELvfoa/uBN0kOQaqovLjUWEB7iW4/Q+t4k= +github.com/ionos-cloud/sdk-go/v6 v6.1.9 h1:Iq3VIXzeEbc8EbButuACgfLMiY5TPVWUPNrF+Vsddo4= +github.com/ionos-cloud/sdk-go/v6 v6.1.9/go.mod h1:EzEgRIDxBELvfoa/uBN0kOQaqovLjUWEB7iW4/Q+t4k= github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8= @@ -1495,8 +1504,8 @@ github.com/lightstep/go-expohisto v1.0.0/go.mod h1:xDXD0++Mu2FOaItXtdDfksfgxfV0z github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= github.com/linode/linodego v0.7.1/go.mod h1:ga11n3ivecUrPCHN0rANxKmfWBJVkOXfLMZinAbj2sY= -github.com/linode/linodego v1.19.0 h1:n4WJrcr9+30e9JGZ6DI0nZbm5SdAj1kSwvvt/998YUw= -github.com/linode/linodego v1.19.0/go.mod h1:XZFR+yJ9mm2kwf6itZ6SCpu+6w3KnIevV0Uu5HNWJgQ= +github.com/linode/linodego v1.23.0 h1:s0ReCZtuN9Z1IoUN9w1RLeYO1dMZUGPwOQ/IBFsBHtU= +github.com/linode/linodego v1.23.0/go.mod h1:0U7wj/UQOqBNbKv1FYTXiBUXueR8DY4HvIotwE0ENgg= github.com/lufia/iostat v1.2.1 h1:tnCdZBIglgxD47RyD55kfWQcJMGzO+1QBziSQfesf2k= github.com/lufia/iostat v1.2.1/go.mod h1:rEPNA0xXgjHQjuI5Cy05sLlS2oRcSlWHRLrvh/AQ+Pg= github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I= @@ -1577,8 +1586,8 @@ github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3N github.com/miekg/dns v1.1.25/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= -github.com/miekg/dns v1.1.55 h1:GoQ4hpsj0nFLYe+bWiCToyrBEJXkQfOOIvFGFy0lEgo= -github.com/miekg/dns v1.1.55/go.mod h1:uInx36IzPl7FYnDcMeVWxj9byh7DutNykX4G9Sj60FY= +github.com/miekg/dns v1.1.56 h1:5imZaSeoRNvpM9SzWNhEcP9QliKiz20/dA2QabIGVnE= +github.com/miekg/dns v1.1.56/go.mod h1:cRm6Oo2C8TY9ZS/TqsSrseAcncm74lfK5G+ikN2SWWY= github.com/mikioh/ipaddr v0.0.0-20190404000644-d465c8ab6721/go.mod h1:Ickgr2WtCLZ2MDGd4Gr0geeCH5HybhRJbonOgQpvSxc= github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8 h1:AMFGa4R4MiIpspGNG7Z948v4n35fFGB3RR3G/ry4FWs= github.com/minio/asm2plan9s v0.0.0-20200509001527-cdd76441f9d8/go.mod h1:mC1jAcsrzbxHt8iiaC+zU4b1ylILSosueou12R++wfY= @@ -1681,8 +1690,8 @@ github.com/ncabatoff/go-seq v0.0.0-20180805175032-b08ef85ed833 h1:t4WWQ9I797y7QU github.com/ncabatoff/go-seq v0.0.0-20180805175032-b08ef85ed833/go.mod h1:0CznHmXSjMEqs5Tezj/w2emQoM41wzYM9KpDKUHPYag= github.com/ncabatoff/process-exporter v0.7.10 h1:+Ere7+3se6QqP54gg7aBRagWcL8bq3u5zNi/GRSWeKQ= github.com/ncabatoff/process-exporter v0.7.10/go.mod h1:DHZRZjqxw9LCOpLlX0DjBuyn6d5plh41Jv6Tmttj7Ek= -github.com/nerdswords/yet-another-cloudwatch-exporter v0.54.0 h1:a2jReAfDiSyU/aXCKO05hcJMTdtyQQyj41Jmwyg6fh8= -github.com/nerdswords/yet-another-cloudwatch-exporter v0.54.0/go.mod h1:VngmqrhYKwZzUuv/sgVCfUhLB6BkgSZfL5USqZbGKnY= +github.com/nerdswords/yet-another-cloudwatch-exporter v0.55.0 h1:M3fH9gzU48jBfYbXXYEZVTcUhnfhDIG/oeIQl6kBGP0= +github.com/nerdswords/yet-another-cloudwatch-exporter v0.55.0/go.mod h1:GR4pDHlRonT97AsGSmlcWiISF8AjifK/19SAVD0tIlU= github.com/newrelic/newrelic-telemetry-sdk-go v0.2.0/go.mod h1:G9MqE/cHGv3Hx3qpYhfuyFUsGx2DpVcGi1iJIqTg+JQ= github.com/nicolai86/scaleway-sdk v1.10.2-0.20180628010248-798f60e20bb2 h1:BQ1HW7hr4IVovMwWg0E0PYcyW8CzqDcVmaew9cujU4s= github.com/nicolai86/scaleway-sdk v1.10.2-0.20180628010248-798f60e20bb2/go.mod h1:TLb2Sg7HQcgGdloNxkrmtgDNR9uVYF3lfdFIN4Ro6Sk= @@ -1861,8 +1870,8 @@ github.com/oschwald/geoip2-golang v1.9.0 h1:uvD3O6fXAXs+usU+UGExshpdP13GAqp4GBrz github.com/oschwald/geoip2-golang v1.9.0/go.mod h1:BHK6TvDyATVQhKNbQBdrj9eAvuwOMi2zSFXizL3K81Y= github.com/oschwald/maxminddb-golang v1.11.0 h1:aSXMqYR/EPNjGE8epgqwDay+P30hCBZIveY0WZbAWh0= github.com/oschwald/maxminddb-golang v1.11.0/go.mod h1:YmVI+H0zh3ySFR3w+oz8PCfglAFj3PuCmui13+P9zDg= -github.com/ovh/go-ovh v1.4.1 h1:VBGa5wMyQtTP7Zb+w97zRCh9sLtM/2YKRyy+MEJmWaM= -github.com/ovh/go-ovh v1.4.1/go.mod h1:6bL6pPyUT7tBfI0pqOegJgRjgjuO+mOo+MyXd1EEC0M= +github.com/ovh/go-ovh v1.4.3 h1:Gs3V823zwTFpzgGLZNI6ILS4rmxZgJwJCz54Er9LwD0= +github.com/ovh/go-ovh v1.4.3/go.mod h1:AkPXVtgwB6xlKblMjRKJJmjRp+ogrE7fz2lVgcQY8SY= github.com/packethost/packngo v0.1.1-0.20180711074735-b9cb5096f54c h1:vwpFWvAO8DeIZfFeqASzZfsxuWPno9ncAebBEP0N3uE= github.com/packethost/packngo v0.1.1-0.20180711074735-b9cb5096f54c/go.mod h1:otzZQXgoO96RTzDB/Hycg0qZcXZsWJGJRSXbmEIJ+4M= github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= @@ -2001,13 +2010,13 @@ github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1 github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= +github.com/prometheus/prometheus v0.48.1 h1:CTszphSNTXkuCG6O0IfpKdHcJkvvnAAE1GbELKS+NFk= +github.com/prometheus/prometheus v0.48.1/go.mod h1:SRw624aMAxTfryAcP8rOjg4S/sHHaetx2lyJJ2nM83g= github.com/prometheus/snmp_exporter v0.24.1 h1:AihTbJHurMo8bjtjJde8U+4gMEvpvYvT21Xbd4SzJgY= github.com/prometheus/snmp_exporter v0.24.1/go.mod h1:j6uIGkdR0DXvKn7HJtSkeDj//UY0sWmdd6XhvdBjln0= github.com/prometheus/statsd_exporter v0.22.7/go.mod h1:N/TevpjkIh9ccs6nuzY3jQn9dFqnUakOjnEuMPJJJnI= github.com/prometheus/statsd_exporter v0.22.8 h1:Qo2D9ZzaQG+id9i5NYNGmbf1aa/KxKbB9aKfMS+Yib0= github.com/prometheus/statsd_exporter v0.22.8/go.mod h1:/DzwbTEaFTE0Ojz5PqcSk6+PFHOPWGxdXVr6yC8eFOM= -github.com/prometheus/tsdb v0.10.0 h1:If5rVCMTp6W2SiRAQFlbpJNgVlgMEd+U2GZckwK38ic= -github.com/prometheus/tsdb v0.10.0/go.mod h1:oi49uRhEe9dPUTlS3JRZOwJuVi6tmh10QSgwXEyGCt4= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 h1:N/ElC8H3+5XpJzTSTfLsJV/mx9Q9g7kxmchpfZyxgzM= @@ -2056,8 +2065,8 @@ github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da h1:p3Vo3i64TCL github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= github.com/satori/go.uuid v1.2.1-0.20181028125025-b2ce2384e17b/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= -github.com/scaleway/scaleway-sdk-go v1.0.0-beta.20 h1:a9hSJdJcd16e0HoMsnFvaHvxB3pxSD+SC7+CISp7xY0= -github.com/scaleway/scaleway-sdk-go v1.0.0-beta.20/go.mod h1:fCa7OJZ/9DRTnOKmxvT6pn+LPWUptQAmHF/SBJUGEcg= +github.com/scaleway/scaleway-sdk-go v1.0.0-beta.21 h1:yWfiTPwYxB0l5fGMhl/G+liULugVIHD9AU77iNLrURQ= +github.com/scaleway/scaleway-sdk-go v1.0.0-beta.21/go.mod h1:fCa7OJZ/9DRTnOKmxvT6pn+LPWUptQAmHF/SBJUGEcg= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= @@ -2504,15 +2513,29 @@ golang.org/x/crypto v0.0.0-20220511200225-c6db032c6c88/go.mod h1:IxCIyHEi3zRg3s0 golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= golang.org/x/crypto v0.15.0 h1:frVn1TEaCEaZcn3Tmd7Y2b5KKPaZ+I32Q2OA3kYp5TA= golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g= -golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1 h1:MGwJjxBy0HJshjDNfLsYO8xppfqWlA5ZT9OhtUUhTNw= -golang.org/x/exp v0.0.0-20230713183714-613f0c0eb8a1/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc= +golang.org/x/exp v0.0.0-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= +golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ= +golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20180702182130-06c8688daad7/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -2526,8 +2549,12 @@ golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPI golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.1-0.20200828183125-ce943fd02449/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -2535,9 +2562,7 @@ 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.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -2687,6 +2712,7 @@ golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191003212358-c178f38b412c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -2830,6 +2856,7 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= @@ -2845,9 +2872,11 @@ golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgw golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -2863,6 +2892,7 @@ golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapK golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= @@ -2894,7 +2924,6 @@ 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.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.15.0 h1:zdAyfUGbYmuVokhzVmghFl2ZJh5QhcfebBgmVPFYA+8= golang.org/x/tools v0.15.0/go.mod h1:hpksKq4dtpQWS1uQ61JkdqWM3LscIS6Slf+VVkm+wQk= @@ -2946,8 +2975,8 @@ google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00 google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= -google.golang.org/api v0.146.0 h1:9aBYT4vQXt9dhCuLNfwfd3zpwu8atg0yPkjBymwSrOM= -google.golang.org/api v0.146.0/go.mod h1:OARJqIfoYjXJj4C1AiBSXYZt03qsoz8FQYU6fBEfrHM= +google.golang.org/api v0.147.0 h1:Can3FaQo9LlVqxJCodNmeZW/ib3/qKAY3rFeXiHo5gc= +google.golang.org/api v0.147.0/go.mod h1:pQ/9j83DcmPd/5C9e2nFOdjjNkDZ1G+zkbK2uvdkJMs= 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= @@ -3023,8 +3052,8 @@ google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEc google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20231012201019-e917dd12ba7a h1:fwgW9j3vHirt4ObdHoYNwuO24BEZjSzbh+zPaNWoiY8= google.golang.org/genproto v0.0.0-20231012201019-e917dd12ba7a/go.mod h1:EMfReVxb80Dq1hhioy0sOsY9jCE46YDgHlJ7fWVUWRE= -google.golang.org/genproto/googleapis/api v0.0.0-20231002182017-d307bd883b97 h1:W18sezcAYs+3tDZX4F80yctqa12jcP1PUS2gQu1zTPU= -google.golang.org/genproto/googleapis/api v0.0.0-20231002182017-d307bd883b97/go.mod h1:iargEX0SFPm3xcfMI0d1domjg0ZF4Aa0p2awqyxhvF0= +google.golang.org/genproto/googleapis/api v0.0.0-20231012201019-e917dd12ba7a h1:myvhA4is3vrit1a6NZCWBIwN0kNEnX21DJOJX/NvIfI= +google.golang.org/genproto/googleapis/api v0.0.0-20231012201019-e917dd12ba7a/go.mod h1:SUBoKXbI1Efip18FClrQVGjWcyd0QZd8KkvdP34t7ww= google.golang.org/genproto/googleapis/rpc v0.0.0-20231016165738-49dd2c1f3d0b h1:ZlWIi1wSK56/8hn4QcBp/j9M7Gt3U/3hZw3mC7vDICo= google.golang.org/genproto/googleapis/rpc v0.0.0-20231016165738-49dd2c1f3d0b/go.mod h1:swOH3j0KzcDDgGUWr+SNpyTen5YrXjS3eyPzFYKc6lc= google.golang.org/grpc v0.0.0-20180920234847-8997b5fa0873/go.mod h1:0JHn/cJsOMiMfNA9+DeHDlAU7KAAB5GDlYFpa9MZMio= diff --git a/pkg/metrics/instance/configstore/api_test.go b/pkg/metrics/instance/configstore/api_test.go index 15a111520301..84c0198dee00 100644 --- a/pkg/metrics/instance/configstore/api_test.go +++ b/pkg/metrics/instance/configstore/api_test.go @@ -139,6 +139,7 @@ scrape_configs: honor_timestamps: true metrics_path: /metrics scheme: http + track_timestamps_staleness: true static_configs: - targets: - 127.0.0.1:12345 diff --git a/pkg/metrics/instance/host_filter_test.go b/pkg/metrics/instance/host_filter_test.go index aa53bd25b727..8a24373594c0 100644 --- a/pkg/metrics/instance/host_filter_test.go +++ b/pkg/metrics/instance/host_filter_test.go @@ -172,6 +172,7 @@ func TestHostFilter_PatchSD(t *testing.T) { honor_timestamps: true metrics_path: /metrics scheme: http + track_timestamps_staleness: false follow_redirects: true enable_http2: true kubernetes_sd_configs: diff --git a/pkg/metrics/instance/marshal_test.go b/pkg/metrics/instance/marshal_test.go index 5d2a68b870da..b102c3d635d2 100644 --- a/pkg/metrics/instance/marshal_test.go +++ b/pkg/metrics/instance/marshal_test.go @@ -36,6 +36,7 @@ scrape_configs: honor_timestamps: true metrics_path: /metrics scheme: http + track_timestamps_staleness: true static_configs: - targets: - 127.0.0.1:12345 @@ -92,6 +93,7 @@ scrape_configs: honor_timestamps: true metrics_path: /metrics scheme: http + track_timestamps_staleness: true static_configs: - targets: - 127.0.0.1:12345 From d8efe1a9412b8997d24a075c7ffecbd6157c9bf6 Mon Sep 17 00:00:00 2001 From: Piotr <17101802+thampiotr@users.noreply.github.com> Date: Fri, 5 Jan 2024 14:33:14 +0100 Subject: [PATCH 07/68] create migrate tasks subdirectory (#6051) --- docs/sources/about.md | 4 ++-- docs/sources/flow/reference/cli/convert.md | 6 +++--- docs/sources/flow/tasks/migrate/_index.md | 19 +++++++++++++++++++ .../from-operator.md} | 12 ++++++------ .../from-prometheus.md} | 10 +++++----- .../from-promtail.md} | 10 +++++----- .../from-static.md} | 18 +++++++++--------- 7 files changed, 49 insertions(+), 30 deletions(-) create mode 100644 docs/sources/flow/tasks/migrate/_index.md rename docs/sources/flow/tasks/{migrating-from-operator.md => migrate/from-operator.md} (97%) rename docs/sources/flow/tasks/{migrating-from-prometheus.md => migrate/from-prometheus.md} (98%) rename docs/sources/flow/tasks/{migrating-from-promtail.md => migrate/from-promtail.md} (98%) rename docs/sources/flow/tasks/{migrating-from-static.md => migrate/from-static.md} (97%) diff --git a/docs/sources/about.md b/docs/sources/about.md index c33d73087408..57468c7f3e24 100644 --- a/docs/sources/about.md +++ b/docs/sources/about.md @@ -33,8 +33,8 @@ Grafana Agent is available in three different variants: [Prometheus]: "/docs/grafana-cloud/ -> /docs/agent//flow/tasks/collect-prometheus-metrics.md" [OTel]: "/docs/agent/ -> /docs/agent//flow/tasks/collect-opentelemetry-data.md" [OTel]: "/docs/grafana-cloud/ -> /docs/agent//flow/tasks/collect-opentelemetry-data.md" -[Loki]: "/docs/agent/ -> /docs/agent//flow/tasks/migrating-from-promtail.md" -[Loki]: "/docs/grafana-cloud/ -> /docs/agent//flow/tasks/migrating-from-promtail.md" +[Loki]: "/docs/agent/ -> /docs/agent//flow/tasks/migrate/from-promtail.md" +[Loki]: "/docs/grafana-cloud/ -> /docs/agent//flow/tasks/migrate/from-promtail.md" [clustering]: "/docs/agent/ -> /docs/agent//flow/concepts/clustering/_index.md" [clustering]: "/docs/grafana-cloud/ -> /docs/agent//flow/concepts/clustering/_index.md" [rules]: "/docs/agent/ -> /docs/agent/latest/flow/reference/components/mimir.rules.kubernetes.md" diff --git a/docs/sources/flow/reference/cli/convert.md b/docs/sources/flow/reference/cli/convert.md index 833341b47752..a9a3810ec3ee 100644 --- a/docs/sources/flow/reference/cli/convert.md +++ b/docs/sources/flow/reference/cli/convert.md @@ -82,7 +82,7 @@ This includes Prometheus features such as and many supported *_sd_configs. Unsupported features in a source configuration result in [errors]. -Refer to [Migrate from Prometheus to {{< param "PRODUCT_NAME" >}}]({{< relref "../../tasks/migrating-from-prometheus/" >}}) for a detailed migration guide. +Refer to [Migrate from Prometheus to {{< param "PRODUCT_NAME" >}}]({{< relref "../../tasks/migrate/from-prometheus/" >}}) for a detailed migration guide. ### Promtail @@ -96,7 +96,7 @@ are supported and can be converted to {{< param "PRODUCT_NAME" >}} configuration If you have unsupported features in a source configuration, you will receive [errors] when you convert to a flow configuration. The converter will also raise warnings for configuration options that may require your attention. -Refer to [Migrate from Promtail to {{< param "PRODUCT_NAME" >}}]({{< relref "../../tasks/migrating-from-promtail/" >}}) for a detailed migration guide. +Refer to [Migrate from Promtail to {{< param "PRODUCT_NAME" >}}]({{< relref "../../tasks/migrate/from-promtail/" >}}) for a detailed migration guide. ### Static @@ -113,4 +113,4 @@ flags with a space between each flag, for example `--extra-args="-enable-feature If you have unsupported features in a Static mode source configuration, you will receive [errors][] when you convert to a Flow mode configuration. The converter will also raise warnings for configuration options that may require your attention. -Refer to [Migrate from Grafana Agent Static to {{< param "PRODUCT_NAME" >}}]({{< relref "../../tasks/migrating-from-static/" >}}) for a detailed migration guide. \ No newline at end of file +Refer to [Migrate from Grafana Agent Static to {{< param "PRODUCT_NAME" >}}]({{< relref "../../tasks/migrate/from-static/" >}}) for a detailed migration guide. \ No newline at end of file diff --git a/docs/sources/flow/tasks/migrate/_index.md b/docs/sources/flow/tasks/migrate/_index.md new file mode 100644 index 000000000000..a0c98966dcb4 --- /dev/null +++ b/docs/sources/flow/tasks/migrate/_index.md @@ -0,0 +1,19 @@ +--- +aliases: +- /docs/grafana-cloud/agent/flow/tasks/migrate/ +- /docs/grafana-cloud/monitor-infrastructure/agent/flow/tasks/migrate/ +- /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/tasks/migrate/ +- /docs/grafana-cloud/send-data/agent/flow/tasks/migrate/ +canonical: https://grafana.com/docs/agent/latest/flow/tasks/migrate/ +description: How to migrate to Grafana Agent Flow +menuTitle: Migrate +title: Migrate to Grafana Agent Flow +weight: 100 +--- + +# How to migrate to {{% param "PRODUCT_NAME" %}} + +This section details how to migrate to {{< param "PRODUCT_NAME" >}} from other +common solutions. + +{{< section >}} diff --git a/docs/sources/flow/tasks/migrating-from-operator.md b/docs/sources/flow/tasks/migrate/from-operator.md similarity index 97% rename from docs/sources/flow/tasks/migrating-from-operator.md rename to docs/sources/flow/tasks/migrate/from-operator.md index 375ffec59e51..1e942a2da941 100644 --- a/docs/sources/flow/tasks/migrating-from-operator.md +++ b/docs/sources/flow/tasks/migrate/from-operator.md @@ -1,19 +1,19 @@ --- aliases: -- /docs/grafana-cloud/monitor-infrastructure/agent/flow/tasks/migrating-from-operator/ -- /docs/grafana-cloud/send-data/agent/flow/tasks/migrating-from-operator/ +- /docs/grafana-cloud/monitor-infrastructure/agent/flow/tasks/migrate/from-operator/ +- /docs/grafana-cloud/send-data/agent/flow/tasks/migrate/from-operator/ # Previous page aliases for backwards compatibility: - /docs/grafana-cloud/monitor-infrastructure/agent/flow/getting-started/migrating-from-operator/ - /docs/grafana-cloud/send-data/agent/flow/getting-started/migrating-from-operator/ - ../getting-started/migrating-from-operator/ # /docs/agent/latest/flow/getting-started/migrating-from-operator/ -canonical: https://grafana.com/docs/agent/latest/flow/tasks/migrating-from-operator/ -description: Migrating from Grafana Agent Operator to Grafana Agent Flow +canonical: https://grafana.com/docs/agent/latest/flow/tasks/migrate/from-operator/ +description: Migrate from Grafana Agent Operator to Grafana Agent Flow menuTitle: Migrate from Operator -title: Migrating from Grafana Agent Operator to Grafana Agent Flow +title: Migrate from Grafana Agent Operator to Grafana Agent Flow weight: 320 --- -# Migrating from Grafana Agent Operator to {{% param "PRODUCT_NAME" %}} +# Migrate from Grafana Agent Operator to {{% param "PRODUCT_NAME" %}} With the release of {{< param "PRODUCT_NAME" >}}, Grafana Agent Operator is no longer the recommended way to deploy {{< param "PRODUCT_ROOT_NAME" >}} in Kubernetes. Some of the Operator functionality has moved into {{< param "PRODUCT_NAME" >}} itself, and the Helm Chart has replaced the remaining functionality. diff --git a/docs/sources/flow/tasks/migrating-from-prometheus.md b/docs/sources/flow/tasks/migrate/from-prometheus.md similarity index 98% rename from docs/sources/flow/tasks/migrating-from-prometheus.md rename to docs/sources/flow/tasks/migrate/from-prometheus.md index 837ca9da1e07..74a53f2475c5 100644 --- a/docs/sources/flow/tasks/migrating-from-prometheus.md +++ b/docs/sources/flow/tasks/migrate/from-prometheus.md @@ -1,16 +1,16 @@ --- aliases: -- /docs/grafana-cloud/agent/flow/tasks/migrating-from-prometheus/ -- /docs/grafana-cloud/monitor-infrastructure/agent/flow/tasks/migrating-from-prometheus/ -- /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/tasks/migrating-from-prometheus/ -- /docs/grafana-cloud/send-data/agent/flow/tasks/migrating-from-prometheus/ +- /docs/grafana-cloud/agent/flow/tasks/migrate/from-prometheus/ +- /docs/grafana-cloud/monitor-infrastructure/agent/flow/tasks/migrate/from-prometheus/ +- /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/tasks/migrate/from-prometheus/ +- /docs/grafana-cloud/send-data/agent/flow/tasks/migrate/from-prometheus/ # Previous page aliases for backwards compatibility: - /docs/grafana-cloud/agent/flow/getting-started/migrating-from-prometheus/ - /docs/grafana-cloud/monitor-infrastructure/agent/flow/getting-started/migrating-from-prometheus/ - /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/getting-started/migrating-from-prometheus/ - /docs/grafana-cloud/send-data/agent/flow/getting-started/migrating-from-prometheus/ - ../getting-started/migrating-from-prometheus/ # /docs/agent/latest/flow/getting-started/migrating-from-prometheus/ -canonical: https://grafana.com/docs/agent/latest/flow/tasks/migrating-from-prometheus/ +canonical: https://grafana.com/docs/agent/latest/flow/tasks/migrate/from-prometheus/ description: Learn how to migrate from Prometheus to Grafana Agent Flow menuTitle: Migrate from Prometheus title: Migrate from Prometheus to Grafana Agent Flow diff --git a/docs/sources/flow/tasks/migrating-from-promtail.md b/docs/sources/flow/tasks/migrate/from-promtail.md similarity index 98% rename from docs/sources/flow/tasks/migrating-from-promtail.md rename to docs/sources/flow/tasks/migrate/from-promtail.md index d38e9b904697..89c863f8758f 100644 --- a/docs/sources/flow/tasks/migrating-from-promtail.md +++ b/docs/sources/flow/tasks/migrate/from-promtail.md @@ -1,16 +1,16 @@ --- aliases: -- /docs/grafana-cloud/agent/flow/tasks/migrating-from-promtail/ -- /docs/grafana-cloud/monitor-infrastructure/agent/flow/tasks/migrating-from-promtail/ -- /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/tasks/migrating-from-promtail/ -- /docs/grafana-cloud/send-data/agent/flow/tasks/migrating-from-promtail/ +- /docs/grafana-cloud/agent/flow/tasks/migrate/from-promtail/ +- /docs/grafana-cloud/monitor-infrastructure/agent/flow/tasks/migrate/from-promtail/ +- /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/tasks/migrate/from-promtail/ +- /docs/grafana-cloud/send-data/agent/flow/tasks/migrate/from-promtail/ # Previous page aliases for backwards compatibility: - /docs/grafana-cloud/agent/flow/getting-started/migrating-from-promtail/ - /docs/grafana-cloud/monitor-infrastructure/agent/flow/getting-started/migrating-from-promtail/ - /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/getting-started/migrating-from-promtail/ - /docs/grafana-cloud/send-data/agent/flow/getting-started/migrating-from-promtail/ - ../getting-started/migrating-from-promtail/ # /docs/agent/latest/flow/getting-started/migrating-from-promtail/ -canonical: https://grafana.com/docs/agent/latest/flow/tasks/migrating-from-promtail/ +canonical: https://grafana.com/docs/agent/latest/flow/tasks/migrate/from-promtail/ description: Learn how to migrate from Promtail to Grafana Agent Flow menuTitle: Migrate from Promtail title: Migrate from Promtail to Grafana Agent Flow diff --git a/docs/sources/flow/tasks/migrating-from-static.md b/docs/sources/flow/tasks/migrate/from-static.md similarity index 97% rename from docs/sources/flow/tasks/migrating-from-static.md rename to docs/sources/flow/tasks/migrate/from-static.md index a4033dab096a..bf8532f207d9 100644 --- a/docs/sources/flow/tasks/migrating-from-static.md +++ b/docs/sources/flow/tasks/migrate/from-static.md @@ -1,16 +1,16 @@ --- aliases: -- /docs/grafana-cloud/agent/flow/tasks/migrating-from-static/ -- /docs/grafana-cloud/monitor-infrastructure/agent/flow/tasks/migrating-from-static/ -- /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/tasks/migrating-from-static/ -- /docs/grafana-cloud/send-data/agent/flow/tasks/migrating-from-static/ +- /docs/grafana-cloud/agent/flow/tasks/migrate/from-static/ +- /docs/grafana-cloud/monitor-infrastructure/agent/flow/tasks/migrate/from-static/ +- /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/tasks/migrate/from-static/ +- /docs/grafana-cloud/send-data/agent/flow/tasks/migrate/from-static/ # Previous page aliases for backwards compatibility: - /docs/grafana-cloud/agent/flow/getting-started/migrating-from-static/ - /docs/grafana-cloud/monitor-infrastructure/agent/flow/getting-started/migrating-from-static/ - /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/getting-started/migrating-from-static/ - /docs/grafana-cloud/send-data/agent/flow/getting-started/migrating-from-static/ - ../getting-started/migrating-from-static/ # /docs/agent/latest/flow/getting-started/migrating-from-static/ -canonical: https://grafana.com/docs/agent/latest/flow/tasks/migrating-from-static/ +canonical: https://grafana.com/docs/agent/latest/flow/tasks/migrate/from-static/ description: Learn how to migrate your configuration from Grafana Agent Static to Grafana Agent Flow menuTitle: Migrate from Static to Flow title: Migrate Grafana Agent Static to Grafana Agent Flow @@ -388,10 +388,10 @@ The following list is specific to the convert command and not {{< param "PRODUCT [Agent Management]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/static/configuration/agent-management.md" [env]: "/docs/agent/ -> /docs/agent//flow/reference/stdlib/env.md" [env]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/reference/stdlib/env.md" -[Prometheus Limitations]: "/docs/agent/ -> /docs/agent//flow/tasks/migrating-from-prometheus.md#limitations" -[Prometheus Limitations]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/tasks/migrating-from-prometheus.md#limitations" -[Promtail Limitations]: "/docs/agent/ -> /docs/agent//flow/tasks/migrating-from-promtail.md#limitations" -[Promtail Limitations]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/tasks/migrating-from-promtail.md#limitations" +[Prometheus Limitations]: "/docs/agent/ -> /docs/agent//flow/tasks/migrate/from-prometheus.md#limitations" +[Prometheus Limitations]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/tasks/migrate/from-prometheus.md#limitations" +[Promtail Limitations]: "/docs/agent/ -> /docs/agent//flow/tasks/migrate/from-promtail.md#limitations" +[Promtail Limitations]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/tasks/migrate/from-promtail.md#limitations" [Metrics]: "/docs/agent/ -> /docs/agent//static/configuration/metrics-config.md" [Metrics]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/static/configuration/metrics-config.md" [Logs]: "/docs/agent/ -> /docs/agent//static/configuration/logs-config.md" From 0b25b5fdca2526ca4d4341c5484a55085f155ef9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Tudur=C3=AD?= Date: Fri, 5 Jan 2024 15:40:28 +0100 Subject: [PATCH 08/68] Add `sample_age_limit` to remote_write config to drop old samples (#6052) --- CHANGELOG.md | 1 + component/prometheus/remotewrite/types.go | 3 +++ .../prometheusconvert/component/remote_write.go | 1 + .../testdata-v2/integrations_v2.river | 2 +- .../staticconvert/testdata-v2/unsupported.river | 2 +- .../testdata/prom_remote_write.river | 16 ++++++++-------- .../staticconvert/testdata/prom_scrape.river | 3 ++- .../staticconvert/testdata/prom_scrape.yaml | 1 + .../staticconvert/testdata/promtail_prom.river | 2 +- .../staticconvert/testdata/sanitize.river | 2 +- .../staticconvert/testdata/unsupported.river | 4 ++-- .../components/prometheus.remote_write.md | 5 +++++ go.mod | 12 ++++++++++-- go.sum | 12 ++++++------ 14 files changed, 43 insertions(+), 23 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4d008e4ab023..47d9a28c0716 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -82,6 +82,7 @@ Main (unreleased) - Add support for `http_sd_config` within a `scrape_config` for prometheus to flow config conversion. (@erikbaranowski) - `discovery.lightsail` now supports additional parameters for configuring HTTP client settings. (@ptodev) +- Add `sample_age_limit` to remote_write config to drop samples older than a specified duration. (@marctc) ### Bugfixes diff --git a/component/prometheus/remotewrite/types.go b/component/prometheus/remotewrite/types.go index 473a2928e246..637059aba416 100644 --- a/component/prometheus/remotewrite/types.go +++ b/component/prometheus/remotewrite/types.go @@ -35,6 +35,7 @@ var ( MinBackoff: 30 * time.Millisecond, MaxBackoff: 5 * time.Second, RetryOnHTTP429: true, + SampleAgeLimit: 0, } DefaultMetadataOptions = MetadataOptions{ @@ -141,6 +142,7 @@ type QueueOptions struct { MinBackoff time.Duration `river:"min_backoff,attr,optional"` MaxBackoff time.Duration `river:"max_backoff,attr,optional"` RetryOnHTTP429 bool `river:"retry_on_http_429,attr,optional"` + SampleAgeLimit time.Duration `river:"sample_age_limit,attr,optional"` } // SetToDefault implements river.Defaulter. @@ -164,6 +166,7 @@ func (r *QueueOptions) toPrometheusType() config.QueueConfig { MinBackoff: model.Duration(r.MinBackoff), MaxBackoff: model.Duration(r.MaxBackoff), RetryOnRateLimit: r.RetryOnHTTP429, + SampleAgeLimit: model.Duration(r.SampleAgeLimit), } } diff --git a/converter/internal/prometheusconvert/component/remote_write.go b/converter/internal/prometheusconvert/component/remote_write.go index 4756f84d6674..37c4c6814a04 100644 --- a/converter/internal/prometheusconvert/component/remote_write.go +++ b/converter/internal/prometheusconvert/component/remote_write.go @@ -96,6 +96,7 @@ func toQueueOptions(queueConfig *prom_config.QueueConfig) *remotewrite.QueueOpti MinBackoff: time.Duration(queueConfig.MinBackoff), MaxBackoff: time.Duration(queueConfig.MaxBackoff), RetryOnHTTP429: queueConfig.RetryOnRateLimit, + SampleAgeLimit: time.Duration(queueConfig.SampleAgeLimit), } } diff --git a/converter/internal/staticconvert/testdata-v2/integrations_v2.river b/converter/internal/staticconvert/testdata-v2/integrations_v2.river index d6306565d9e2..919af1b47286 100644 --- a/converter/internal/staticconvert/testdata-v2/integrations_v2.river +++ b/converter/internal/staticconvert/testdata-v2/integrations_v2.river @@ -1,6 +1,6 @@ prometheus.remote_write "metrics_default" { endpoint { - name = "default-8be96f" + name = "default-149bbd" url = "http://localhost:9009/api/prom/push" queue_config { } diff --git a/converter/internal/staticconvert/testdata-v2/unsupported.river b/converter/internal/staticconvert/testdata-v2/unsupported.river index 0dcdb9ac79a6..c9585a88c5dc 100644 --- a/converter/internal/staticconvert/testdata-v2/unsupported.river +++ b/converter/internal/staticconvert/testdata-v2/unsupported.river @@ -1,6 +1,6 @@ prometheus.remote_write "metrics_default" { endpoint { - name = "default-8be96f" + name = "default-149bbd" url = "http://localhost:9009/api/prom/push" queue_config { } diff --git a/converter/internal/staticconvert/testdata/prom_remote_write.river b/converter/internal/staticconvert/testdata/prom_remote_write.river index bc9edcd50834..2d341fed6a5b 100644 --- a/converter/internal/staticconvert/testdata/prom_remote_write.river +++ b/converter/internal/staticconvert/testdata/prom_remote_write.river @@ -1,6 +1,6 @@ prometheus.remote_write "metrics_test1" { endpoint { - name = "test1-8be96f" + name = "test1-149bbd" url = "http://localhost:9009/api/prom/push" queue_config { } @@ -11,7 +11,7 @@ prometheus.remote_write "metrics_test1" { prometheus.remote_write "metrics_test2" { endpoint { - name = "test2-533083" + name = "test2-c6d55a" url = "http://localhost:9010/api/prom/push" send_exemplars = false @@ -23,7 +23,7 @@ prometheus.remote_write "metrics_test2" { prometheus.remote_write "metrics_test3" { endpoint { - name = "test3-a3c419" + name = "test3-aa96fd" url = "http://localhost:9011/api/prom/push" queue_config { } @@ -32,7 +32,7 @@ prometheus.remote_write "metrics_test3" { } endpoint { - name = "test3-41df1c" + name = "test3-a93240" url = "http://localhost:9012/api/prom/push" queue_config { @@ -45,7 +45,7 @@ prometheus.remote_write "metrics_test3" { prometheus.remote_write "metrics_test4_sigv4_defaults" { endpoint { - name = "test4_sigv4_defaults-c42e88" + name = "test4_sigv4_defaults-f815bf" url = "http://localhost:9012/api/prom/push" queue_config { } @@ -58,7 +58,7 @@ prometheus.remote_write "metrics_test4_sigv4_defaults" { prometheus.remote_write "metrics_test5_sigv4_explicit" { endpoint { - name = "test5_sigv4_explicit-050ad5" + name = "test5_sigv4_explicit-bc8fca" url = "http://localhost:9012/api/prom/push" queue_config { } @@ -77,7 +77,7 @@ prometheus.remote_write "metrics_test5_sigv4_explicit" { prometheus.remote_write "metrics_test6_azuread_defaults" { endpoint { - name = "test6_azuread_defaults-fbed02" + name = "test6_azuread_defaults-cc4e7e" url = "http://localhost:9012/api/prom/push" queue_config { } @@ -94,7 +94,7 @@ prometheus.remote_write "metrics_test6_azuread_defaults" { prometheus.remote_write "metrics_test7_azuread_explicit" { endpoint { - name = "test7_azuread_explicit-416842" + name = "test7_azuread_explicit-9e1a3e" url = "http://localhost:9012/api/prom/push" queue_config { } diff --git a/converter/internal/staticconvert/testdata/prom_scrape.river b/converter/internal/staticconvert/testdata/prom_scrape.river index e73fd76733e3..f0afe395531e 100644 --- a/converter/internal/staticconvert/testdata/prom_scrape.river +++ b/converter/internal/staticconvert/testdata/prom_scrape.river @@ -91,7 +91,7 @@ prometheus.relabel "metrics_agent_promobee" { prometheus.remote_write "metrics_agent" { endpoint { - name = "agent-6ea089" + name = "agent-36127e" url = "https://prometheus-us-central1.grafana.net/api/prom/push" basic_auth { @@ -103,6 +103,7 @@ prometheus.remote_write "metrics_agent" { max_shards = 10 batch_send_deadline = "3m0s" max_backoff = "10s" + sample_age_limit = "50s" } metadata_config { } diff --git a/converter/internal/staticconvert/testdata/prom_scrape.yaml b/converter/internal/staticconvert/testdata/prom_scrape.yaml index b81e865ef5d0..afffa13a2054 100644 --- a/converter/internal/staticconvert/testdata/prom_scrape.yaml +++ b/converter/internal/staticconvert/testdata/prom_scrape.yaml @@ -19,6 +19,7 @@ metrics: batch_send_deadline: 3m max_shards: 10 max_backoff: 10s + sample_age_limit: 50s basic_auth: username: 11111 password: my-secret-password-here diff --git a/converter/internal/staticconvert/testdata/promtail_prom.river b/converter/internal/staticconvert/testdata/promtail_prom.river index e31469f5267b..1744d37aee5c 100644 --- a/converter/internal/staticconvert/testdata/promtail_prom.river +++ b/converter/internal/staticconvert/testdata/promtail_prom.river @@ -18,7 +18,7 @@ prometheus.scrape "metrics_name_jobName" { prometheus.remote_write "metrics_name" { endpoint { - name = "name-8be96f" + name = "name-149bbd" url = "http://localhost:9009/api/prom/push" queue_config { } diff --git a/converter/internal/staticconvert/testdata/sanitize.river b/converter/internal/staticconvert/testdata/sanitize.river index 1bf214eda874..eaacf45291b6 100644 --- a/converter/internal/staticconvert/testdata/sanitize.river +++ b/converter/internal/staticconvert/testdata/sanitize.river @@ -1,6 +1,6 @@ prometheus.remote_write "metrics_integrations" { endpoint { - name = "integrations-717d0f" + name = "integrations-ce3432" url = "https://region.grafana.net/api/prom/push" basic_auth { diff --git a/converter/internal/staticconvert/testdata/unsupported.river b/converter/internal/staticconvert/testdata/unsupported.river index 8c0909bb6c7f..76923a6c7f06 100644 --- a/converter/internal/staticconvert/testdata/unsupported.river +++ b/converter/internal/staticconvert/testdata/unsupported.river @@ -8,7 +8,7 @@ prometheus.scrape "metrics_agent_prometheus" { prometheus.remote_write "metrics_agent" { endpoint { - name = "agent-d885f6" + name = "agent-eea444" url = "https://prometheus-us-central1.grafana.net/api/prom/push" queue_config { } @@ -41,7 +41,7 @@ prometheus.scrape "integrations_statsd_exporter" { prometheus.remote_write "integrations" { endpoint { - name = "agent-d885f6" + name = "agent-eea444" url = "https://prometheus-us-central1.grafana.net/api/prom/push" queue_config { } diff --git a/docs/sources/flow/reference/components/prometheus.remote_write.md b/docs/sources/flow/reference/components/prometheus.remote_write.md index 6348b7b9c3ff..f869343e0919 100644 --- a/docs/sources/flow/reference/components/prometheus.remote_write.md +++ b/docs/sources/flow/reference/components/prometheus.remote_write.md @@ -165,6 +165,7 @@ Name | Type | Description | Default | Required `min_backoff` | `duration` | Initial retry delay. The backoff time gets doubled for each retry. | `"30ms"` | no `max_backoff` | `duration` | Maximum retry delay. | `"5s"` | no `retry_on_http_429` | `bool` | Retry when an HTTP 429 status code is received. | `true` | no +`sample_age_limit` | `duration` | Maximum age of samples to send. | `"0s"` | no Each queue then manages a number of concurrent _shards_ which is responsible for sending a fraction of data to their respective endpoints. The number of @@ -191,6 +192,10 @@ responses should be treated as recoverable errors; other `HTTP 4xx` status code responses are never considered recoverable errors. When `retry_on_http_429` is enabled, `Retry-After` response headers from the servers are honored. +The `sample_age_limit` argument specifies the maximum age of samples to send. Any +samples older than the limit are dropped and won't be sent to the remote storage. +The default value is `0s`, which means that all samples are sent (feature is disabled). + ### metadata_config block Name | Type | Description | Default | Required diff --git a/go.mod b/go.mod index f8d9059376ab..852050ec69a0 100644 --- a/go.mod +++ b/go.mod @@ -142,7 +142,7 @@ require ( github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.66.0 github.com/prometheus-operator/prometheus-operator/pkg/client v0.66.0 github.com/prometheus/blackbox_exporter v0.24.1-0.20230623125439-bd22efa1c900 - github.com/prometheus/client_golang v1.17.0 + github.com/prometheus/client_golang v1.18.0 github.com/prometheus/client_model v0.5.0 github.com/prometheus/common v0.45.0 github.com/prometheus/consul_exporter v0.8.0 @@ -216,7 +216,7 @@ require ( golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa golang.org/x/net v0.18.0 golang.org/x/oauth2 v0.13.0 - golang.org/x/sys v0.14.1-0.20231108175955-e4099bfacb8c + golang.org/x/sys v0.15.0 golang.org/x/text v0.14.0 golang.org/x/time v0.3.0 google.golang.org/api v0.147.0 @@ -677,6 +677,14 @@ replace ( k8s.io/klog/v2 => github.com/simonpasquier/klog-gokit/v3 v3.3.0 ) +// TODO(marctc): remove replace directive once: +// +// * There is a release of Prometheus which contains +// prometheus/prometheus#13002 +// We use the last v1-related tag as the replace statement does not work for v2 +// tags without the v2 suffix to the module root. +replace github.com/prometheus/prometheus => github.com/grafana/prometheus v1.8.2-0.20240105105355-3e2c486167d2 // grafana/prometheus@drop-old-inmemory-samples-squashed-2 + replace gopkg.in/yaml.v2 => github.com/rfratto/go-yaml v0.0.0-20211119180816-77389c3526dc // Replace directives from Loki diff --git a/go.sum b/go.sum index d966bfea9876..410e895a31bd 100644 --- a/go.sum +++ b/go.sum @@ -1080,6 +1080,8 @@ github.com/grafana/opentelemetry-collector/service v0.0.0-20231018134914-c0109e0 github.com/grafana/opentelemetry-collector/service v0.0.0-20231018134914-c0109e052230/go.mod h1:kBdpzrqR2wJkOdg50yzp4dv+2XBMyeqTgF4lCx0hSpQ= github.com/grafana/postgres_exporter v0.8.1-0.20210722175051-db35d7c2f520 h1:HnFWqxhoSF3WC7sKAdMZ+SRXvHLVZlZ3sbQjuUlTqkw= github.com/grafana/postgres_exporter v0.8.1-0.20210722175051-db35d7c2f520/go.mod h1:+HPXgiOV0InDHcZ2jNijL1SOKvo0eEPege5fQA0+ICI= +github.com/grafana/prometheus v1.8.2-0.20240105105355-3e2c486167d2 h1:eJD8U9G91ID/pKsLjJnjqve8yv1NiE/l6dGYnwchPVM= +github.com/grafana/prometheus v1.8.2-0.20240105105355-3e2c486167d2/go.mod h1:SRw624aMAxTfryAcP8rOjg4S/sHHaetx2lyJJ2nM83g= github.com/grafana/pyroscope-go/godeltaprof v0.1.3 h1:eunWpv1B3Z7ZK9o4499EmQGlY+CsDmSZ4FbxjRx37uk= github.com/grafana/pyroscope-go/godeltaprof v0.1.3/go.mod h1:1HSPtjU8vLG0jE9JrTdzjgFqdJ/VgN7fvxBNq3luJko= github.com/grafana/pyroscope/api v0.2.0 h1:TzOxL0s6SiaLEy944ZAKgHcx/JDRJXu4O8ObwkqR6p4= @@ -1957,8 +1959,8 @@ github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqr github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ= -github.com/prometheus/client_golang v1.17.0 h1:rl2sfwZMtSthVU752MqfjQozy7blglC+1SOtjMAMh+Q= -github.com/prometheus/client_golang v1.17.0/go.mod h1:VeL+gMmOAxkS2IqfCq0ZmHSL+LjWfWDUmp1mBz9JgUY= +github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk= +github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA= github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= @@ -2010,8 +2012,6 @@ github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1 github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= -github.com/prometheus/prometheus v0.48.1 h1:CTszphSNTXkuCG6O0IfpKdHcJkvvnAAE1GbELKS+NFk= -github.com/prometheus/prometheus v0.48.1/go.mod h1:SRw624aMAxTfryAcP8rOjg4S/sHHaetx2lyJJ2nM83g= github.com/prometheus/snmp_exporter v0.24.1 h1:AihTbJHurMo8bjtjJde8U+4gMEvpvYvT21Xbd4SzJgY= github.com/prometheus/snmp_exporter v0.24.1/go.mod h1:j6uIGkdR0DXvKn7HJtSkeDj//UY0sWmdd6XhvdBjln0= github.com/prometheus/statsd_exporter v0.22.7/go.mod h1:N/TevpjkIh9ccs6nuzY3jQn9dFqnUakOjnEuMPJJJnI= @@ -2807,8 +2807,8 @@ golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.14.1-0.20231108175955-e4099bfacb8c h1:3kC/TjQ+xzIblQv39bCOyRk8fbEeJcDHwbyxPUU2BpA= -golang.org/x/sys v0.14.1-0.20231108175955-e4099bfacb8c/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= +golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= 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/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= From c246cf896ce497d2821b4e18116e5b1493d3b199 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Tudur=C3=AD?= Date: Fri, 5 Jan 2024 16:22:02 +0100 Subject: [PATCH 09/68] Update version to v0.39.0-rc.0 (#6053) --- CHANGELOG.md | 3 +++ docs/sources/_index.md | 2 +- pkg/operator/defaults.go | 2 +- tools/gen-versioned-files/agent-version.txt | 2 +- 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 47d9a28c0716..f72d18c9f49f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,9 @@ internal API changes are not present. Main (unreleased) ----------------- +v0.39.0-rc.0 (2024-01-05) +------------------------- + ### Breaking changes - `otelcol.receiver.prometheus` will drop all `otel_scope_info` metrics when converting them to OTLP. (@wildum) diff --git a/docs/sources/_index.md b/docs/sources/_index.md index e12c414c491e..1a7a2a261874 100644 --- a/docs/sources/_index.md +++ b/docs/sources/_index.md @@ -9,7 +9,7 @@ title: Grafana Agent description: Grafana Agent is a flexible, performant, vendor-neutral, telemetry collector weight: 350 cascade: - AGENT_RELEASE: v0.38.1 + AGENT_RELEASE: v0.39.0-rc.0 OTEL_VERSION: v0.87.0 --- diff --git a/pkg/operator/defaults.go b/pkg/operator/defaults.go index b66cfb52289b..a518d884b0b1 100644 --- a/pkg/operator/defaults.go +++ b/pkg/operator/defaults.go @@ -2,7 +2,7 @@ package operator // Supported versions of the Grafana Agent. var ( - DefaultAgentVersion = "v0.38.1" + DefaultAgentVersion = "v0.39.0-rc.0" DefaultAgentBaseImage = "grafana/agent" DefaultAgentImage = DefaultAgentBaseImage + ":" + DefaultAgentVersion ) diff --git a/tools/gen-versioned-files/agent-version.txt b/tools/gen-versioned-files/agent-version.txt index b4a466a81031..f02ec0731bfa 100644 --- a/tools/gen-versioned-files/agent-version.txt +++ b/tools/gen-versioned-files/agent-version.txt @@ -1 +1 @@ -v0.38.1 +v0.39.0-rc.0 From c467eff70e899833e5cebe64299c34e5af303bde Mon Sep 17 00:00:00 2001 From: Christophe van de Kerchove Date: Fri, 5 Jan 2024 11:07:42 -0500 Subject: [PATCH 10/68] feat: Allow user to add service account labels (#6022) This can be useful to use OIDC required labels for grafana-agent to authenticate to services. For example, Azure Workload Identity requires a labels to set additional labels on the service account for it to function properly. Co-authored-by: christophe.vandekerchove --- .../helm/charts/grafana-agent/CHANGELOG.md | 2 + .../helm/charts/grafana-agent/README.md | 1 + ...dditional-serviceaccount-label-values.yaml | 3 + .../templates/serviceaccount.yaml | 3 + .../helm/charts/grafana-agent/values.yaml | 2 + .../grafana-agent/templates/configmap.yaml | 42 +++++++ .../templates/controllers/daemonset.yaml | 73 +++++++++++ .../grafana-agent/templates/rbac.yaml | 117 ++++++++++++++++++ .../grafana-agent/templates/service.yaml | 22 ++++ .../templates/serviceaccount.yaml | 13 ++ 10 files changed, 278 insertions(+) create mode 100644 operations/helm/charts/grafana-agent/ci/additional-serviceaccount-label-values.yaml create mode 100644 operations/helm/tests/additional-serviceaccount-label/grafana-agent/templates/configmap.yaml create mode 100644 operations/helm/tests/additional-serviceaccount-label/grafana-agent/templates/controllers/daemonset.yaml create mode 100644 operations/helm/tests/additional-serviceaccount-label/grafana-agent/templates/rbac.yaml create mode 100644 operations/helm/tests/additional-serviceaccount-label/grafana-agent/templates/service.yaml create mode 100644 operations/helm/tests/additional-serviceaccount-label/grafana-agent/templates/serviceaccount.yaml diff --git a/operations/helm/charts/grafana-agent/CHANGELOG.md b/operations/helm/charts/grafana-agent/CHANGELOG.md index d14525031740..8752c007df6f 100644 --- a/operations/helm/charts/grafana-agent/CHANGELOG.md +++ b/operations/helm/charts/grafana-agent/CHANGELOG.md @@ -14,6 +14,8 @@ Unreleased - Update `rbac` to include necessary rules for the `otelcol.processor.k8sattributes` component. (@rlankfo) +- Add `serviceAccount.additionalLabels` to values.yaml to enable setting additional labels on the created service account. (@zopanix) + ### Bugfixes - Statefulset should use value `.controller.enableStatefulSetAutoDeletePVC` instead of just `.enableStatefulSetAutoDeletePVC`. (@captncraig) diff --git a/operations/helm/charts/grafana-agent/README.md b/operations/helm/charts/grafana-agent/README.md index 1839e56ed202..76aea9536d92 100644 --- a/operations/helm/charts/grafana-agent/README.md +++ b/operations/helm/charts/grafana-agent/README.md @@ -118,6 +118,7 @@ use the older mode (called "static mode"), set the `agent.mode` value to | service.clusterIP | string | `""` | Cluster IP, can be set to None, empty "" or an IP address | | service.enabled | bool | `true` | Creates a Service for the controller's pods. | | service.type | string | `"ClusterIP"` | Service type | +| serviceAccount.additionalLabels | object | `{}` | Additional labels to add to the created service account. | | serviceAccount.annotations | object | `{}` | Annotations to add to the created service account. | | serviceAccount.create | bool | `true` | Whether to create a service account for the Grafana Agent deployment. | | serviceAccount.name | string | `nil` | The name of the existing service account to use when serviceAccount.create is false. | diff --git a/operations/helm/charts/grafana-agent/ci/additional-serviceaccount-label-values.yaml b/operations/helm/charts/grafana-agent/ci/additional-serviceaccount-label-values.yaml new file mode 100644 index 000000000000..91b7cbb7c258 --- /dev/null +++ b/operations/helm/charts/grafana-agent/ci/additional-serviceaccount-label-values.yaml @@ -0,0 +1,3 @@ +serviceAccount: + additionalLabels: + test: "true" diff --git a/operations/helm/charts/grafana-agent/templates/serviceaccount.yaml b/operations/helm/charts/grafana-agent/templates/serviceaccount.yaml index 8f4c8477a7d5..766201635e77 100644 --- a/operations/helm/charts/grafana-agent/templates/serviceaccount.yaml +++ b/operations/helm/charts/grafana-agent/templates/serviceaccount.yaml @@ -5,6 +5,9 @@ metadata: name: {{ include "grafana-agent.serviceAccountName" . }} labels: {{- include "grafana-agent.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} {{- with .Values.serviceAccount.annotations }} annotations: {{- toYaml . | nindent 4 }} diff --git a/operations/helm/charts/grafana-agent/values.yaml b/operations/helm/charts/grafana-agent/values.yaml index 7b80e68618e6..dd94b3b09118 100644 --- a/operations/helm/charts/grafana-agent/values.yaml +++ b/operations/helm/charts/grafana-agent/values.yaml @@ -115,6 +115,8 @@ rbac: serviceAccount: # -- Whether to create a service account for the Grafana Agent deployment. create: true + # -- Additional labels to add to the created service account. + additionalLabels: {} # -- Annotations to add to the created service account. annotations: {} # -- The name of the existing service account to use when diff --git a/operations/helm/tests/additional-serviceaccount-label/grafana-agent/templates/configmap.yaml b/operations/helm/tests/additional-serviceaccount-label/grafana-agent/templates/configmap.yaml new file mode 100644 index 000000000000..2fdc6f011777 --- /dev/null +++ b/operations/helm/tests/additional-serviceaccount-label/grafana-agent/templates/configmap.yaml @@ -0,0 +1,42 @@ +--- +# Source: grafana-agent/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: grafana-agent + labels: + helm.sh/chart: grafana-agent + app.kubernetes.io/name: grafana-agent + app.kubernetes.io/instance: grafana-agent + app.kubernetes.io/version: "vX.Y.Z" + app.kubernetes.io/managed-by: Helm +data: + config.river: |- + logging { + level = "info" + format = "logfmt" + } + + discovery.kubernetes "pods" { + role = "pod" + } + + discovery.kubernetes "nodes" { + role = "node" + } + + discovery.kubernetes "services" { + role = "service" + } + + discovery.kubernetes "endpoints" { + role = "endpoints" + } + + discovery.kubernetes "endpointslices" { + role = "endpointslice" + } + + discovery.kubernetes "ingresses" { + role = "ingress" + } diff --git a/operations/helm/tests/additional-serviceaccount-label/grafana-agent/templates/controllers/daemonset.yaml b/operations/helm/tests/additional-serviceaccount-label/grafana-agent/templates/controllers/daemonset.yaml new file mode 100644 index 000000000000..7ac89ceb865a --- /dev/null +++ b/operations/helm/tests/additional-serviceaccount-label/grafana-agent/templates/controllers/daemonset.yaml @@ -0,0 +1,73 @@ +--- +# Source: grafana-agent/templates/controllers/daemonset.yaml +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: grafana-agent + labels: + helm.sh/chart: grafana-agent + app.kubernetes.io/name: grafana-agent + app.kubernetes.io/instance: grafana-agent + app.kubernetes.io/version: "vX.Y.Z" + app.kubernetes.io/managed-by: Helm +spec: + minReadySeconds: 10 + selector: + matchLabels: + app.kubernetes.io/name: grafana-agent + app.kubernetes.io/instance: grafana-agent + template: + metadata: + labels: + app.kubernetes.io/name: grafana-agent + app.kubernetes.io/instance: grafana-agent + spec: + serviceAccountName: grafana-agent + containers: + - name: grafana-agent + image: docker.io/grafana/agent:v0.38.1 + imagePullPolicy: IfNotPresent + args: + - run + - /etc/agent/config.river + - --storage.path=/tmp/agent + - --server.http.listen-addr=0.0.0.0:80 + - --server.http.ui-path-prefix=/ + env: + - name: AGENT_MODE + value: flow + - name: AGENT_DEPLOY_MODE + value: "helm" + - name: HOSTNAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + ports: + - containerPort: 80 + name: http-metrics + readinessProbe: + httpGet: + path: /-/ready + port: 80 + initialDelaySeconds: 10 + timeoutSeconds: 1 + volumeMounts: + - name: config + mountPath: /etc/agent + - name: config-reloader + image: docker.io/jimmidyson/configmap-reload:v0.8.0 + args: + - --volume-dir=/etc/agent + - --webhook-url=http://localhost:80/-/reload + volumeMounts: + - name: config + mountPath: /etc/agent + resources: + requests: + cpu: 1m + memory: 5Mi + dnsPolicy: ClusterFirst + volumes: + - name: config + configMap: + name: grafana-agent diff --git a/operations/helm/tests/additional-serviceaccount-label/grafana-agent/templates/rbac.yaml b/operations/helm/tests/additional-serviceaccount-label/grafana-agent/templates/rbac.yaml new file mode 100644 index 000000000000..3765583fb64f --- /dev/null +++ b/operations/helm/tests/additional-serviceaccount-label/grafana-agent/templates/rbac.yaml @@ -0,0 +1,117 @@ +--- +# Source: grafana-agent/templates/rbac.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: grafana-agent + labels: + helm.sh/chart: grafana-agent + app.kubernetes.io/name: grafana-agent + app.kubernetes.io/instance: grafana-agent + app.kubernetes.io/version: "vX.Y.Z" + app.kubernetes.io/managed-by: Helm +rules: + # Rules which allow discovery.kubernetes to function. + - apiGroups: + - "" + - "discovery.k8s.io" + - "networking.k8s.io" + resources: + - endpoints + - endpointslices + - ingresses + - nodes + - nodes/proxy + - nodes/metrics + - pods + - services + verbs: + - get + - list + - watch + # Rules which allow loki.source.kubernetes and loki.source.podlogs to work. + - apiGroups: + - "" + resources: + - pods + - pods/log + - namespaces + verbs: + - get + - list + - watch + - apiGroups: + - "monitoring.grafana.com" + resources: + - podlogs + verbs: + - get + - list + - watch + # Rules which allow mimir.rules.kubernetes to work. + - apiGroups: ["monitoring.coreos.com"] + resources: + - prometheusrules + verbs: + - get + - list + - watch + - nonResourceURLs: + - /metrics + verbs: + - get + # Rules for prometheus.kubernetes.* + - apiGroups: ["monitoring.coreos.com"] + resources: + - podmonitors + - servicemonitors + - probes + verbs: + - get + - list + - watch + # Rules which allow eventhandler to work. + - apiGroups: + - "" + resources: + - events + verbs: + - get + - list + - watch + # needed for remote.kubernetes.* + - apiGroups: [""] + resources: + - "configmaps" + - "secrets" + verbs: + - get + - list + - watch + # needed for otelcol.processor.k8sattributes + - apiGroups: ["apps"] + resources: ["replicasets"] + verbs: ["get", "list", "watch"] + - apiGroups: ["extensions"] + resources: ["replicasets"] + verbs: ["get", "list", "watch"] +--- +# Source: grafana-agent/templates/rbac.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: grafana-agent + labels: + helm.sh/chart: grafana-agent + app.kubernetes.io/name: grafana-agent + app.kubernetes.io/instance: grafana-agent + app.kubernetes.io/version: "vX.Y.Z" + app.kubernetes.io/managed-by: Helm +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: grafana-agent +subjects: + - kind: ServiceAccount + name: grafana-agent + namespace: default diff --git a/operations/helm/tests/additional-serviceaccount-label/grafana-agent/templates/service.yaml b/operations/helm/tests/additional-serviceaccount-label/grafana-agent/templates/service.yaml new file mode 100644 index 000000000000..04f6eeff3c4d --- /dev/null +++ b/operations/helm/tests/additional-serviceaccount-label/grafana-agent/templates/service.yaml @@ -0,0 +1,22 @@ +--- +# Source: grafana-agent/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + name: grafana-agent + labels: + helm.sh/chart: grafana-agent + app.kubernetes.io/name: grafana-agent + app.kubernetes.io/instance: grafana-agent + app.kubernetes.io/version: "vX.Y.Z" + app.kubernetes.io/managed-by: Helm +spec: + type: ClusterIP + selector: + app.kubernetes.io/name: grafana-agent + app.kubernetes.io/instance: grafana-agent + ports: + - name: http-metrics + port: 80 + targetPort: 80 + protocol: "TCP" diff --git a/operations/helm/tests/additional-serviceaccount-label/grafana-agent/templates/serviceaccount.yaml b/operations/helm/tests/additional-serviceaccount-label/grafana-agent/templates/serviceaccount.yaml new file mode 100644 index 000000000000..ba80344cee51 --- /dev/null +++ b/operations/helm/tests/additional-serviceaccount-label/grafana-agent/templates/serviceaccount.yaml @@ -0,0 +1,13 @@ +--- +# Source: grafana-agent/templates/serviceaccount.yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + name: grafana-agent + labels: + helm.sh/chart: grafana-agent + app.kubernetes.io/name: grafana-agent + app.kubernetes.io/instance: grafana-agent + app.kubernetes.io/version: "vX.Y.Z" + app.kubernetes.io/managed-by: Helm + test: "true" From cbdfc8733c24405c3e5edaba63ab19f456d3b4a4 Mon Sep 17 00:00:00 2001 From: Craig Peterson <192540+captncraig@users.noreply.github.com> Date: Fri, 5 Jan 2024 12:10:25 -0500 Subject: [PATCH 11/68] create new helm release 0.30.0 (#6057) * create new helm release * gen --- operations/helm/charts/grafana-agent/CHANGELOG.md | 3 +++ operations/helm/charts/grafana-agent/Chart.yaml | 2 +- operations/helm/charts/grafana-agent/README.md | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/operations/helm/charts/grafana-agent/CHANGELOG.md b/operations/helm/charts/grafana-agent/CHANGELOG.md index 8752c007df6f..6603ab6fb063 100644 --- a/operations/helm/charts/grafana-agent/CHANGELOG.md +++ b/operations/helm/charts/grafana-agent/CHANGELOG.md @@ -10,6 +10,9 @@ internal API changes are not present. Unreleased ---------- +0.30.0 (2024-01-05) +------------------- + ### Enhancements - Update `rbac` to include necessary rules for the `otelcol.processor.k8sattributes` component. (@rlankfo) diff --git a/operations/helm/charts/grafana-agent/Chart.yaml b/operations/helm/charts/grafana-agent/Chart.yaml index 78630fed515d..45ab45dd8ba2 100644 --- a/operations/helm/charts/grafana-agent/Chart.yaml +++ b/operations/helm/charts/grafana-agent/Chart.yaml @@ -2,7 +2,7 @@ apiVersion: v2 name: grafana-agent description: 'Grafana Agent' type: application -version: 0.29.0 +version: 0.30.0 appVersion: 'v0.38.1' dependencies: diff --git a/operations/helm/charts/grafana-agent/README.md b/operations/helm/charts/grafana-agent/README.md index 76aea9536d92..98e4219d36b5 100644 --- a/operations/helm/charts/grafana-agent/README.md +++ b/operations/helm/charts/grafana-agent/README.md @@ -1,6 +1,6 @@ # Grafana Agent Helm chart -![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![Version: 0.29.0](https://img.shields.io/badge/Version-0.29.0-informational?style=flat-square) ![AppVersion: v0.38.1](https://img.shields.io/badge/AppVersion-v0.38.1-informational?style=flat-square) +![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![Version: 0.30.0](https://img.shields.io/badge/Version-0.30.0-informational?style=flat-square) ![AppVersion: v0.38.1](https://img.shields.io/badge/AppVersion-v0.38.1-informational?style=flat-square) Helm chart for deploying [Grafana Agent][] to Kubernetes. From c30cae4b6b9ed81d2f916007793ead7a771e8393 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=90=E1=BB=97=20Tr=E1=BB=8Dng=20H=E1=BA=A3i?= <41283691+hainenber@users.noreply.github.com> Date: Mon, 8 Jan 2024 16:51:32 +0700 Subject: [PATCH 12/68] chore(sec): fix vulns by bumping pkgs to patched ver (#6060) * chore(sec): fix vulns by bumping pkgs to patched ver Signed-off-by: hainenber * chore(doc): add CHANGELOG entry Signed-off-by: hainenber * fix(ci): accomodate func signature change Signed-off-by: hainenber --------- Signed-off-by: hainenber --- CHANGELOG.md | 6 + go.mod | 86 ++++----- go.sum | 232 ++++++++++++------------- pkg/integrations/mssql/sql_exporter.go | 4 + 4 files changed, 165 insertions(+), 163 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f72d18c9f49f..4496cb325474 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,12 @@ internal API changes are not present. Main (unreleased) ----------------- +### Security fixes +- Fixes following vulnerabilities (@hainenber) + - [GO-2023-2409](https://github.com/advisories/GHSA-mhpq-9638-x6pw) + - [GO-2023-2412](https://github.com/advisories/GHSA-7ww5-4wqc-m92c) + - [CVE-2023-49568](https://github.com/advisories/GHSA-mw99-9chc-xw7r) + v0.39.0-rc.0 (2024-01-05) ------------------------- diff --git a/go.mod b/go.mod index 852050ec69a0..071002b5e7c3 100644 --- a/go.mod +++ b/go.mod @@ -14,13 +14,13 @@ require ( github.com/alecthomas/kingpin/v2 v2.4.0 github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 github.com/aws/aws-sdk-go v1.45.25 - github.com/aws/aws-sdk-go-v2 v1.21.1 - github.com/aws/aws-sdk-go-v2/config v1.18.44 + github.com/aws/aws-sdk-go-v2 v1.24.0 + github.com/aws/aws-sdk-go-v2/config v1.26.2 github.com/aws/aws-sdk-go-v2/service/s3 v1.34.1 github.com/bmatcuk/doublestar v1.3.4 github.com/bufbuild/connect-go v1.10.0 github.com/buger/jsonparser v1.1.1 - github.com/burningalchemist/sql_exporter v0.0.0-20221222155641-2ff59aa75200 + github.com/burningalchemist/sql_exporter v0.0.0-20240103092044-466b38b6abc4 github.com/cespare/xxhash/v2 v2.2.0 github.com/cilium/ebpf v0.12.3 // indirect github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf @@ -34,10 +34,10 @@ require ( github.com/fortytw2/leaktest v1.3.0 github.com/fsnotify/fsnotify v1.6.0 github.com/github/smimesign v0.2.0 - github.com/go-git/go-git/v5 v5.4.2 + github.com/go-git/go-git/v5 v5.11.0 github.com/go-kit/log v0.2.1 github.com/go-logfmt/logfmt v0.6.0 - github.com/go-logr/logr v1.3.0 + github.com/go-logr/logr v1.4.1 github.com/go-sourcemap/sourcemap v2.1.3+incompatible github.com/go-sql-driver/mysql v1.7.1 github.com/gogo/protobuf v1.3.2 @@ -87,7 +87,7 @@ require ( github.com/jmespath/go-jmespath v0.4.0 github.com/json-iterator/go v1.1.12 github.com/klauspost/compress v1.17.3 - github.com/lib/pq v1.10.7 + github.com/lib/pq v1.10.9 github.com/mackerelio/go-osstat v0.2.3 github.com/miekg/dns v1.1.56 github.com/mitchellh/mapstructure v1.5.1-0.20220423185008-bf980b35cac4 @@ -212,16 +212,16 @@ require ( go.uber.org/goleak v1.2.1 go.uber.org/multierr v1.11.0 go.uber.org/zap v1.26.0 - golang.org/x/crypto v0.15.0 + golang.org/x/crypto v0.17.0 golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa - golang.org/x/net v0.18.0 + golang.org/x/net v0.19.0 golang.org/x/oauth2 v0.13.0 golang.org/x/sys v0.15.0 golang.org/x/text v0.14.0 golang.org/x/time v0.3.0 google.golang.org/api v0.147.0 google.golang.org/grpc v1.59.0 - google.golang.org/protobuf v1.31.0 + google.golang.org/protobuf v1.32.0 gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v3 v3.0.1 gotest.tools v2.2.0+incompatible @@ -271,8 +271,7 @@ require ( github.com/Microsoft/go-winio v0.6.1 // indirect github.com/Microsoft/hcsshim v0.11.4 // indirect github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5 // indirect - github.com/ProtonMail/go-crypto v0.0.0-20210920160938-87db9fbc61c7 // indirect - github.com/acomagu/bufpipe v1.0.3 // indirect + github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 // indirect github.com/alecthomas/participle/v2 v2.1.0 // indirect github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect github.com/andybalholm/brotli v1.0.5 // indirect @@ -283,21 +282,21 @@ require ( github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect github.com/avvmoto/buf-readerat v0.0.0-20171115124131-a17c8cb89270 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.10 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.13.42 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.12 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.16.13 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.10 // indirect github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.69 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.42 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.36 // indirect - github.com/aws/aws-sdk-go-v2/internal/ini v1.3.44 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.9 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.9 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.7.2 // indirect github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.26 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.11 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4 // indirect github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.29 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.36 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.9 // indirect github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.14.3 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.15.1 // indirect - github.com/aws/aws-sdk-go-v2/service/ssooidc v1.17.2 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.23.1 // indirect - github.com/aws/smithy-go v1.15.0 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.18.5 // indirect + github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.5 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.26.6 // indirect + github.com/aws/smithy-go v1.19.0 // indirect github.com/beevik/ntp v1.3.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver v3.5.2-0.20180723201105-3c1074078d32+incompatible // indirect @@ -313,7 +312,7 @@ require ( github.com/cncf/xds/go v0.0.0-20230607035331-e9ce68804cb4 // indirect github.com/containerd/cgroups v1.1.0 // indirect github.com/containerd/console v1.0.3 // indirect - github.com/containerd/containerd v1.7.6 // indirect + github.com/containerd/containerd v1.7.11 // indirect github.com/containerd/continuity v0.4.2 // indirect github.com/containerd/ttrpc v1.2.2 // indirect github.com/coreos/go-semver v0.3.1 // indirect @@ -332,7 +331,7 @@ require ( github.com/docker/distribution v2.8.2+incompatible // indirect github.com/docker/go-units v0.5.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect - github.com/dvsekhvalnov/jose2go v1.5.0 // indirect + github.com/dvsekhvalnov/jose2go v1.6.0 // indirect github.com/eapache/go-resiliency v1.4.0 // indirect github.com/eapache/go-xerial-snappy v0.0.0-20230731223053-c322873962e3 // indirect github.com/eapache/queue v1.1.0 // indirect @@ -342,7 +341,7 @@ require ( github.com/elastic/go-windows v1.0.1 // indirect github.com/ema/qdisc v1.0.0 // indirect github.com/emicklei/go-restful/v3 v3.11.0 // indirect - github.com/emirpasic/gods v1.12.0 // indirect + github.com/emirpasic/gods v1.18.1 // indirect github.com/envoyproxy/go-control-plane v0.11.1 // indirect github.com/envoyproxy/protoc-gen-validate v1.0.2 // indirect github.com/euank/go-kmsg-parser v2.0.0+incompatible // indirect @@ -354,8 +353,8 @@ require ( github.com/felixge/httpsnoop v1.0.3 // indirect github.com/form3tech-oss/jwt-go v3.2.5+incompatible // indirect github.com/gabriel-vasile/mimetype v1.4.2 // indirect - github.com/go-git/gcfg v1.5.0 // indirect - github.com/go-git/go-billy/v5 v5.3.1 // indirect + github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect + github.com/go-git/go-billy/v5 v5.5.0 // indirect github.com/go-kit/kit v0.13.0 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.3.0 // indirect @@ -379,7 +378,7 @@ require ( github.com/gogo/googleapis v1.4.1 // indirect github.com/gogo/status v1.1.1 // indirect github.com/golang-jwt/jwt/v4 v4.5.0 // indirect - github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe // indirect + github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 // indirect github.com/golang-sql/sqlexp v0.1.0 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/gomodule/redigo v1.8.9 // indirect @@ -428,13 +427,13 @@ require ( github.com/influxdata/telegraf v1.16.3 // indirect github.com/ionos-cloud/sdk-go/v6 v6.1.9 // indirect github.com/jackc/chunkreader/v2 v2.0.1 // indirect - github.com/jackc/pgconn v1.13.0 // indirect + github.com/jackc/pgconn v1.14.0 // indirect github.com/jackc/pgio v1.0.0 // indirect github.com/jackc/pgpassfile v1.0.0 // indirect - github.com/jackc/pgproto3/v2 v2.3.1 // indirect - github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b // indirect - github.com/jackc/pgtype v1.12.0 // indirect - github.com/jackc/pgx/v4 v4.17.2 // indirect + github.com/jackc/pgproto3/v2 v2.3.2 // indirect + github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect + github.com/jackc/pgtype v1.14.0 // indirect + github.com/jackc/pgx/v4 v4.18.1 // indirect github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect github.com/jcmturner/aescts/v2 v2.0.0 // indirect github.com/jcmturner/dnsutils/v2 v2.0.0 // indirect @@ -448,7 +447,7 @@ require ( github.com/jpillora/backoff v1.0.0 // indirect github.com/jsimonetti/rtnetlink v1.3.5 // indirect github.com/karrick/godirwalk v1.17.0 // indirect - github.com/kevinburke/ssh_config v1.1.0 // indirect + github.com/kevinburke/ssh_config v1.2.0 // indirect github.com/klauspost/asmfmt v1.3.2 // indirect github.com/klauspost/cpuid/v2 v2.2.5 // indirect github.com/knadh/koanf v1.5.0 // indirect @@ -470,7 +469,7 @@ require ( github.com/mdlayher/netlink v1.7.2 // indirect github.com/mdlayher/socket v0.4.1 // indirect github.com/mdlayher/wifi v0.1.0 // indirect - github.com/microsoft/go-mssqldb v0.19.0 // indirect + github.com/microsoft/go-mssqldb v1.6.0 // indirect github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect @@ -516,7 +515,7 @@ require ( github.com/prometheus-community/go-runit v0.1.0 // indirect github.com/prometheus/alertmanager v0.26.0 // indirect github.com/prometheus/common/sigv4 v0.1.0 - github.com/prometheus/exporter-toolkit v0.10.1-0.20230714054209-2f4150c63f97 // indirect + github.com/prometheus/exporter-toolkit v0.11.0 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect github.com/remeh/sizedwaitgroup v1.0.0 // indirect github.com/renier/xmlrpc v0.0.0-20170708154548-ce4a1a486c03 // indirect @@ -533,7 +532,7 @@ require ( github.com/shopspring/decimal v1.2.0 // indirect github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c // indirect github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546 // indirect - github.com/snowflakedb/gosnowflake v1.6.22 // indirect + github.com/snowflakedb/gosnowflake v1.7.2-0.20240103203018-f1d625f17408 // indirect github.com/softlayer/softlayer-go v0.0.0-20180806151055-260589d94c7d // indirect github.com/soheilhy/cmux v0.1.5 // indirect github.com/spf13/afero v1.9.5 // indirect @@ -551,14 +550,14 @@ require ( github.com/tklauser/numcpus v0.6.1 // indirect github.com/tomnomnom/linkheader v0.0.0-20180905144013-02ca5825eb80 // indirect github.com/uber/jaeger-lib v2.4.1+incompatible // indirect - github.com/vertica/vertica-sql-go v1.3.0 // indirect + github.com/vertica/vertica-sql-go v1.3.3 // indirect github.com/vishvananda/netlink v1.2.1-beta.2 // indirect github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f // indirect github.com/vmware/govmomi v0.32.0 // indirect github.com/vultr/govultr/v2 v2.17.2 // indirect github.com/willf/bitset v1.1.11 // indirect github.com/willf/bloom v2.0.3+incompatible // indirect - github.com/xanzy/ssh-agent v0.3.1 // indirect + github.com/xanzy/ssh-agent v0.3.3 // indirect github.com/xdg-go/pbkdf2 v1.0.0 // indirect github.com/xdg-go/stringprep v1.0.4 // indirect github.com/xdg/scram v0.0.0-20180814205039-7eeb5667e42c // indirect @@ -567,7 +566,7 @@ require ( github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xeipuuv/gojsonschema v1.2.0 // indirect github.com/xhit/go-str2duration/v2 v2.1.0 // indirect - github.com/xo/dburl v0.13.0 // indirect + github.com/xo/dburl v0.20.0 // indirect github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect github.com/yusufpapurcu/wmi v1.2.3 // indirect go.etcd.io/etcd/api/v3 v3.5.9 // indirect @@ -583,7 +582,7 @@ require ( go4.org/netipx v0.0.0-20230125063823-8449b0a6169f // indirect golang.org/x/mod v0.14.0 // indirect golang.org/x/sync v0.5.0 // indirect - golang.org/x/term v0.14.0 // indirect + golang.org/x/term v0.15.0 // indirect golang.org/x/tools v0.15.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect @@ -623,7 +622,10 @@ require ( github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/network/armnetwork/v2 v2.2.1 // indirect github.com/Shopify/sarama v1.38.1 // indirect github.com/Workiva/go-datastructures v1.1.0 // indirect + github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.26.0 // indirect github.com/channelmeter/iso8601duration v0.0.0-20150204201828-8da3af7a2a61 // indirect + github.com/cloudflare/circl v1.3.3 // indirect + github.com/containerd/log v0.1.0 // indirect github.com/drone/envsubst v1.0.3 // indirect github.com/go-jose/go-jose/v3 v3.0.1 // indirect github.com/golang-jwt/jwt/v5 v5.0.0 // indirect @@ -642,8 +644,10 @@ require ( github.com/open-telemetry/opentelemetry-collector-contrib/pkg/translator/prometheusremotewrite v0.87.0 // indirect github.com/openshift/api v3.9.0+incompatible // indirect github.com/openshift/client-go v0.0.0-20210521082421-73d9475a9142 // indirect + github.com/pjbgf/sha1cd v0.3.0 // indirect github.com/prometheus-community/prom-label-proxy v0.6.0 // indirect github.com/sercand/kuberesolver/v4 v4.0.0 // indirect + github.com/skeema/knownhosts v1.2.1 // indirect github.com/sony/gobreaker v0.5.0 // indirect github.com/tidwall/gjson v1.10.2 // indirect github.com/tidwall/match v1.1.1 // indirect diff --git a/go.sum b/go.sum index 410e895a31bd..b3f0d41a4a63 100644 --- a/go.sum +++ b/go.sum @@ -80,14 +80,10 @@ github.com/Azure/azure-pipeline-go v0.1.9/go.mod h1:XA1kFWRVhSK+KNFiOhfv83Fv8L9a github.com/Azure/azure-pipeline-go v0.2.3/go.mod h1:x841ezTBIMG6O3lAcl8ATHnsOPVl2bqk7S3ta6S6u4k= github.com/Azure/azure-sdk-for-go v36.2.0+incompatible h1:09cv2WoH0g6jl6m2iT+R9qcIPZKhXEL0sbmLhxP895s= github.com/Azure/azure-sdk-for-go v36.2.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.0.0/go.mod h1:uGG2W01BaETf0Ozp+QxxKJdMBNRWPdstHG0Fmdwn1/U= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.1.2/go.mod h1:uGG2W01BaETf0Ozp+QxxKJdMBNRWPdstHG0Fmdwn1/U= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.0-beta.1 h1:ODs3brnqQM99Tq1PffODpAViYv3Bf8zOg464MU7p5ew= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.9.0-beta.1/go.mod h1:3Ug6Qzto9anB6mGlEdgYMDF5zHQ+wwhEaYR4s17PHMw= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.1.0/go.mod h1:bhXu1AjYL+wutSL/kpSq6s7733q2Rb0yuot9Zgfqa/0= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0 h1:BMAjVKJM0U/CYF27gA0ZMmXGkOcvfFtD0oHVZ1TIPRI= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.4.0/go.mod h1:1fXstnBMas5kzG+S3q8UoJcmyU6nUeunJcMDHcRYHhs= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.0.0/go.mod h1:eWRD7oawr1Mu1sLCawqVc0CUiF43ia3qQMxLscsKQ9w= github.com/Azure/azure-sdk-for-go/sdk/internal v1.4.0 h1:TuEMD+E+1aTjjLICGQOW6vLe8UWES7kopac9mUXL56Y= github.com/Azure/azure-sdk-for-go/sdk/internal v1.4.0/go.mod h1:s4kgfzA0covAXNicZHDMN58jExvcng2mC/DepXiF1EI= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/compute/armcompute/v4 v4.2.1 h1:UPeCRD+XY7QlaGQte2EVI2iOcWvUYA2XY8w5T/8v0NQ= @@ -110,6 +106,10 @@ github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armsubscriptions github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armsubscriptions v1.2.0/go.mod h1:ThfyMjs6auYrWPnYJjI3H4H++oVPrz01pizpu8lfl3A= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.2.0 h1:Ma67P/GGprNwsslzEH6+Kb8nybI8jpDTm4Wmzu2ReK8= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/storage/armstorage v1.2.0/go.mod h1:c+Lifp3EDEamAkPVzMooRNOK6CZjNSdEnf1A7jsI9u4= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.0.0 h1:yfJe15aSwEQ6Oo6J+gdfdulPNoZ3TEhmbhLIoxZcA+U= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.0.0/go.mod h1:Q28U+75mpCaSCDowNEmhIo/rmgdkqmkmzI7N6TGR4UY= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v0.8.0 h1:T028gtTPiYt/RMUfs8nVsAL7FDQrfLlrm/NnRG/zcC4= +github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v0.8.0/go.mod h1:cw4zVQgBby0Z5f2v0itn6se2dDP17nTjbZFXW5uPyHA= github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.2.0 h1:gggzg0SUMs6SQbEw+3LoSsYf9YMjkupeAnHMX8O9mmY= github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v1.2.0/go.mod h1:+6KLcKIVgxoBDMqMO/Nvy7bZ9a0nbU3I1DtFQK3YvB4= github.com/Azure/azure-storage-queue-go v0.0.0-20181215014128-6ed74e755687/go.mod h1:K6am8mT+5iFXgingS9LUc7TmbsW6XBw3nxaRyaMyWc8= @@ -172,7 +172,6 @@ github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZ github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk= github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo= github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= -github.com/AzureAD/microsoft-authentication-library-for-go v0.5.1/go.mod h1:Vt9sXTKwMyGcOxSmLDMnGPgqsUg7m8pe215qMLrDXw4= github.com/AzureAD/microsoft-authentication-library-for-go v1.2.0 h1:hVeq+yCyUi+MsoO/CU95yqCIcdzra5ovzk8Q2BBpV2M= github.com/AzureAD/microsoft-authentication-library-for-go v1.2.0/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= @@ -210,10 +209,8 @@ github.com/Mellanox/rdmamap v0.0.0-20191106181932-7c3c4763a6ee/go.mod h1:jDA6v0T github.com/Microsoft/ApplicationInsights-Go v0.4.2/go.mod h1:CukZ/G66zxXtI+h/VcVn3eVVDGDHfXM2zVILF7bMmsg= github.com/Microsoft/go-winio v0.4.3/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= github.com/Microsoft/go-winio v0.4.9/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= -github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= -github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= -github.com/Microsoft/go-winio v0.5.0/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= github.com/Microsoft/go-winio v0.5.1/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= +github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/Microsoft/hcsshim v0.11.4 h1:68vKo2VN8DE9AdN4tnkWnmdhqdbpUFM8OF3Airm7fz8= @@ -225,9 +222,8 @@ github.com/Nvveen/Gotty v0.0.0-20120604004816-cd527374f1e5/go.mod h1:lmUJ/7eu/Q8 github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8= github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= -github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo= -github.com/ProtonMail/go-crypto v0.0.0-20210920160938-87db9fbc61c7 h1:DSqTh6nEes/uO8BlNcGk8PzZsxY2sN9ZL//veWBdTRI= -github.com/ProtonMail/go-crypto v0.0.0-20210920160938-87db9fbc61c7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo= +github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371 h1:kkhsdkhsCvIsutKu5zLMgWtgh9YxGCNAw8Ad8hjwfYg= +github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/rehttp v1.1.0 h1:JFZ7OeK+hbJpTxhNB0NDZT47AuXqCU0Smxfjtph7/Rs= @@ -252,8 +248,6 @@ github.com/Workiva/go-datastructures v1.1.0 h1:hu20UpgZneBhQ3ZvwiOGlqJSKIosin2Rd github.com/Workiva/go-datastructures v1.1.0/go.mod h1:1yZL+zfsztete+ePzZz/Zb1/t5BnDuE2Ya2MMGhzP6A= github.com/abdullin/seq v0.0.0-20160510034733-d5467c17e7af h1:DBNMBMuMiWYu0b+8KMJuWmfCkcxl09JwdlqwDZZ6U14= github.com/abdullin/seq v0.0.0-20160510034733-d5467c17e7af/go.mod h1:5Jv4cbFiHJMsVxt52+i0Ha45fjshj6wxYr1r19tB9bw= -github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk= -github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4= github.com/aerospike/aerospike-client-go v1.27.0/go.mod h1:zj8LBEnWBDOVEIJt8LvaRvDG5ARAoa5dBeHaB472NRc= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= @@ -281,8 +275,8 @@ github.com/alicebob/miniredis/v2 v2.30.4/go.mod h1:b25qWj4fCEsBeAAR2mlb0ufImGC6u github.com/amir/raidman v0.0.0-20170415203553-1ccc43bfb9c9/go.mod h1:eliMa/PW+RDr2QLWRmLH1R1ZA4RInpmvOzDDXtaIZkc= github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs= github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig= -github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA= -github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c= +github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= +github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/antonmedv/expr v1.15.3 h1:q3hOJZNvLvhqE8OHBs1cFRdbXFNKuA+bHmRaI+AmRmI= github.com/antonmedv/expr v1.15.3/go.mod h1:0E/6TxnOlRNp81GMzX9QfDPAmHo2Phg00y4JUv1ihsE= @@ -326,34 +320,34 @@ github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZw github.com/aws/aws-sdk-go-v2 v1.7.0/go.mod h1:tb9wi5s61kTDA5qCkcDbt3KRVV74GGslQkl/DRdX/P4= github.com/aws/aws-sdk-go-v2 v1.9.2/go.mod h1:cK/D0BBs0b/oWPIcX/Z/obahJK1TT7IPVjy53i/mX/4= github.com/aws/aws-sdk-go-v2 v1.18.1/go.mod h1:uzbQtefpm44goOPmdKyAlXSNcwlRgF3ePWVW6EtJvvw= -github.com/aws/aws-sdk-go-v2 v1.21.1 h1:wjHYshtPpYOZm+/mu3NhVgRRc0baM6LJZOmxPZ5Cwzs= -github.com/aws/aws-sdk-go-v2 v1.21.1/go.mod h1:ErQhvNuEMhJjweavOYhxVkn2RUx7kQXVATHrjKtxIpM= +github.com/aws/aws-sdk-go-v2 v1.24.0 h1:890+mqQ+hTpNuw0gGP6/4akolQkSToDJgHfQE7AwGuk= +github.com/aws/aws-sdk-go-v2 v1.24.0/go.mod h1:LNh45Br1YAkEKaAqvmE1m8FUx6a5b/V0oAKV7of29b4= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.10 h1:dK82zF6kkPeCo8J1e+tGx4JdvDIQzj7ygIoLg8WMuGs= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.10/go.mod h1:VeTZetY5KRJLuD/7fkQXMU6Mw7H5m/KP2J5Iy9osMno= github.com/aws/aws-sdk-go-v2/config v1.8.3/go.mod h1:4AEiLtAb8kLs7vgw2ZV3p2VZ1+hBavOc84hqxVNpCyw= github.com/aws/aws-sdk-go-v2/config v1.18.27/go.mod h1:0My+YgmkGxeqjXZb5BYme5pc4drjTnM+x1GJ3zv42Nw= -github.com/aws/aws-sdk-go-v2/config v1.18.44 h1:U10NQ3OxiY0dGGozmVIENIDnCT0W432PWxk2VO8wGnY= -github.com/aws/aws-sdk-go-v2/config v1.18.44/go.mod h1:pHxnQBldd0heEdJmolLBk78D1Bf69YnKLY3LOpFImlU= +github.com/aws/aws-sdk-go-v2/config v1.26.2 h1:+RWLEIWQIGgrz2pBPAUoGgNGs1TOyF4Hml7hCnYj2jc= +github.com/aws/aws-sdk-go-v2/config v1.26.2/go.mod h1:l6xqvUxt0Oj7PI/SUXYLNyZ9T/yBPn3YTQcJLLOdtR8= github.com/aws/aws-sdk-go-v2/credentials v1.4.3/go.mod h1:FNNC6nQZQUuyhq5aE5c7ata8o9e4ECGmS4lAXC7o1mQ= github.com/aws/aws-sdk-go-v2/credentials v1.13.26/go.mod h1:GoXt2YC8jHUBbA4jr+W3JiemnIbkXOfxSXcisUsZ3os= -github.com/aws/aws-sdk-go-v2/credentials v1.13.42 h1:KMkjpZqcMOwtRHChVlHdNxTUUAC6NC/b58mRZDIdcRg= -github.com/aws/aws-sdk-go-v2/credentials v1.13.42/go.mod h1:7ltKclhvEB8305sBhrpls24HGxORl6qgnQqSJ314Uw8= +github.com/aws/aws-sdk-go-v2/credentials v1.16.13 h1:WLABQ4Cp4vXtXfOWOS3MEZKr6AAYUpMczLhgKtAjQ/8= +github.com/aws/aws-sdk-go-v2/credentials v1.16.13/go.mod h1:Qg6x82FXwW0sJHzYruxGiuApNo31UEtJvXVSZAXeWiw= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.6.0/go.mod h1:gqlclDEZp4aqJOancXK6TN24aKhT0W0Ae9MHk3wzTMM= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.4/go.mod h1:E1hLXN/BL2e6YizK1zFlYd8vsfi2GTjbjBazinMmeaM= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.12 h1:3j5lrl9kVQrJ1BU4O0z7MQ8sa+UXdiLuo4j0V+odNI8= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.12/go.mod h1:JbFpcHDBdsex1zpIKuVRorZSQiZEyc3MykNCcjgz174= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.10 h1:w98BT5w+ao1/r5sUuiH6JkVzjowOKeOJRHERyy1vh58= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.14.10/go.mod h1:K2WGI7vUvkIv1HoNbfBA1bvIZ+9kL3YVmWxeKuLQsiw= github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.69 h1:u9tquzvPabbR1hghIq0+snSCYPeF9jA7JeB46iazH6w= github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.69/go.mod h1:KzrYE4t9hLh8TjJkfGsmPYcVlYb7QWiPPv3aCOhwms0= github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.34/go.mod h1:wZpTEecJe0Btj3IYnDx/VlUzor9wm3fJHyvLpQF0VwY= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.42 h1:817VqVe6wvwE46xXy6YF5RywvjOX6U2zRQQ6IbQFK0s= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.42/go.mod h1:oDfgXoBBmj+kXnqxDDnIDnC56QBosglKp8ftRCTxR+0= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.9 h1:v+HbZaCGmOwnTTVS86Fleq0vPzOd7tnJGbFhP0stNLs= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.2.9/go.mod h1:Xjqy+Nyj7VDLBtCMkQYOw1QYfAEZCVLrfI0ezve8wd4= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.28/go.mod h1:7VRpKQQedkfIEXb4k52I7swUnZP0wohVajJMRn3vsUw= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.36 h1:7ZApaXzWbo8slc+W5TynuUlB4z66g44h7uqa3/d/BsY= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.36/go.mod h1:rwr4WnmFi3RJO0M4dxbJtgi9BPLMpVBMX1nUte5ha9U= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.9 h1:N94sVhRACtXyVcjXxrwK1SKFIJrA9pOJ5yu2eSHnmls= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.5.9/go.mod h1:hqamLz7g1/4EJP+GH5NBhcUMLjW+gKLQabgyz6/7WAU= github.com/aws/aws-sdk-go-v2/internal/ini v1.2.4/go.mod h1:ZcBrrI3zBKlhGFNYWvju0I3TR93I7YIgAfy82Fh4lcQ= github.com/aws/aws-sdk-go-v2/internal/ini v1.3.35/go.mod h1:0Eg1YjxE0Bhn56lx+SHJwCzhW+2JGtizsrx+lCqrfm0= -github.com/aws/aws-sdk-go-v2/internal/ini v1.3.44 h1:quOJOqlbSfeJTboXLjYXM1M9T52LBXqLoTPlmsKLpBo= -github.com/aws/aws-sdk-go-v2/internal/ini v1.3.44/go.mod h1:LNy+P1+1LiRcCsVYr/4zG5n8zWFL0xsvZkOybjbftm8= +github.com/aws/aws-sdk-go-v2/internal/ini v1.7.2 h1:GrSw8s0Gs/5zZ0SX+gX4zQjRnRsMJDJ2sLur1gRBhEM= +github.com/aws/aws-sdk-go-v2/internal/ini v1.7.2/go.mod h1:6fQQgfuGmw8Al/3M2IgIllycxV7ZW7WCdVSqfBeUiCY= github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.26 h1:wscW+pnn3J1OYnanMnza5ZVYXLX4cKk5rAvUAl4Qu+c= github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.26/go.mod h1:MtYiox5gvyB+OyP0Mr0Sm/yzbEAIPL9eijj/ouHAPw0= github.com/aws/aws-sdk-go-v2/service/amp v1.17.5 h1:Wg2vTVYrMrfkNqrCGaggQq1UBdzgrAsorAfavLNpU/E= @@ -370,40 +364,43 @@ github.com/aws/aws-sdk-go-v2/service/databasemigrationservice v1.30.4 h1:Ir8BEej github.com/aws/aws-sdk-go-v2/service/databasemigrationservice v1.30.4/go.mod h1:NSAyKko0rDkrZOjcdCPPvMEe+FyIw/aDDQ8X+xAIW44= github.com/aws/aws-sdk-go-v2/service/ec2 v1.117.0 h1:Yq39vbwQX+Xw+Ubcsg/ElwO+TWAxAIAdrREtpjGnCHw= github.com/aws/aws-sdk-go-v2/service/ec2 v1.117.0/go.mod h1:0FhI2Rzcv5BNM3dNnbcCx2qa2naFZoAidJi11cQgzL0= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.11 h1:y2+VQzC6Zh2ojtV2LoC0MNwHWc6qXv/j2vrQtlftkdA= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.11/go.mod h1:iV4q2hsqtNECrfmlXyord9u4zyuFEJX9eLgLpSPzWA8= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4 h1:/b31bi3YVNlkzkBrm9LfpaKoaYZUxIAj4sHfOTmLfqw= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.10.4/go.mod h1:2aGXHFmbInwgP9ZfpmdIfOELL79zhdNYNmReK8qDfdQ= github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.29 h1:zZSLP3v3riMOP14H7b4XP0uyfREDQOYv2cqIrvTXDNQ= github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.29/go.mod h1:z7EjRjVwZ6pWcWdI2H64dKttvzaP99jRIj5hphW0M5U= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.3.2/go.mod h1:72HRZDLMtmVQiLG2tLfQcaWLCssELvGl+Zf2WVxMmR8= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.28/go.mod h1:jj7znCIg05jXlaGBlFMGP8+7UN3VtCkRBG2spnmRQkU= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.36 h1:YXlm7LxwNlauqb2OrinWlcvtsflTzP8GaMvYfQBhoT4= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.36/go.mod h1:ou9ffqJ9hKOVZmjlC6kQ6oROAyG1M4yBKzR+9BKbDwk= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.9 h1:Nf2sHxjMJR8CSImIVCONRi4g0Su3J+TSTbS7G0pUeMU= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.10.9/go.mod h1:idky4TER38YIjr2cADF1/ugFMKvZV7p//pVeV5LZbF0= github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.14.3 h1:dBL3StFxHtpBzJJ/mNEsjXVgfO+7jR0dAIEwLqMapEA= github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.14.3/go.mod h1:f1QyiAsvIv4B49DmCqrhlXqyaR+0IxMmyX+1P+AnzOM= github.com/aws/aws-sdk-go-v2/service/resourcegroupstaggingapi v1.15.5 h1:dMsTYzhTpsDMY79IzCh/jq1tHRwgfa15ujhKUjZk0fg= github.com/aws/aws-sdk-go-v2/service/resourcegroupstaggingapi v1.15.5/go.mod h1:Lh/6ABs1m80bEB36fAW9gEPW5kSsAr7Mdn8dGyWRLp0= github.com/aws/aws-sdk-go-v2/service/s3 v1.34.1 h1:rYYwwsGqbwvGgQHjBkqgDt8MynXk+I8xgS0IEj5gOT0= github.com/aws/aws-sdk-go-v2/service/s3 v1.34.1/go.mod h1:aVbf0sko/TsLWHx30c/uVu7c62+0EAJ3vbxaJga0xCw= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.26.0 h1:dPCRgAL4WD9tSMaDglRNGOiAtSTjkwNiUW5GDpWFfHA= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.26.0/go.mod h1:4Ae1NCLK6ghmjzd45Tc33GgCKhUWD2ORAlULtMO1Cbs= github.com/aws/aws-sdk-go-v2/service/shield v1.19.5 h1:zX/1OHVjTNB2D1xiQ0pByYNLbVgbl84fTj5W4tMKdAk= github.com/aws/aws-sdk-go-v2/service/shield v1.19.5/go.mod h1:NKqcE1DkD5YSbTAR8MxhFGFDmSkGNo68/Q8hht3Mi5w= github.com/aws/aws-sdk-go-v2/service/sso v1.4.2/go.mod h1:NBvT9R1MEF+Ud6ApJKM0G+IkPchKS7p7c2YPKwHmBOk= github.com/aws/aws-sdk-go-v2/service/sso v1.12.12/go.mod h1:HuCOxYsF21eKrerARYO6HapNeh9GBNq7fius2AcwodY= -github.com/aws/aws-sdk-go-v2/service/sso v1.15.1 h1:ZN3bxw9OYC5D6umLw6f57rNJfGfhg1DIAAcKpzyUTOE= -github.com/aws/aws-sdk-go-v2/service/sso v1.15.1/go.mod h1:PieckvBoT5HtyB9AsJRrYZFY2Z+EyfVM/9zG6gbV8DQ= +github.com/aws/aws-sdk-go-v2/service/sso v1.18.5 h1:ldSFWz9tEHAwHNmjx2Cvy1MjP5/L9kNoR0skc6wyOOM= +github.com/aws/aws-sdk-go-v2/service/sso v1.18.5/go.mod h1:CaFfXLYL376jgbP7VKC96uFcU8Rlavak0UlAwk1Dlhc= github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.12/go.mod h1:E4VrHCPzmVB/KFXtqBGKb3c8zpbNBgKe3fisDNLAW5w= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.17.2 h1:fSCCJuT5i6ht8TqGdZc5Q5K9pz/atrf7qH4iK5C9XzU= -github.com/aws/aws-sdk-go-v2/service/ssooidc v1.17.2/go.mod h1:5eNtr+vNc5vVd92q7SJ+U/HszsIdhZBEyi9dkMRKsp8= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.5 h1:2k9KmFawS63euAkY4/ixVNsYYwrwnd5fIvgEKkfZFNM= +github.com/aws/aws-sdk-go-v2/service/ssooidc v1.21.5/go.mod h1:W+nd4wWDVkSUIox9bacmkBP5NMFQeTJ/xqNabpzSR38= github.com/aws/aws-sdk-go-v2/service/storagegateway v1.19.6 h1:DfxHxomSOVAmiYb4I1IkcrKtjFrm4EHUEw/oHPuNgxI= github.com/aws/aws-sdk-go-v2/service/storagegateway v1.19.6/go.mod h1:o3x7HLasCY8mN914V4611sbXPOE54V8t0pzCtz5bxQ0= github.com/aws/aws-sdk-go-v2/service/sts v1.7.2/go.mod h1:8EzeIqfWt2wWT4rJVu3f21TfrhJ8AEMzVybRNSb/b4g= github.com/aws/aws-sdk-go-v2/service/sts v1.19.2/go.mod h1:dp0yLPsLBOi++WTxzCjA/oZqi6NPIhoR+uF7GeMU9eg= -github.com/aws/aws-sdk-go-v2/service/sts v1.23.1 h1:ASNYk1ypWAxRhJjKS0jBnTUeDl7HROOpeSMu1xDA/I8= -github.com/aws/aws-sdk-go-v2/service/sts v1.23.1/go.mod h1:2cnsAhVT3mqusovc2stUSUrSBGTcX9nh8Tu6xh//2eI= +github.com/aws/aws-sdk-go-v2/service/sts v1.26.6 h1:HJeiuZ2fldpd0WqngyMR6KW7ofkXNLyOaHwEIGm39Cs= +github.com/aws/aws-sdk-go-v2/service/sts v1.26.6/go.mod h1:XX5gh4CB7wAs4KhcF46G6C8a2i7eupU19dcAAE+EydU= github.com/aws/smithy-go v1.5.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E= github.com/aws/smithy-go v1.8.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E= github.com/aws/smithy-go v1.13.5/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= -github.com/aws/smithy-go v1.15.0 h1:PS/durmlzvAFpQHDs4wi4sNNP9ExsqZh6IlfdHXgKK8= -github.com/aws/smithy-go v1.15.0/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= +github.com/aws/smithy-go v1.19.0 h1:KWFKQV80DpP3vJrrA9sVAHQ5gc2z8i4EzrLhLlWXcBM= +github.com/aws/smithy-go v1.19.0/go.mod h1:NukqUGpCZIILqqiV0NIjeFh24kd/FAa4beRb6nbIUPE= github.com/aybabtme/iocontrol v0.0.0-20150809002002-ad15bcfc95a0 h1:0NmehRCgyk5rljDQLKUO+cRJCnduDyn11+zGZIc9Z48= github.com/aybabtme/iocontrol v0.0.0-20150809002002-ad15bcfc95a0/go.mod h1:6L7zgvqo0idzI7IO8de6ZC051AfXb5ipkIJ7bIA2tGA= github.com/basgys/goxml2json v1.1.0 h1:4ln5i4rseYfXNd86lGEB+Vi652IsIXIvggKM/BhUKVw= @@ -439,8 +436,9 @@ github.com/bufbuild/connect-go v1.10.0 h1:QAJ3G9A1OYQW2Jbk3DeoJbkCxuKArrvZgDt47m github.com/bufbuild/connect-go v1.10.0/go.mod h1:CAIePUgkDR5pAFaylSMtNK45ANQjp9JvpluG20rhpV8= github.com/buger/jsonparser v1.1.1 h1:2PnMjfWD7wBILjqQbt530v576A/cAbQvEW9gGIpYMUs= github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= -github.com/burningalchemist/sql_exporter v0.0.0-20221222155641-2ff59aa75200 h1:1zECtssRshqhP8+DELKyWeg8rxaRC5OO72kJQhrJOE8= -github.com/burningalchemist/sql_exporter v0.0.0-20221222155641-2ff59aa75200/go.mod h1:76BPyhi77q3CgH4ZcgW91r0+34cRMpORDnjlf0CmWpk= +github.com/burningalchemist/sql_exporter v0.0.0-20240103092044-466b38b6abc4 h1:dgjwrjeVe90AeMhrx04TmDKjZe7xqKKEUxT3QKNx9RU= +github.com/burningalchemist/sql_exporter v0.0.0-20240103092044-466b38b6abc4/go.mod h1:aRr7CZ/KleZpcDkQVsNeXE1BFT3xRG8baUHJ7J+j8NI= +github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= github.com/c2h5oh/datasize v0.0.0-20200112174442-28bbd4740fee h1:BnPxIde0gjtTnc9Er7cxvBk8DHLWhEux0SxayC8dP6I= github.com/c2h5oh/datasize v0.0.0-20200112174442-28bbd4740fee/go.mod h1:S/7n9copUssQ56c7aAgHqftWO4LTf4xY6CGWt8Bc+3M= github.com/caio/go-tdigest v2.3.0+incompatible/go.mod h1:sHQM/ubZStBUmF1WbB8FAm8q9GjDajLC5T7ydxE3JHI= @@ -482,6 +480,8 @@ github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp github.com/cisco-ie/nx-telemetry-proto v0.0.0-20190531143454-82441e232cf6/go.mod h1:ugEfq4B8T8ciw/h5mCkgdiDRFS4CkqqhH2dymDB4knc= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs= +github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58 h1:F1EaeKL/ta07PY/k9Os/UFtwERei2/XzGemhpGnBKNg= github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58/go.mod h1:EOBUe0h4xcZ5GoxqC5SDxFQ8gwyZPKQoEzownBlhI80= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= @@ -501,12 +501,14 @@ github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8a github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw= github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= github.com/containerd/containerd v1.4.1/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= -github.com/containerd/containerd v1.7.6 h1:oNAVsnhPoy4BTPQivLgTzI9Oleml9l/+eYIDYXRCYo8= -github.com/containerd/containerd v1.7.6/go.mod h1:SY6lrkkuJT40BVNO37tlYTSnKJnP5AXBc0fhx0q+TJ4= +github.com/containerd/containerd v1.7.11 h1:lfGKw3eU35sjV0aG2eYZTiwFEY1pCzxdzicHP3SZILw= +github.com/containerd/containerd v1.7.11/go.mod h1:5UluHxHTX2rdvYuZ5OJTC5m/KJNs0Zs9wVoJm9zf5ZE= github.com/containerd/continuity v0.0.0-20181203112020-004b46473808/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/containerd/continuity v0.0.0-20190827140505-75bee3e2ccb6/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= github.com/containerd/continuity v0.4.2 h1:v3y/4Yz5jwnvqPKJJ+7Wf93fyWoCB3F5EclWG023MDM= github.com/containerd/continuity v0.4.2/go.mod h1:F6PTNCKepoxEaXLQp3wDAjygEnImnZ/7o4JzpodfroQ= +github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I= +github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo= github.com/containerd/ttrpc v1.2.2 h1:9vqZr0pxwOF5koz6N0N3kJ0zDHokrcPxIR/ZR2YFtOs= github.com/containerd/ttrpc v1.2.2/go.mod h1:sIT6l32Ph/H9cvnJsfXM5drIVzTr5A2flTf1G5tYZak= github.com/containerd/typeurl v1.0.2 h1:Chlt8zIieDbzQFzXzAeBEF92KhExuE4p9p92/QmY7aY= @@ -576,7 +578,6 @@ github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQ github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi/U= github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE= github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= -github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko= github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI= github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= github.com/docker/cli v20.10.11+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= @@ -608,8 +609,8 @@ github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:Htrtb github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= -github.com/dvsekhvalnov/jose2go v1.5.0 h1:3j8ya4Z4kMCwT5nXIKFSV84YS+HdqSSO0VsTQxaLAeM= -github.com/dvsekhvalnov/jose2go v1.5.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= +github.com/dvsekhvalnov/jose2go v1.6.0 h1:Y9gnSnP4qEI0+/uQkHvFXeD2PLPJeXEL+ySMEA2EjTY= +github.com/dvsekhvalnov/jose2go v1.6.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-resiliency v1.2.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= github.com/eapache/go-resiliency v1.4.0 h1:3OK9bWpPk5q6pbFAaYSEwD9CLUSHG8bnZuqX2yMt3B0= @@ -633,14 +634,16 @@ github.com/elastic/go-windows v1.0.1/go.mod h1:FoVvqWSun28vaDQPbj2Elfc0JahhPB7WQ github.com/elazarl/go-bindata-assetfs v0.0.0-20160803192304-e1a2a7ec64b0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4= github.com/elazarl/goproxy v0.0.0-20170405201442-c4fc26588b6e/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= +github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a h1:mATvB/9r/3gvcejNsXKSkQ6lcIaNec2nyfOdlTBR2lU= +github.com/elazarl/goproxy v0.0.0-20230808193330-2592e75ae04a/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM= github.com/ema/qdisc v1.0.0 h1:EHLG08FVRbWLg8uRICa3xzC9Zm0m7HyMHfXobWFnXYg= github.com/ema/qdisc v1.0.0/go.mod h1:FhIc0fLYi7f+lK5maMsesDqwYojIOh3VfRs8EVd5YJQ= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful/v3 v3.11.0 h1:rAQeMHw1c7zTmncogyy8VvRZwtkmkZ4FxERmMY4rD+g= github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= -github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg= -github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= +github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= +github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/envoyproxy/go-control-plane v0.0.0-20180919002855-2137d9196328/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= @@ -683,7 +686,6 @@ github.com/felixge/fgprof v0.9.3 h1:VvyZxILNuCiUCSXtPtYmmtGvb65nqXh2QFWc0Wpf2/g= github.com/felixge/fgprof v0.9.3/go.mod h1:RdbpDgzqYVh/T9fPELJyV7EYJuHB55UTEULNun8eiPw= github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/form3tech-oss/jwt-go v3.2.5+incompatible h1:/l4kBbb4/vGSsdtB5nUe8L7B9mImVMaBPw9L/0TBHU8= @@ -709,19 +711,18 @@ github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeME github.com/ghodss/yaml v1.0.1-0.20190212211648-25d852aebe32/go.mod h1:GIjDIg/heH5DOkXY3YJ/wNhfHsQHoXGjl8G8amsYQ1I= github.com/githubexporter/github-exporter v0.0.0-20231025122338-656e7dc33fe7 h1:wT/4jrX36BHZMjkpPYrCY4lJR+HHG7L+cC0M3p5letQ= github.com/githubexporter/github-exporter v0.0.0-20231025122338-656e7dc33fe7/go.mod h1:q49R4E4fu+HqGnSSSFpAuJIMm8DV5YNhKBW/Ke9SBPE= -github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0= -github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= +github.com/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY= +github.com/gliderlabs/ssh v0.3.5/go.mod h1:8XB4KraRrX39qHhT6yxPsHedjA08I/uBVwj4xC+/+z4= github.com/glinton/ping v0.1.4-0.20200311211934-5ac87da8cd96/go.mod h1:uY+1eqFUyotrQxF1wYFNtMeHp/swbYRsoGzfcPZ8x3o= github.com/go-asn1-ber/asn1-ber v1.3.1/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0= -github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= -github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E= -github.com/go-git/go-billy/v5 v5.2.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= -github.com/go-git/go-billy/v5 v5.3.1 h1:CPiOUAzKtMRvolEKw+bG1PLRpT7D3LIs3/3ey4Aiu34= -github.com/go-git/go-billy/v5 v5.3.1/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0= -github.com/go-git/go-git-fixtures/v4 v4.2.1 h1:n9gGL1Ct/yIw+nfsfr8s4+sbhT+Ncu2SubfXjIWgci8= -github.com/go-git/go-git-fixtures/v4 v4.2.1/go.mod h1:K8zd3kDUAykwTdDCr+I0per6Y6vMiRR/nnVTBtavnB0= -github.com/go-git/go-git/v5 v5.4.2 h1:BXyZu9t0VkbiHtqrsvdq39UDhGJTl1h55VW6CSC4aY4= -github.com/go-git/go-git/v5 v5.4.2/go.mod h1:gQ1kArt6d+n+BGd+/B/I74HwRTLhth2+zti4ihgckDc= +github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= +github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= +github.com/go-git/go-billy/v5 v5.5.0 h1:yEY4yhzCDuMGSv83oGxiBotRzhwhNr8VZyphhiu+mTU= +github.com/go-git/go-billy/v5 v5.5.0/go.mod h1:hmexnoNsr2SJU1Ju67OaNz5ASJY3+sHgFRpCtpDCKow= +github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= +github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= +github.com/go-git/go-git/v5 v5.11.0 h1:XIZc1p+8YzypNr34itUfSvYJcv+eYdTnTvOZ2vD3cA4= +github.com/go-git/go-git/v5 v5.11.0/go.mod h1:6GFcX2P3NM7FPBfpePbpLd21XxsgdAt+lKqXmCUiUCY= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -744,8 +745,8 @@ github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KE github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.3.0 h1:2y3SDp0ZXuc6/cjLSZ+Q3ir+QB9T/iG5yYRXqsagWSY= -github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/zapr v1.2.4 h1:QHVo+6stLbfJmYGkQ7uGHUCu5hnAFAj6mDe6Ea0SeOo= @@ -878,16 +879,14 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/gogo/status v1.1.1 h1:DuHXlSFHNKqTQ+/ACf5Vs6r4X/dH2EgIzR9Vr+H65kg= github.com/gogo/status v1.1.1/go.mod h1:jpG3dM5QPcqu19Hg8lkUhBFBa3TcLs1DG7+2Jqci7oU= -github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= -github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg= github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang-jwt/jwt/v5 v5.0.0 h1:1n1XNM9hk7O9mnQoNBGolZvzebBQ7p93ULHRc28XJUE= github.com/golang-jwt/jwt/v5 v5.0.0/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= -github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY= -github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= +github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA= +github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A= github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI= github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= @@ -1013,7 +1012,6 @@ github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/enterprise-certificate-proxy v0.3.1 h1:SBWmZhjUDRorQxrN0nwzf+AHBxnbFjViHQS4P0yVpmQ= @@ -1329,8 +1327,8 @@ github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsU github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o= github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY= github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI= -github.com/jackc/pgconn v1.13.0 h1:3L1XMNV2Zvca/8BYhzcRFS70Lr0WlDg16Di6SFGAbys= -github.com/jackc/pgconn v1.13.0/go.mod h1:AnowpAqO4CMIIJNZl2VJp+KrkAZciAkhEl0W0JIobpI= +github.com/jackc/pgconn v1.14.0 h1:vrbA9Ud87g6JdFWkHTJXppVce58qPIdP7N8y0Ml/A7Q= +github.com/jackc/pgconn v1.14.0/go.mod h1:9mBNlny0UvkgJdCDvdVHYSjI+8tD2rnKK69Wz8ti++E= github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE= github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8= github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE= @@ -1346,23 +1344,24 @@ github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvW github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= -github.com/jackc/pgproto3/v2 v2.3.1 h1:nwj7qwf0S+Q7ISFfBndqeLwSwxs+4DPsbRFjECT1Y4Y= -github.com/jackc/pgproto3/v2 v2.3.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= -github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b h1:C8S2+VttkHFdOOCXJe+YGfa4vHYwlt4Zx+IVXQ97jYg= +github.com/jackc/pgproto3/v2 v2.3.2 h1:7eY55bdBeCz1F2fTzSz69QC+pG46jYq9/jtSPiJ5nn0= +github.com/jackc/pgproto3/v2 v2.3.2/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= +github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a h1:bbPeKD0xmW/Y25WS6cokEszi5g+S0QxI/d45PkRi7Nk= +github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a/go.mod h1:5TJZWKEWniPve33vlWYSoGYefn3gLQRzjfDlhSJ9ZKM= github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg= github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc= github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw= github.com/jackc/pgtype v1.8.1-0.20210724151600-32e20a603178/go.mod h1:C516IlIV9NKqfsMCXTdChteoXmwgUceqaLfjg2e3NlM= -github.com/jackc/pgtype v1.12.0 h1:Dlq8Qvcch7kiehm8wPGIW0W3KsCCHJnRacKW0UM8n5w= -github.com/jackc/pgtype v1.12.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4= +github.com/jackc/pgtype v1.14.0 h1:y+xUdabmyMkJLyApYuPj38mW+aAIqCe5uuBB51rH3Vw= +github.com/jackc/pgtype v1.14.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4= github.com/jackc/pgx v3.6.0+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I= github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y= github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM= github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc= github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs= -github.com/jackc/pgx/v4 v4.17.2 h1:0Ut0rpeKwvIVbMQ1KbMBU4h6wxehBI535LK6Flheh8E= -github.com/jackc/pgx/v4 v4.17.2/go.mod h1:lcxIZN44yMIrWI78a5CpucdD14hX0SBDbNRvjDBItsw= +github.com/jackc/pgx/v4 v4.18.1 h1:YP7G1KABtKpB5IHrO9vYwSrCOhs7p3uqhvhhQBptya0= +github.com/jackc/pgx/v4 v4.18.1/go.mod h1:FydWkUyadDmdNH/mHnGob881GawxeEm7TcMCzkb+qQE= github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= @@ -1383,14 +1382,12 @@ github.com/jcmturner/gofork v1.7.6 h1:QH0l3hzAU1tfT3rZCnW5zXl+orbkNMMRGJfdJjHVET github.com/jcmturner/gofork v1.7.6/go.mod h1:1622LH6i/EZqLloHfE7IeZ0uEJwMSUyQ/nDd82IeqRo= github.com/jcmturner/goidentity/v6 v6.0.1 h1:VKnZd2oEIMorCTsFBnJWbExfNN7yZr3EhJAxwOkZg6o= github.com/jcmturner/goidentity/v6 v6.0.1/go.mod h1:X1YW3bgtvwAXju7V3LCIMpY0Gbxyjn/mY9zx4tFonSg= -github.com/jcmturner/gokrb5/v8 v8.4.2/go.mod h1:sb+Xq/fTY5yktf/VxLsE3wlfPqQjp0aWNYyvBVK62bc= github.com/jcmturner/gokrb5/v8 v8.4.4 h1:x1Sv4HaTpepFkXbt2IkL29DXRf8sOfZXo8eRKh687T8= github.com/jcmturner/gokrb5/v8 v8.4.4/go.mod h1:1btQEpgT6k+unzCwX1KdWMEwPPkkgBtP+F6aCACiMrs= github.com/jcmturner/rpc/v2 v2.0.3 h1:7FXXj8Ti1IaVFpSAziCZWNzbNuZmnvw/i6CqLNdWfZY= github.com/jcmturner/rpc/v2 v2.0.3/go.mod h1:VUJYCIDm3PVOEHw8sgt091/20OJjskO/YJki3ELg/Hc= github.com/jefferai/jsonx v0.0.0-20160721235117-9cc31c3135ee/go.mod h1:N0t2vlmpe8nyZB5ouIbJQPDSR+mH6oe7xHB9VZHSUzM= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= -github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= github.com/jhump/protoreflect v1.6.0/go.mod h1:eaTn3RZAmMBcV0fifFvlm6VHNz3wSkYyXYWUh7ymB74= github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= @@ -1443,9 +1440,8 @@ github.com/karrick/godirwalk v1.16.1/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1q github.com/karrick/godirwalk v1.17.0 h1:b4kY7nqDdioR/6qnbHQyDvmA17u5G1cZ6J+CZXwSWoI= github.com/karrick/godirwalk v1.17.0/go.mod h1:j4mkqPuvaLI8mp1DroR3P6ad7cyYd4c1qeJ3RV7ULlk= github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= -github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= -github.com/kevinburke/ssh_config v1.1.0 h1:pH/t1WS9NzT8go394IqZeJTMHVm6Cr6ZJ6AQ+mdNo/o= -github.com/kevinburke/ssh_config v1.1.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= +github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= +github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/keybase/go-crypto v0.0.0-20180614160407-5114a9a81e1b/go.mod h1:ghbZscTyKdM07+Fw3KSi0hcJm+AlEUWj8QLlPtijN/M= github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= @@ -1499,8 +1495,8 @@ github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.3.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.10.1/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= -github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= +github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/lightstep/go-expohisto v1.0.0 h1:UPtTS1rGdtehbbAF7o/dhkWLTDI73UifG8LbfQI7cA4= github.com/lightstep/go-expohisto v1.0.0/go.mod h1:xDXD0++Mu2FOaItXtdDfksfgxfV0z1TMPa+e/EUd0cs= github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= @@ -1529,8 +1525,6 @@ github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0 github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= -github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A= -github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= @@ -1582,8 +1576,8 @@ github.com/mdlayher/wifi v0.1.0 h1:y8wYRUXwok5CtUZOXT3egghYesX0O79E3ALl+SIDm9Q= github.com/mdlayher/wifi v0.1.0/go.mod h1:+gBYnZAMcUKHSFzMJXwlz7tLsEHgwDJ9DJCefhJM+gI= github.com/metalmatze/signal v0.0.0-20210307161603-1c9aa721a97a h1:0usWxe5SGXKQovz3p+BiQ81Jy845xSMu2CWKuXsXuUM= github.com/metalmatze/signal v0.0.0-20210307161603-1c9aa721a97a/go.mod h1:3OETvrxfELvGsU2RoGGWercfeZ4bCL3+SOwzIWtJH/Q= -github.com/microsoft/go-mssqldb v0.19.0 h1:LMRSgLcNMF8paPX14xlyQBmBH+jnFylPsYpVZf86eHM= -github.com/microsoft/go-mssqldb v0.19.0/go.mod h1:ukJCBnnzLzpVF0qYRT+eg1e+eSwjeQ7IvenUv8QPook= +github.com/microsoft/go-mssqldb v1.6.0 h1:mM3gYdVwEPFrlg/Dvr2DNVEgYFG7L42l+dGc67NNNpc= +github.com/microsoft/go-mssqldb v1.6.0/go.mod h1:00mDtPbeQCRGC1HwOOR5K/gr30P1NcEG0vx6Kbv2aJU= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.25/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= @@ -1649,9 +1643,7 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= -github.com/montanaflynn/stats v0.6.6/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= github.com/montanaflynn/stats v0.7.0 h1:r3y12KyNxj/Sb/iOE46ws+3mS1+MZca1wlHQFPsY/JU= github.com/montanaflynn/stats v0.7.0/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= @@ -1904,7 +1896,8 @@ github.com/pierrec/lz4 v2.6.1+incompatible h1:9UY3+iC23yxF0UfGaYrGplQ+79Rg+h/q9F github.com/pierrec/lz4 v2.6.1+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pierrec/lz4/v4 v4.1.18 h1:xaKrnTkyoqfh1YItXl56+6KJNVYWlEEPuAQW9xsplYQ= github.com/pierrec/lz4/v4 v4.1.18/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= -github.com/pkg/browser v0.0.0-20210115035449-ce105d075bb4/go.mod h1:N6UoU20jOqggOuDwUaBQpluzLNDqif3kq9z2wpdYEfQ= +github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= +github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI= github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU= github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= @@ -1993,8 +1986,8 @@ github.com/prometheus/consul_exporter v0.8.0/go.mod h1:KHTgkT1/oLpXKC4+mKZV63hZS github.com/prometheus/exporter-toolkit v0.6.0/go.mod h1:ZUBIj498ePooX9t/2xtDjeQYwvRpiPP2lh5u4iblj2g= github.com/prometheus/exporter-toolkit v0.7.0/go.mod h1:ZUBIj498ePooX9t/2xtDjeQYwvRpiPP2lh5u4iblj2g= github.com/prometheus/exporter-toolkit v0.7.1/go.mod h1:ZUBIj498ePooX9t/2xtDjeQYwvRpiPP2lh5u4iblj2g= -github.com/prometheus/exporter-toolkit v0.10.1-0.20230714054209-2f4150c63f97 h1:oHcfzdJnM/SFppy2aUlvomk37GI33x9vgJULihE5Dt8= -github.com/prometheus/exporter-toolkit v0.10.1-0.20230714054209-2f4150c63f97/go.mod h1:LoBCZeRh+5hX+fSULNyFnagYlQG/gBsyA/deNzROkq8= +github.com/prometheus/exporter-toolkit v0.11.0 h1:yNTsuZ0aNCNFQ3aFTD2uhPOvr4iD7fdBvKPAEGkNf+g= +github.com/prometheus/exporter-toolkit v0.11.0/go.mod h1:BVnENhnNecpwoTLiABx7mrPB/OLRIgN74qlQbV+FK1Q= github.com/prometheus/memcached_exporter v0.13.0 h1:d246RYODFCXy39XA8S2PBrqp5jLCSvl9b4KsYspDCHk= github.com/prometheus/memcached_exporter v0.13.0/go.mod h1:fp7Wk6v0RFijeP3Syvd1TShBSJoCG5iFfvPdi5dCMEU= github.com/prometheus/procfs v0.0.0-20180408092902-8b1c2da0d56d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= @@ -2115,6 +2108,8 @@ github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/skeema/knownhosts v1.2.1 h1:SHWdIUa82uGZz+F+47k8SY4QhhI291cXCpopT1lK2AQ= +github.com/skeema/knownhosts v1.2.1/go.mod h1:xYbVRSPxqBZFrdmDyMmsOs+uX1UZC3nTN3ThzgDxUwo= github.com/smarty/assertions v1.15.0 h1:cR//PqUBUiQRakZWqBiFFQ9wb8emQGDb0HeGdqGByCY= github.com/smarty/assertions v1.15.0/go.mod h1:yABtdzeQs6l1brC900WlRNwj6ZR55d7B+E8C6HtKdec= github.com/smartystreets/assertions v0.0.0-20180820201707-7c9eb446e3cf/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= @@ -2123,8 +2118,8 @@ github.com/smartystreets/goconvey v0.0.0-20180222194500-ef6db91d284a/go.mod h1:X github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smartystreets/goconvey v1.8.1 h1:qGjIddxOk4grTu9JPOU31tVfq3cNdBlNa5sSznIX1xY= github.com/smartystreets/goconvey v1.8.1/go.mod h1:+/u4qLyY6x1jReYOp7GOM2FSt8aP9CzCZL03bI28W60= -github.com/snowflakedb/gosnowflake v1.6.22 h1:2crLpqmFVyV03NPAxxAtzQBMFn6wUPqOJ1uRl4ruOJ4= -github.com/snowflakedb/gosnowflake v1.6.22/go.mod h1:P2fE/xiD2kQXpr48OdgnazkzPsKD6aVtnHD3WP8yD9c= +github.com/snowflakedb/gosnowflake v1.7.2-0.20240103203018-f1d625f17408 h1:uhlKs7Mu7Pc1eLUFGOzBIUA7m7YKyMYu7egQ1LMYAik= +github.com/snowflakedb/gosnowflake v1.7.2-0.20240103203018-f1d625f17408/go.mod h1:xVuVfmC5OturIIXxT0TPTyLPGLSNZaDbgJh2AIIWzLE= github.com/softlayer/softlayer-go v0.0.0-20180806151055-260589d94c7d h1:bVQRCxQvfjNUeRqaY/uT0tFuvuFY0ulgnczuR684Xic= github.com/softlayer/softlayer-go v0.0.0-20180806151055-260589d94c7d/go.mod h1:Cw4GTlQccdRGSEf6KiMju767x0NEHE0YIVPJSaXjlsw= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= @@ -2231,8 +2226,8 @@ github.com/uber/jaeger-lib v2.4.1+incompatible h1:td4jdvLcExb4cBISKIpHuGoVXh+dVK github.com/uber/jaeger-lib v2.4.1+incompatible/go.mod h1:ComeNDZlWwrWnDv8aPp0Ba6+uUTzImX/AauajbLI56U= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/vertica/vertica-sql-go v1.3.0 h1:oZL8PgwrpALegtTFhImsaJvg5oQd2G7v7Uai97X9Xp8= -github.com/vertica/vertica-sql-go v1.3.0/go.mod h1:jnn2GFuv+O2Jcjktb7zyc4Utlbu9YVqpHH/lx63+1M4= +github.com/vertica/vertica-sql-go v1.3.3 h1:fL+FKEAEy5ONmsvya2WH5T8bhkvY27y/Ik3ReR2T+Qw= +github.com/vertica/vertica-sql-go v1.3.3/go.mod h1:jnn2GFuv+O2Jcjktb7zyc4Utlbu9YVqpHH/lx63+1M4= github.com/vincent-petithory/dataurl v1.0.0 h1:cXw+kPto8NLuJtlMsI152irrVw9fRDX8AbShPRpg2CI= github.com/vincent-petithory/dataurl v1.0.0/go.mod h1:FHafX5vmDzyP+1CQATJn7WFKc9CvnvxyvZy6I1MrG/U= github.com/vishvananda/netlink v0.0.0-20171020171820-b2de5d10e38e/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk= @@ -2264,9 +2259,8 @@ github.com/wk8/go-ordered-map v0.2.0 h1:KlvGyHstD1kkGZkPtHCyCfRYS0cz84uk6rrW/Dnh github.com/wk8/go-ordered-map v0.2.0/go.mod h1:9ZIbRunKbuvfPKyBP1SIKLcXNlv74YCOZ3t3VTS6gRk= github.com/wvanbergen/kafka v0.0.0-20171203153745-e2edea948ddf/go.mod h1:nxx7XRXbR9ykhnC8lXqQyJS0rfvJGxKyKw/sT1YOttg= github.com/wvanbergen/kazoo-go v0.0.0-20180202103751-f72d8611297a/go.mod h1:vQQATAGxVK20DC1rRubTJbZDDhhpA4QfU02pMdPxGO4= -github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= -github.com/xanzy/ssh-agent v0.3.1 h1:AmzO1SSWxw73zxFZPRwaMN1MohDw8UyHnmuxyceTEGo= -github.com/xanzy/ssh-agent v0.3.1/go.mod h1:QIE4lCeL7nkC25x+yA3LBIYfwCc1TFziCtG7cBAac6w= +github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= +github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= @@ -2291,8 +2285,8 @@ github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQ github.com/xhit/go-str2duration/v2 v2.1.0 h1:lxklc02Drh6ynqX+DdPyp5pCKLUQpRT8bp8Ydu2Bstc= github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= -github.com/xo/dburl v0.13.0 h1:kq+oD1j/m8DnJ/p6G/LQXRosVchs8q5/AszEUKkvYfo= -github.com/xo/dburl v0.13.0/go.mod h1:K6rSPgbVqP3ZFT0RHkdg/M3M5KhLeV2MaS/ZqaLd1kA= +github.com/xo/dburl v0.20.0 h1:v601OhM9J4Zh56R270ncM9HRgoxp39tf9+nt5ft9UD0= +github.com/xo/dburl v0.20.0/go.mod h1:B7/G9FGungw6ighV8xJNwWYQPMfn3gsi2sn5SE8Bzco= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -2476,7 +2470,6 @@ go4.org/netipx v0.0.0-20230125063823-8449b0a6169f/go.mod h1:tgPU4N2u9RByaTN3NC2p golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= @@ -2499,25 +2492,24 @@ golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 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-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/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-20210314154223-e6e6c4f2bb5b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/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-20210711020723-a769d52b0f97/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-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220511200225-c6db032c6c88/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220829220503-c86fa9a7ed90/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= +golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= +golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I= -golang.org/x/crypto v0.15.0 h1:frVn1TEaCEaZcn3Tmd7Y2b5KKPaZ+I32Q2OA3kYp5TA= -golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g= +golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k= +golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4= 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= @@ -2610,7 +2602,6 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= @@ -2621,7 +2612,6 @@ golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210224082022-3d97a244fca7/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= -golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= @@ -2632,16 +2622,16 @@ golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ= -golang.org/x/net v0.18.0 h1:mIYleuAkSbHh0tCv7RvjL3F6ZVbLjq4+R7zbOn3Kokg= -golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ= +golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= +golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= golang.org/x/oauth2 v0.0.0-20170807180024-9a379c6b3e95/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= 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= @@ -2764,14 +2754,12 @@ golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210502180810-71e4cd670f79/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -2789,7 +2777,6 @@ golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20211031064116-611d5d643895/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220224120231-95c6836cb0e7/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -2800,6 +2787,7 @@ golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -2816,10 +2804,11 @@ golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuX golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo= -golang.org/x/term v0.14.0 h1:LGK9IlZ8T9jvdy6cTdfKUCltatMFOehAQo9SRC46UQ8= -golang.org/x/term v0.14.0/go.mod h1:TySc+nGkYR6qt8km8wUhuFRTVSMIX3XPR58y2lC8vww= +golang.org/x/term v0.15.0 h1:y/Oo/a/q3IXu26lQgl04j/gjuBDOBlx7X6Om1j2CPW4= +golang.org/x/term v0.15.0/go.mod h1:BDl952bC7+uMoWR75FIrCDx79TPU9oHkTZ9yRbYOrX0= 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= @@ -2834,6 +2823,7 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= @@ -3110,8 +3100,8 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= -google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I= +google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= @@ -3147,8 +3137,6 @@ gopkg.in/jcmturner/rpc.v1 v1.1.0/go.mod h1:YIdkC4XfD6GXbzje11McwsDuOlZQSb9W4vfLv gopkg.in/ldap.v3 v3.1.0/go.mod h1:dQjCc0R0kfyFjIlWNMH1DORwUASZyDxo2Ry1B51dXaQ= gopkg.in/mgo.v2 v2.0.0-20160818020120-3f83fa500528/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= -gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce h1:+JknDZhAj8YMt7GC73Ei8pv4MzjDUNPHgQWJdtMAaDU= -gopkg.in/natefinch/npipe.v2 v2.0.0-20160621034901-c1b8fa8bdcce/go.mod h1:5AcXVHNjg+BDxry382+8OKon8SEWiKktQR07RKPsv1c= gopkg.in/olivere/elastic.v5 v5.0.70/go.mod h1:FylZT6jQWtfHsicejzOm3jIMVPOAksa80i3o+6qtQRk= gopkg.in/ory-am/dockertest.v3 v3.3.4/go.mod h1:s9mmoLkaGeAh97qygnNj4xWkiN7e1SKekYC6CovU+ek= gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= diff --git a/pkg/integrations/mssql/sql_exporter.go b/pkg/integrations/mssql/sql_exporter.go index fd9af2278be0..84d930d35a3e 100644 --- a/pkg/integrations/mssql/sql_exporter.go +++ b/pkg/integrations/mssql/sql_exporter.go @@ -114,6 +114,9 @@ func (c *Config) NewIntegration(l log.Logger) (integrations.Integration, error) collectorConfig = *customCollectorConfig } + // TODO(hainenber): expose below attr as config + enablePing := false + t, err := sql_exporter.NewTarget( "mssqlintegration", "", @@ -128,6 +131,7 @@ func (c *Config) NewIntegration(l log.Logger) (integrations.Integration, error) MaxConns: c.MaxOpenConnections, MaxIdleConns: c.MaxIdleConnections, }, + &enablePing, ) if err != nil { From f471706f709c6a744103fa8dc182fd722fe12522 Mon Sep 17 00:00:00 2001 From: mattdurham Date: Mon, 8 Jan 2024 09:21:57 -0500 Subject: [PATCH 13/68] add changelog (#6058) --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4496cb325474..36107e76a0c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -111,6 +111,8 @@ v0.39.0-rc.0 (2024-01-05) - Fix issue where `prometheus.exporter.kafka` would crash when configuring `sasl_password`. (@rfratto) +- Fix nil panic when using the process collector with the windows exporter. (@mattdurham) + ### Other changes - Bump github.com/IBM/sarama from v1.41.2 to v1.42.1 From b7c1089ef1785faac765555705ad8e0f2d071796 Mon Sep 17 00:00:00 2001 From: mattdurham Date: Mon, 8 Jan 2024 10:43:53 -0500 Subject: [PATCH 14/68] add call to set perf query (#6065) --- CHANGELOG.md | 4 ++++ .../windows_exporter/windows_exporter_windows.go | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 36107e76a0c7..90012924be72 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,10 @@ Main (unreleased) - [GO-2023-2412](https://github.com/advisories/GHSA-7ww5-4wqc-m92c) - [CVE-2023-49568](https://github.com/advisories/GHSA-mw99-9chc-xw7r) +### Bugfixes + +- Fix performance issue where perf lib where clause was not being set, leading to timeouts in collecting metrics for windows_exporter. (@mattdurham) + v0.39.0-rc.0 (2024-01-05) ------------------------- diff --git a/pkg/integrations/windows_exporter/windows_exporter_windows.go b/pkg/integrations/windows_exporter/windows_exporter_windows.go index fd0a7effe023..94e05f1121a6 100644 --- a/pkg/integrations/windows_exporter/windows_exporter_windows.go +++ b/pkg/integrations/windows_exporter/windows_exporter_windows.go @@ -23,6 +23,11 @@ func New(logger log.Logger, c *Config) (integrations.Integration, error) { if err != nil { return nil, err } + err = winCol.SetPerfCounterQuery() + if err != nil { + return nil, err + } + return integrations.NewCollectorIntegration(c.Name(), integrations.WithCollectors( // Hard-coded 4m timeout to represent the time a series goes stale. // TODO: Make configurable if useful. From df408837cbe96e38da7033d6eb534407eda06eb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=90=E1=BB=97=20Tr=E1=BB=8Dng=20H=E1=BA=A3i?= <41283691+hainenber@users.noreply.github.com> Date: Tue, 9 Jan 2024 00:17:36 +0700 Subject: [PATCH 15/68] chore(build): remove seemingly obsolete exclude directive (#6059) Signed-off-by: hainenber --- go.mod | 3 --- 1 file changed, 3 deletions(-) diff --git a/go.mod b/go.mod index 071002b5e7c3..4a42f89440db 100644 --- a/go.mod +++ b/go.mod @@ -725,9 +725,6 @@ replace ( github.com/prometheus/node_exporter => github.com/grafana/node_exporter v0.18.1-grafana-r01.0.20231004161416-702318429731 ) -// Excluding fixes a conflict in test packages and allows "go mod tidy" to run. -exclude google.golang.org/grpc/examples v0.0.0-20200728065043-dfc0c05b2da9 - // Replacing for an internal fork which allows us to observe metrics produced by the Collector. // This is a temporary solution while a new configuration design is discussed for the collector. Related issues: // https://github.com/open-telemetry/opentelemetry-collector/issues/7532 From d1619fc3050d20192bc57b93ffc67e419409b64b Mon Sep 17 00:00:00 2001 From: Piotr <17101802+thampiotr@users.noreply.github.com> Date: Mon, 8 Jan 2024 17:18:58 +0000 Subject: [PATCH 16/68] Docs: Move Monitoring section into Tasks section (#6064) * Move monitoring section into Tasks * Make generate versioned files * Revert "Make generate versioned files" This reverts commit 240908be24c7cc8fb79feeb4daebcc8dda8f6bae. * update gen template * tweak monitor docs titles --- docs/sources/_index.md | 4 ++-- docs/sources/_index.md.t | 4 ++-- docs/sources/flow/concepts/clustering.md | 8 +++---- docs/sources/flow/monitoring/_index.md | 18 -------------- docs/sources/flow/reference/cli/run.md | 2 +- .../flow/setup/configure/configure-linux.md | 4 ++-- .../flow/setup/configure/configure-macos.md | 4 ++-- .../flow/setup/configure/configure-windows.md | 4 ++-- docs/sources/flow/setup/install/docker.md | 4 ++-- .../flow/tasks/configure-agent-clustering.md | 4 ++-- .../debugging.md => tasks/debug.md} | 23 +++++++++++------- .../distribute-prometheus-scrape-load.md | 4 ++-- .../estimate-resource-usage.md} | 15 +++++++++--- .../flow/tasks/migrate/from-prometheus.md | 8 +++---- .../flow/tasks/migrate/from-promtail.md | 8 +++---- .../sources/flow/tasks/migrate/from-static.md | 8 +++---- docs/sources/flow/tasks/monitor/_index.md | 24 +++++++++++++++++++ .../monitor}/component_metrics.md | 15 ++++++++---- .../monitor}/controller_metrics.md | 15 ++++++++---- 19 files changed, 106 insertions(+), 70 deletions(-) delete mode 100644 docs/sources/flow/monitoring/_index.md rename docs/sources/flow/{monitoring/debugging.md => tasks/debug.md} (89%) rename docs/sources/flow/{monitoring/agent-resource-usage.md => tasks/estimate-resource-usage.md} (79%) create mode 100644 docs/sources/flow/tasks/monitor/_index.md rename docs/sources/flow/{monitoring => tasks/monitor}/component_metrics.md (75%) rename docs/sources/flow/{monitoring => tasks/monitor}/controller_metrics.md (74%) diff --git a/docs/sources/_index.md b/docs/sources/_index.md index 1a7a2a261874..4b19726241b6 100644 --- a/docs/sources/_index.md +++ b/docs/sources/_index.md @@ -115,6 +115,6 @@ Patch and security releases may be created at any time. [Flow mode]: "/docs/agent/ -> /docs/agent//flow" [Flow mode]: "/docs/grafana-cloud/ -> /docs/agent//flow" -[UI]: "/docs/agent/ -> /docs/agent//flow/monitoring/debugging.md#grafana-agent-flow-ui" -[UI]: "/docs/grafana-cloud/ -> /docs/agent//flow/monitoring/debugging.md#grafana-agent-flow-ui" +[UI]: "/docs/agent/ -> /docs/agent//flow/tasks/debug.md#grafana-agent-flow-ui" +[UI]: "/docs/grafana-cloud/ -> /docs/agent//flow/tasks/debug.md#grafana-agent-flow-ui" {{% /docs/reference %}} diff --git a/docs/sources/_index.md.t b/docs/sources/_index.md.t index d769d5cfffc5..c8dccbfb6748 100644 --- a/docs/sources/_index.md.t +++ b/docs/sources/_index.md.t @@ -115,6 +115,6 @@ Patch and security releases may be created at any time. [Flow mode]: "/docs/agent/ -> /docs/agent//flow" [Flow mode]: "/docs/grafana-cloud/ -> /docs/agent//flow" -[UI]: "/docs/agent/ -> /docs/agent//flow/monitoring/debugging.md#grafana-agent-flow-ui" -[UI]: "/docs/grafana-cloud/ -> /docs/agent//flow/monitoring/debugging.md#grafana-agent-flow-ui" +[UI]: "/docs/agent/ -> /docs/agent//flow/tasks/debug.md#grafana-agent-flow-ui" +[UI]: "/docs/grafana-cloud/ -> /docs/agent//flow/tasks/debug.md#grafana-agent-flow-ui" {{% /docs/reference %}} diff --git a/docs/sources/flow/concepts/clustering.md b/docs/sources/flow/concepts/clustering.md index 3f6f5b093639..e02a6131d4a5 100644 --- a/docs/sources/flow/concepts/clustering.md +++ b/docs/sources/flow/concepts/clustering.md @@ -76,8 +76,8 @@ Refer to [Debugging clustering issues][debugging] for additional troubleshooting [prometheus.operator.podmonitors]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/reference/components/prometheus.operator.podmonitors.md#clustering-beta" [prometheus.operator.servicemonitors]: "/docs/agent/ -> /docs/agent//flow/reference/components/prometheus.operator.servicemonitors.md#clustering-beta" [prometheus.operator.servicemonitors]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/reference/components/prometheus.operator.servicemonitors.md#clustering-beta" -[clustering page]: "/docs/agent/ -> /docs/agent//flow/monitoring/debugging.md#clustering-page" -[clustering page]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/monitoring/debugging.md#clustering-page" -[debugging]: "/docs/agent/ -> /docs/agent//flow/monitoring/debugging.md#debugging-clustering-issues" -[debugging]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/monitoring/debugging.md#debugging-clustering-issues" +[clustering page]: "/docs/agent/ -> /docs/agent//flow/tasks/debug.md#clustering-page" +[clustering page]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/tasks/debug.md#clustering-page" +[debugging]: "/docs/agent/ -> /docs/agent//flow/tasks/debug.md#debugging-clustering-issues" +[debugging]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/tasks/debug.md#debugging-clustering-issues" {{% /docs/reference %}} \ No newline at end of file diff --git a/docs/sources/flow/monitoring/_index.md b/docs/sources/flow/monitoring/_index.md deleted file mode 100644 index 729bbaa8ff89..000000000000 --- a/docs/sources/flow/monitoring/_index.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -aliases: -- /docs/grafana-cloud/agent/flow/monitoring/ -- /docs/grafana-cloud/monitor-infrastructure/agent/flow/monitoring/ -- /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/monitoring/ -- /docs/grafana-cloud/send-data/agent/flow/monitoring/ -canonical: https://grafana.com/docs/agent/latest/flow/monitoring/ -description: Learn about monitoring Grafana Agent Flow -title: Monitoring Grafana Agent Flow -menuTitle: Monitoring -weight: 500 ---- - -# Monitoring {{% param "PRODUCT_NAME" %}} - -This section details various ways to monitor and debug {{< param "PRODUCT_NAME" >}}. - -{{< section >}} diff --git a/docs/sources/flow/reference/cli/run.md b/docs/sources/flow/reference/cli/run.md index 4a7adc21b7b2..4da0df47a473 100644 --- a/docs/sources/flow/reference/cli/run.md +++ b/docs/sources/flow/reference/cli/run.md @@ -171,7 +171,7 @@ transitions to the terminating state when shutting down. The current state of a clustered {{< param "PRODUCT_ROOT_NAME" >}} is shown on the clustering page in the [UI][]. -[UI]: {{< relref "../../monitoring/debugging.md#clustering-page" >}} +[UI]: {{< relref "../../tasks/debug.md#clustering-page" >}} ## Configuration conversion (beta) diff --git a/docs/sources/flow/setup/configure/configure-linux.md b/docs/sources/flow/setup/configure/configure-linux.md index 3964eb416070..a2cb7389774f 100644 --- a/docs/sources/flow/setup/configure/configure-linux.md +++ b/docs/sources/flow/setup/configure/configure-linux.md @@ -93,6 +93,6 @@ To expose the UI to other machines, complete the following steps: {{% docs/reference %}} [run]: "/docs/agent/ -> /docs/agent//flow/reference/cli/run.md" [run]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/reference/cli/run.md" -[UI]: "/docs/agent/ -> /docs/agent//flow/monitoring/debugging.md#grafana-agent-flow-ui" -[UI]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/monitoring/debugging.md#grafana-agent-flow-ui" +[UI]: "/docs/agent/ -> /docs/agent//flow/tasks/debug.md#grafana-agent-flow-ui" +[UI]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/tasks/debug.md#grafana-agent-flow-ui" {{% /docs/reference %}} diff --git a/docs/sources/flow/setup/configure/configure-macos.md b/docs/sources/flow/setup/configure/configure-macos.md index 5261e75f9877..e0943be422cb 100644 --- a/docs/sources/flow/setup/configure/configure-macos.md +++ b/docs/sources/flow/setup/configure/configure-macos.md @@ -82,6 +82,6 @@ To expose the UI to other machines, complete the following steps: To listen on all interfaces, replace `127.0.0.1` with `0.0.0.0`. {{% docs/reference %}} -[UI]: "/docs/agent/ -> /docs/agent//flow/monitoring/debugging.md#grafana-agent-flow-ui" -[UI]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/monitoring/debugging.md#grafana-agent-flow-ui" +[UI]: "/docs/agent/ -> /docs/agent//flow/tasks/debug.md#grafana-agent-flow-ui" +[UI]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/tasks/debug.md#grafana-agent-flow-ui" {{% /docs/reference %}} diff --git a/docs/sources/flow/setup/configure/configure-windows.md b/docs/sources/flow/setup/configure/configure-windows.md index 010e6897b8ea..520ba2b64539 100644 --- a/docs/sources/flow/setup/configure/configure-windows.md +++ b/docs/sources/flow/setup/configure/configure-windows.md @@ -90,7 +90,7 @@ To expose the UI to other machines, complete the following steps: To listen on all interfaces, replace `LISTEN_ADDR` with `0.0.0.0`. {{% docs/reference %}} -[UI]: "/docs/agent/ -> /docs/agent//flow/monitoring/debugging.md#grafana-agent-flow-ui" -[UI]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/monitoring/debugging.md#grafana-agent-flow-ui" +[UI]: "/docs/agent/ -> /docs/agent//flow/tasks/debug.md#grafana-agent-flow-ui" +[UI]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/tasks/debug.md#grafana-agent-flow-ui" {{% /docs/reference %}} diff --git a/docs/sources/flow/setup/install/docker.md b/docs/sources/flow/setup/install/docker.md index 15f9e391e08e..9460ab71a8f3 100644 --- a/docs/sources/flow/setup/install/docker.md +++ b/docs/sources/flow/setup/install/docker.md @@ -92,6 +92,6 @@ To verify that {{< param "PRODUCT_NAME" >}} is running successfully, navigate to {{% docs/reference %}} [run]: "/docs/agent/ -> /docs/agent//flow/reference/cli/run.md" [run]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/reference/cli/run.md" -[UI]: "/docs/agent/ -> /docs/agent//flow/monitoring/debugging.md#grafana-agent-flow-ui" -[UI]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/monitoring/debugging.md#grafana-agent-flow-ui" +[UI]: "/docs/agent/ -> /docs/agent//flow/tasks/debug.md#grafana-agent-flow-ui" +[UI]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/tasks/debug.md#grafana-agent-flow-ui" {{% /docs/reference %}} diff --git a/docs/sources/flow/tasks/configure-agent-clustering.md b/docs/sources/flow/tasks/configure-agent-clustering.md index b1ab444d4ebb..ca67ecd2d608 100644 --- a/docs/sources/flow/tasks/configure-agent-clustering.md +++ b/docs/sources/flow/tasks/configure-agent-clustering.md @@ -69,6 +69,6 @@ To configure clustering: [beta]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/stability.md#beta" [install-helm]: "/docs/agent/ -> /docs/agent//flow/setup/install/kubernetes.md" [install-helm]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/setup/install/kubernetes.md" -[UI]: "/docs/agent/ -> /docs/agent//flow/monitoring/debugging.md#component-detail-page" -[UI]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/monitoring/debugging.md#component-detail-page" +[UI]: "/docs/agent/ -> /docs/agent//flow/tasks/debug.md#component-detail-page" +[UI]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/tasks/debug.md#component-detail-page" {{% /docs/reference %}} diff --git a/docs/sources/flow/monitoring/debugging.md b/docs/sources/flow/tasks/debug.md similarity index 89% rename from docs/sources/flow/monitoring/debugging.md rename to docs/sources/flow/tasks/debug.md index a3d148e52487..6932d6082f82 100644 --- a/docs/sources/flow/monitoring/debugging.md +++ b/docs/sources/flow/tasks/debug.md @@ -1,16 +1,23 @@ --- aliases: +- /docs/grafana-cloud/agent/flow/tasks/debug/ +- /docs/grafana-cloud/monitor-infrastructure/agent/flow/tasks/debug/ +- /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/tasks/debug/ +- /docs/grafana-cloud/send-data/agent/flow/tasks/debug/ +# Previous page aliases for backwards compatibility: - /docs/grafana-cloud/agent/flow/monitoring/debugging/ - /docs/grafana-cloud/monitor-infrastructure/agent/flow/monitoring/debugging/ - /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/monitoring/debugging/ - /docs/grafana-cloud/send-data/agent/flow/monitoring/debugging/ +- ../monitoring/debugging/ # /docs/agent/latest/flow/monitoring/debugging/ canonical: https://grafana.com/docs/agent/latest/flow/monitoring/debugging/ -description: Learn about debugging -title: Debugging -weight: 300 +description: Learn about debugging issues with Grafana Agent Flow +title: Debug issues with Grafana Agent Flow +menuTitle: Debug issues +weight: 1000 --- -# Debugging +# Debug {{< param "PRODUCT_NAME" >}} Follow these steps to debug issues with {{< param "PRODUCT_NAME" >}}: @@ -32,7 +39,7 @@ Follow these steps to debug issues with {{< param "PRODUCT_NAME" >}}: ### Home page -![](../../../assets/ui_home_page.png) +![](../../assets/ui_home_page.png) The home page shows a table of components defined in the configuration file and their health. @@ -42,14 +49,14 @@ Click the {{< param "PRODUCT_ROOT_NAME" >}} logo to navigate back to the home pa ### Graph page -![](../../../assets/ui_graph_page.png) +![](../../assets/ui_graph_page.png) The **Graph** page shows a graph view of components defined in the configuration file and their health. Clicking a component in the graph navigates to the [Component detail page](#component-detail-page) for that component. ### Component detail page -![](../../../assets/ui_component_detail_page.png) +![](../../assets/ui_component_detail_page.png) The component detail page shows the following information for each component: @@ -62,7 +69,7 @@ The component detail page shows the following information for each component: ### Clustering page -![](../../../assets/ui_clustering_page.png) +![](../../assets/ui_clustering_page.png) The clustering page shows the following information for each cluster node: diff --git a/docs/sources/flow/tasks/distribute-prometheus-scrape-load.md b/docs/sources/flow/tasks/distribute-prometheus-scrape-load.md index 961c98543b98..329f6eed9ade 100644 --- a/docs/sources/flow/tasks/distribute-prometheus-scrape-load.md +++ b/docs/sources/flow/tasks/distribute-prometheus-scrape-load.md @@ -63,6 +63,6 @@ To distribute Prometheus metrics scrape load with clustering: [Configure Prometheus metrics collection]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/tasks/collect-prometheus-metrics.md" [Configure clustering]: "/docs/agent/ -> /docs/agent//flow/tasks/configure-agent-clustering.md" [Configure clustering]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/tasks/configure-agent-clustering.md" -[UI]: "/docs/agent/ -> /docs/agent//flow/monitoring/debugging.md#component-detail-page" -[UI]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/monitoring/debugging.md#component-detail-page" +[UI]: "/docs/agent/ -> /docs/agent//flow/tasks/debug.md#component-detail-page" +[UI]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/tasks/debug.md#component-detail-page" {{% /docs/reference %}} diff --git a/docs/sources/flow/monitoring/agent-resource-usage.md b/docs/sources/flow/tasks/estimate-resource-usage.md similarity index 79% rename from docs/sources/flow/monitoring/agent-resource-usage.md rename to docs/sources/flow/tasks/estimate-resource-usage.md index 21b16106d5a3..6fb8a146f6d9 100644 --- a/docs/sources/flow/monitoring/agent-resource-usage.md +++ b/docs/sources/flow/tasks/estimate-resource-usage.md @@ -1,17 +1,26 @@ --- aliases: + - /docs/agent/flow/tasks/estimate-resource-usage/ + - /docs/grafana-cloud/agent/flow/tasks/estimate-resource-usage/ + - /docs/grafana-cloud/monitor-infrastructure/agent/flow/tasks/estimate-resource-usage/ + - /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/tasks/estimate-resource-usage/ + - /docs/grafana-cloud/send-data/agent/flow/tasks/estimate-resource-usage/ + # Previous page aliases for backwards compatibility: - /docs/agent/flow/monitoring/resource-usage/ - /docs/grafana-cloud/agent/flow/monitoring/resource-usage/ - /docs/grafana-cloud/monitor-infrastructure/agent/flow/monitoring/resource-usage/ - /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/monitoring/resource-usage/ - /docs/grafana-cloud/send-data/agent/flow/monitoring/resource-usage/ + - ../monitoring/resource-usage/ # /docs/agent/latest/flow/monitoring/resource-usage/ canonical: https://grafana.com/docs/agent/latest/flow/monitoring/resource-usage/ -description: Guidance for expected Agent resource usage +description: Estimate expected Agent resource usage headless: true -title: Resource usage +title: Estimate resource usage +menuTitle: Estimate resource usage +weight: 190 --- -# {{% param "PRODUCT_NAME" %}} resource usage +# Estimate {{% param "PRODUCT_NAME" %}} resource usage This page provides guidance for expected resource usage of {{% param "PRODUCT_NAME" %}} for each telemetry type, based on operational diff --git a/docs/sources/flow/tasks/migrate/from-prometheus.md b/docs/sources/flow/tasks/migrate/from-prometheus.md index 74a53f2475c5..6224d82901e7 100644 --- a/docs/sources/flow/tasks/migrate/from-prometheus.md +++ b/docs/sources/flow/tasks/migrate/from-prometheus.md @@ -258,10 +258,10 @@ The following list is specific to the convert command and not {{< param "PRODUCT [run]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/reference/cli/run.md" [Start]: "/docs/agent/ -> /docs/agent//flow/setup/start-agent.md" [Start]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/setup/start-agent.md" -[DebuggingUI]: "/docs/agent/ -> /docs/agent//flow/monitoring/debugging.md" -[DebuggingUI]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/monitoring/debugging.md" +[DebuggingUI]: "/docs/agent/ -> /docs/agent//flow/tasks/debug.md" +[DebuggingUI]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/tasks/debug.md" [River]: "/docs/agent/ -> /docs/agent//flow/concepts/config-language/_index.md" [River]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/concepts/config-language/_index.md" -[UI]: "/docs/agent/ -> /docs/agent//flow/monitoring/debugging#grafana-agent-flow-ui" -[UI]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/monitoring/debugging#grafana-agent-flow-ui" +[UI]: "/docs/agent/ -> /docs/agent//flow/tasks/debug#grafana-agent-flow-ui" +[UI]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/tasks/debug#grafana-agent-flow-ui" {{% /docs/reference %}} diff --git a/docs/sources/flow/tasks/migrate/from-promtail.md b/docs/sources/flow/tasks/migrate/from-promtail.md index 89c863f8758f..29dc2ca5c0e6 100644 --- a/docs/sources/flow/tasks/migrate/from-promtail.md +++ b/docs/sources/flow/tasks/migrate/from-promtail.md @@ -241,10 +241,10 @@ The following list is specific to the convert command and not {{< param "PRODUCT [run]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/reference/cli/run.md" [Start]: "/docs/agent/ -> /docs/agent//flow/setup/start-agent.md" [Start]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/setup/start-agent.md" -[DebuggingUI]: "/docs/agent/ -> /docs/agent//flow/monitoring/debugging.md" -[DebuggingUI]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/monitoring/debugging.md" +[DebuggingUI]: "/docs/agent/ -> /docs/agent//flow/tasks/debug.md" +[DebuggingUI]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/tasks/debug.md" [River]: "/docs/agent/ -> /docs/agent//flow/concepts/config-language/_index.md" [River]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/concepts/config-language/_index.md" -[UI]: "/docs/agent/ -> /docs/agent//flow/monitoring/debugging#grafana-agent-flow-ui" -[UI]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/monitoring/debugging#grafana-agent-flow-ui" +[UI]: "/docs/agent/ -> /docs/agent//flow/tasks/debug#grafana-agent-flow-ui" +[UI]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/tasks/debug#grafana-agent-flow-ui" {{% /docs/reference %}} diff --git a/docs/sources/flow/tasks/migrate/from-static.md b/docs/sources/flow/tasks/migrate/from-static.md index bf8532f207d9..0a6fb982853b 100644 --- a/docs/sources/flow/tasks/migrate/from-static.md +++ b/docs/sources/flow/tasks/migrate/from-static.md @@ -376,8 +376,8 @@ The following list is specific to the convert command and not {{< param "PRODUCT [run]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/reference/cli/run.md" [Start]: "/docs/agent/ -> /docs/agent//flow/setup/start-agent.md" [Start]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/setup/start-agent.md" -[DebuggingUI]: "/docs/agent/ -> /docs/agent//flow/monitoring/debugging.md" -[DebuggingUI]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/monitoring/debugging.md" +[DebuggingUI]: "/docs/agent/ -> /docs/agent//flow/tasks/debug.md" +[DebuggingUI]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/tasks/debug.md" [River]: "/docs/agent/ -> /docs/agent//flow/concepts/config-language/" [River]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/concepts/config-language/" [Integrations next]: "/docs/agent/ -> /docs/agent//static/configuration/integrations/integrations-next/_index.md" @@ -396,6 +396,6 @@ The following list is specific to the convert command and not {{< param "PRODUCT [Metrics]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/static/configuration/metrics-config.md" [Logs]: "/docs/agent/ -> /docs/agent//static/configuration/logs-config.md" [Logs]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/static/logs-config.md" -[UI]: "/docs/agent/ -> /docs/agent//flow/monitoring/debugging#grafana-agent-flow-ui" -[UI]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/monitoring/debugging#grafana-agent-flow-ui" +[UI]: "/docs/agent/ -> /docs/agent//flow/tasks/debug#grafana-agent-flow-ui" +[UI]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/tasks/debug#grafana-agent-flow-ui" {{% /docs/reference %}} diff --git a/docs/sources/flow/tasks/monitor/_index.md b/docs/sources/flow/tasks/monitor/_index.md new file mode 100644 index 000000000000..ac23db26072c --- /dev/null +++ b/docs/sources/flow/tasks/monitor/_index.md @@ -0,0 +1,24 @@ +--- +aliases: +- /docs/grafana-cloud/agent/flow/tasks/monitor/ +- /docs/grafana-cloud/monitor-infrastructure/agent/flow/tasks/monitor/ +- /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/tasks/monitor/ +- /docs/grafana-cloud/send-data/agent/flow/tasks/monitor/ +# Previous page aliases for backwards compatibility: +- /docs/grafana-cloud/agent/flow/monitoring/ +- /docs/grafana-cloud/monitor-infrastructure/agent/flow/monitoring/ +- /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/monitoring/ +- /docs/grafana-cloud/send-data/agent/flow/monitoring/ +- ../monitoring/ # /docs/agent/latest/flow/monitoring/ +canonical: https://grafana.com/docs/agent/latest/flow/tasks/monitor/ +description: Learn about monitoring Grafana Agent Flow +title: Monitor Grafana Agent Flow +menuTitle: Monitor +weight: 110 +--- + +# How to monitor {{% param "PRODUCT_NAME" %}} + +This section details various ways to monitor and debug {{< param "PRODUCT_NAME" >}}. + +{{< section >}} diff --git a/docs/sources/flow/monitoring/component_metrics.md b/docs/sources/flow/tasks/monitor/component_metrics.md similarity index 75% rename from docs/sources/flow/monitoring/component_metrics.md rename to docs/sources/flow/tasks/monitor/component_metrics.md index 90c3769572c9..5b3693a1f182 100644 --- a/docs/sources/flow/monitoring/component_metrics.md +++ b/docs/sources/flow/tasks/monitor/component_metrics.md @@ -1,17 +1,24 @@ --- aliases: +- /docs/grafana-cloud/agent/flow/tasks/monitor/component_metrics/ +- /docs/grafana-cloud/monitor-infrastructure/agent/flow/tasks/monitor/component_metrics/ +- /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/tasks/monitor/component_metrics/ +- /docs/grafana-cloud/send-data/agent/flow/tasks/monitor/component_metrics/ +- component-metrics/ # /docs/agent/latest/flow/tasks/monitor/component-metrics/ +# Previous page aliases for backwards compatibility: - /docs/grafana-cloud/agent/flow/monitoring/component_metrics/ - /docs/grafana-cloud/monitor-infrastructure/agent/flow/monitoring/component_metrics/ - /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/monitoring/component_metrics/ - /docs/grafana-cloud/send-data/agent/flow/monitoring/component_metrics/ -- component-metrics/ +- ../../monitoring/component-metrics/ # /docs/agent/latest/flow/monitoring/component-metrics/ +- ../../monitoring/component_metrics/ # /docs/agent/latest/flow/monitoring/component_metrics/ canonical: https://grafana.com/docs/agent/latest/flow/monitoring/component_metrics/ -description: Learn about component metrics -title: Component metrics +description: Learn how to monitor component metrics +title: Monitor components weight: 200 --- -# Component metrics +# How to monitor components {{< param "PRODUCT_NAME" >}} [components][] may optionally expose Prometheus metrics which can be used to investigate the behavior of that component. These component-specific metrics are only generated when an instance of that component is running. diff --git a/docs/sources/flow/monitoring/controller_metrics.md b/docs/sources/flow/tasks/monitor/controller_metrics.md similarity index 74% rename from docs/sources/flow/monitoring/controller_metrics.md rename to docs/sources/flow/tasks/monitor/controller_metrics.md index e0f17a2edba9..0ba7617032aa 100644 --- a/docs/sources/flow/monitoring/controller_metrics.md +++ b/docs/sources/flow/tasks/monitor/controller_metrics.md @@ -1,17 +1,24 @@ --- aliases: +- /docs/grafana-cloud/agent/flow/tasks/monitor/controller_metrics/ +- /docs/grafana-cloud/monitor-infrastructure/agent/flow/tasks/monitor/controller_metrics/ +- /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/tasks/monitor/controller_metrics/ +- /docs/grafana-cloud/send-data/agent/flow/tasks/monitor/controller_metrics/ +- controller-metrics/ # /docs/agent/latest/flow/tasks/monitor/controller-metrics/ +# Previous page aliases for backwards compatibility: - /docs/grafana-cloud/agent/flow/monitoring/controller_metrics/ - /docs/grafana-cloud/monitor-infrastructure/agent/flow/monitoring/controller_metrics/ - /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/monitoring/controller_metrics/ - /docs/grafana-cloud/send-data/agent/flow/monitoring/controller_metrics/ -- controller-metrics/ +- ../../monitoring/controller-metrics/ # /docs/agent/latest/flow/monitoring/controller-metrics/ +- ../../monitoring/controller_metrics/ # /docs/agent/latest/flow/monitoring/controller_metrics/ canonical: https://grafana.com/docs/agent/latest/flow/monitoring/controller_metrics/ -description: Learn about controller metrics -title: Controller metrics +description: Learn how to monitor controller metrics +title: Monitor controller weight: 100 --- -# Controller metrics +# How to monitor controller The {{< param "PRODUCT_NAME" >}} [component controller][] exposes Prometheus metrics which you can use to investigate the controller state. From 4cc078668e05c8d50afa7d769ffae686bbcdaa76 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jan 2024 17:22:01 +0000 Subject: [PATCH 17/68] build(deps): bump github.com/cloudflare/circl from 1.3.3 to 1.3.7 (#6066) Bumps [github.com/cloudflare/circl](https://github.com/cloudflare/circl) from 1.3.3 to 1.3.7. - [Release notes](https://github.com/cloudflare/circl/releases) - [Commits](https://github.com/cloudflare/circl/compare/v1.3.3...v1.3.7) --- updated-dependencies: - dependency-name: github.com/cloudflare/circl dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/go.mod b/go.mod index 4a42f89440db..5e98e5fb0d4c 100644 --- a/go.mod +++ b/go.mod @@ -624,7 +624,7 @@ require ( github.com/Workiva/go-datastructures v1.1.0 // indirect github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.26.0 // indirect github.com/channelmeter/iso8601duration v0.0.0-20150204201828-8da3af7a2a61 // indirect - github.com/cloudflare/circl v1.3.3 // indirect + github.com/cloudflare/circl v1.3.7 // indirect github.com/containerd/log v0.1.0 // indirect github.com/drone/envsubst v1.0.3 // indirect github.com/go-jose/go-jose/v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index b3f0d41a4a63..32c147bb135b 100644 --- a/go.sum +++ b/go.sum @@ -480,8 +480,9 @@ github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp github.com/cisco-ie/nx-telemetry-proto v0.0.0-20190531143454-82441e232cf6/go.mod h1:ugEfq4B8T8ciw/h5mCkgdiDRFS4CkqqhH2dymDB4knc= github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs= github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= +github.com/cloudflare/circl v1.3.7 h1:qlCDlTPz2n9fu58M0Nh1J/JzcFpfgkFHHX3O35r5vcU= +github.com/cloudflare/circl v1.3.7/go.mod h1:sRTcRWXGLrKw6yIGJ+l7amYJFfAXbZG0kBSc8r4zxgA= github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58 h1:F1EaeKL/ta07PY/k9Os/UFtwERei2/XzGemhpGnBKNg= github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58/go.mod h1:EOBUe0h4xcZ5GoxqC5SDxFQ8gwyZPKQoEzownBlhI80= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= From a0e0ca9dbe42045d03fd173c52e9a59da842b66e Mon Sep 17 00:00:00 2001 From: Juan Carlos Date: Mon, 8 Jan 2024 12:21:41 -0600 Subject: [PATCH 18/68] Enable sidecar containers to helm chart (#5871) --- CHANGELOG.md | 4 + .../helm/charts/grafana-agent/README.md | 1 + .../grafana-agent/ci/sidecars-values.yaml | 29 +++++ .../templates/controllers/_pod.yaml | 3 + .../helm/charts/grafana-agent/values.yaml | 3 + .../grafana-agent/templates/configmap.yaml | 42 +++++++ .../templates/controllers/daemonset.yaml | 95 ++++++++++++++ .../grafana-agent/templates/rbac.yaml | 117 ++++++++++++++++++ .../grafana-agent/templates/service.yaml | 22 ++++ .../templates/serviceaccount.yaml | 12 ++ 10 files changed, 328 insertions(+) create mode 100644 operations/helm/charts/grafana-agent/ci/sidecars-values.yaml create mode 100644 operations/helm/tests/sidecars/grafana-agent/templates/configmap.yaml create mode 100644 operations/helm/tests/sidecars/grafana-agent/templates/controllers/daemonset.yaml create mode 100644 operations/helm/tests/sidecars/grafana-agent/templates/rbac.yaml create mode 100644 operations/helm/tests/sidecars/grafana-agent/templates/service.yaml create mode 100644 operations/helm/tests/sidecars/grafana-agent/templates/serviceaccount.yaml diff --git a/CHANGELOG.md b/CHANGELOG.md index 90012924be72..774fbdd73c03 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -43,6 +43,10 @@ v0.39.0-rc.0 (2024-01-05) - A new `discovery.ovhcloud` component for discovering scrape targets on OVHcloud. (@ptodev) +### Features + +- Allow specifying additional containers to run. (@juangom) + ### Enhancements - Flow Windows service: Support environment variables. (@jkroepke) diff --git a/operations/helm/charts/grafana-agent/README.md b/operations/helm/charts/grafana-agent/README.md index 98e4219d36b5..c9c5d6df16a9 100644 --- a/operations/helm/charts/grafana-agent/README.md +++ b/operations/helm/charts/grafana-agent/README.md @@ -78,6 +78,7 @@ use the older mode (called "static mode"), set the `agent.mode` value to | controller.dnsPolicy | string | `"ClusterFirst"` | Configures the DNS policy for the pod. https://kubernetes.io/docs/concepts/services-networking/dns-pod-service/#pod-s-dns-policy | | controller.enableStatefulSetAutoDeletePVC | bool | `false` | Whether to enable automatic deletion of stale PVCs due to a scale down operation, when controller.type is 'statefulset'. | | controller.extraAnnotations | object | `{}` | Annotations to add to controller. | +| controller.extraContainers | list | `[]` | Additional containers to run alongside the agent container and initContainers. | | controller.hostNetwork | bool | `false` | Configures Pods to use the host network. When set to true, the ports that will be used must be specified. | | controller.hostPID | bool | `false` | Configures Pods to use the host PID namespace. | | controller.initContainers | list | `[]` | | diff --git a/operations/helm/charts/grafana-agent/ci/sidecars-values.yaml b/operations/helm/charts/grafana-agent/ci/sidecars-values.yaml new file mode 100644 index 000000000000..a443c9a94974 --- /dev/null +++ b/operations/helm/charts/grafana-agent/ci/sidecars-values.yaml @@ -0,0 +1,29 @@ +controller: + extraContainers: + - name: geo-ip + image: ghcr.io/maxmind/geoipupdate:v6.0 + volumeMounts: + - name: geoip + mountPath: /etc/geoip + volumes: + - name: geoip + emptyDir: {} + env: + - name: GEOIPUPDATE_ACCOUNT_ID + value: "geoipupdate_account_id" + - name: GEOIPUPDATE_LICENSE_KEY + value: "geoipupdate_license_key" + - name: GEOIPUPDATE_EDITION_IDS + value: "GeoLite2-ASN GeoLite2-City GeoLite2-Country" + - name: GEOIPUPDATE_DB_DIR + value: "/etc/geoip" + volumes: + extra: + - name: geoip + mountPath: /etc/geoip + +agent: + mounts: + extra: + - name: geoip + mountPath: /etc/geoip diff --git a/operations/helm/charts/grafana-agent/templates/controllers/_pod.yaml b/operations/helm/charts/grafana-agent/templates/controllers/_pod.yaml index 1fe0363c9232..907b5eb6bfc1 100644 --- a/operations/helm/charts/grafana-agent/templates/controllers/_pod.yaml +++ b/operations/helm/charts/grafana-agent/templates/controllers/_pod.yaml @@ -32,6 +32,9 @@ spec: containers: {{- include "grafana-agent.container" . | nindent 4 }} {{- include "grafana-agent.watch-container" . | nindent 4 }} + {{- with .Values.controller.extraContainers }} + {{- toYaml . | nindent 4 }} + {{- end}} {{- if .Values.controller.priorityClassName }} priorityClassName: {{ .Values.controller.priorityClassName }} {{- end }} diff --git a/operations/helm/charts/grafana-agent/values.yaml b/operations/helm/charts/grafana-agent/values.yaml index dd94b3b09118..254a28e69b2d 100644 --- a/operations/helm/charts/grafana-agent/values.yaml +++ b/operations/helm/charts/grafana-agent/values.yaml @@ -218,6 +218,9 @@ controller: ## initContainers: [] + # -- Additional containers to run alongside the agent container and initContainers. + extraContainers: [] + service: # -- Creates a Service for the controller's pods. enabled: true diff --git a/operations/helm/tests/sidecars/grafana-agent/templates/configmap.yaml b/operations/helm/tests/sidecars/grafana-agent/templates/configmap.yaml new file mode 100644 index 000000000000..2fdc6f011777 --- /dev/null +++ b/operations/helm/tests/sidecars/grafana-agent/templates/configmap.yaml @@ -0,0 +1,42 @@ +--- +# Source: grafana-agent/templates/configmap.yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: grafana-agent + labels: + helm.sh/chart: grafana-agent + app.kubernetes.io/name: grafana-agent + app.kubernetes.io/instance: grafana-agent + app.kubernetes.io/version: "vX.Y.Z" + app.kubernetes.io/managed-by: Helm +data: + config.river: |- + logging { + level = "info" + format = "logfmt" + } + + discovery.kubernetes "pods" { + role = "pod" + } + + discovery.kubernetes "nodes" { + role = "node" + } + + discovery.kubernetes "services" { + role = "service" + } + + discovery.kubernetes "endpoints" { + role = "endpoints" + } + + discovery.kubernetes "endpointslices" { + role = "endpointslice" + } + + discovery.kubernetes "ingresses" { + role = "ingress" + } diff --git a/operations/helm/tests/sidecars/grafana-agent/templates/controllers/daemonset.yaml b/operations/helm/tests/sidecars/grafana-agent/templates/controllers/daemonset.yaml new file mode 100644 index 000000000000..0b22a92e6773 --- /dev/null +++ b/operations/helm/tests/sidecars/grafana-agent/templates/controllers/daemonset.yaml @@ -0,0 +1,95 @@ +--- +# Source: grafana-agent/templates/controllers/daemonset.yaml +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: grafana-agent + labels: + helm.sh/chart: grafana-agent + app.kubernetes.io/name: grafana-agent + app.kubernetes.io/instance: grafana-agent + app.kubernetes.io/version: "vX.Y.Z" + app.kubernetes.io/managed-by: Helm +spec: + minReadySeconds: 10 + selector: + matchLabels: + app.kubernetes.io/name: grafana-agent + app.kubernetes.io/instance: grafana-agent + template: + metadata: + labels: + app.kubernetes.io/name: grafana-agent + app.kubernetes.io/instance: grafana-agent + spec: + serviceAccountName: grafana-agent + containers: + - name: grafana-agent + image: docker.io/grafana/agent:v0.38.1 + imagePullPolicy: IfNotPresent + args: + - run + - /etc/agent/config.river + - --storage.path=/tmp/agent + - --server.http.listen-addr=0.0.0.0:80 + - --server.http.ui-path-prefix=/ + env: + - name: AGENT_MODE + value: flow + - name: AGENT_DEPLOY_MODE + value: "helm" + - name: HOSTNAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + ports: + - containerPort: 80 + name: http-metrics + readinessProbe: + httpGet: + path: /-/ready + port: 80 + initialDelaySeconds: 10 + timeoutSeconds: 1 + volumeMounts: + - name: config + mountPath: /etc/agent + - + mountPath: /etc/geoip + name: geoip + - name: config-reloader + image: docker.io/jimmidyson/configmap-reload:v0.8.0 + args: + - --volume-dir=/etc/agent + - --webhook-url=http://localhost:80/-/reload + volumeMounts: + - name: config + mountPath: /etc/agent + resources: + requests: + cpu: 1m + memory: 5Mi + - env: + - name: GEOIPUPDATE_ACCOUNT_ID + value: geoipupdate_account_id + - name: GEOIPUPDATE_LICENSE_KEY + value: geoipupdate_license_key + - name: GEOIPUPDATE_EDITION_IDS + value: GeoLite2-ASN GeoLite2-City GeoLite2-Country + - name: GEOIPUPDATE_DB_DIR + value: /etc/geoip + image: ghcr.io/maxmind/geoipupdate:v6.0 + name: geo-ip + volumeMounts: + - mountPath: /etc/geoip + name: geoip + volumes: + - emptyDir: {} + name: geoip + dnsPolicy: ClusterFirst + volumes: + - name: config + configMap: + name: grafana-agent + - mountPath: /etc/geoip + name: geoip diff --git a/operations/helm/tests/sidecars/grafana-agent/templates/rbac.yaml b/operations/helm/tests/sidecars/grafana-agent/templates/rbac.yaml new file mode 100644 index 000000000000..3765583fb64f --- /dev/null +++ b/operations/helm/tests/sidecars/grafana-agent/templates/rbac.yaml @@ -0,0 +1,117 @@ +--- +# Source: grafana-agent/templates/rbac.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: grafana-agent + labels: + helm.sh/chart: grafana-agent + app.kubernetes.io/name: grafana-agent + app.kubernetes.io/instance: grafana-agent + app.kubernetes.io/version: "vX.Y.Z" + app.kubernetes.io/managed-by: Helm +rules: + # Rules which allow discovery.kubernetes to function. + - apiGroups: + - "" + - "discovery.k8s.io" + - "networking.k8s.io" + resources: + - endpoints + - endpointslices + - ingresses + - nodes + - nodes/proxy + - nodes/metrics + - pods + - services + verbs: + - get + - list + - watch + # Rules which allow loki.source.kubernetes and loki.source.podlogs to work. + - apiGroups: + - "" + resources: + - pods + - pods/log + - namespaces + verbs: + - get + - list + - watch + - apiGroups: + - "monitoring.grafana.com" + resources: + - podlogs + verbs: + - get + - list + - watch + # Rules which allow mimir.rules.kubernetes to work. + - apiGroups: ["monitoring.coreos.com"] + resources: + - prometheusrules + verbs: + - get + - list + - watch + - nonResourceURLs: + - /metrics + verbs: + - get + # Rules for prometheus.kubernetes.* + - apiGroups: ["monitoring.coreos.com"] + resources: + - podmonitors + - servicemonitors + - probes + verbs: + - get + - list + - watch + # Rules which allow eventhandler to work. + - apiGroups: + - "" + resources: + - events + verbs: + - get + - list + - watch + # needed for remote.kubernetes.* + - apiGroups: [""] + resources: + - "configmaps" + - "secrets" + verbs: + - get + - list + - watch + # needed for otelcol.processor.k8sattributes + - apiGroups: ["apps"] + resources: ["replicasets"] + verbs: ["get", "list", "watch"] + - apiGroups: ["extensions"] + resources: ["replicasets"] + verbs: ["get", "list", "watch"] +--- +# Source: grafana-agent/templates/rbac.yaml +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: grafana-agent + labels: + helm.sh/chart: grafana-agent + app.kubernetes.io/name: grafana-agent + app.kubernetes.io/instance: grafana-agent + app.kubernetes.io/version: "vX.Y.Z" + app.kubernetes.io/managed-by: Helm +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: grafana-agent +subjects: + - kind: ServiceAccount + name: grafana-agent + namespace: default diff --git a/operations/helm/tests/sidecars/grafana-agent/templates/service.yaml b/operations/helm/tests/sidecars/grafana-agent/templates/service.yaml new file mode 100644 index 000000000000..04f6eeff3c4d --- /dev/null +++ b/operations/helm/tests/sidecars/grafana-agent/templates/service.yaml @@ -0,0 +1,22 @@ +--- +# Source: grafana-agent/templates/service.yaml +apiVersion: v1 +kind: Service +metadata: + name: grafana-agent + labels: + helm.sh/chart: grafana-agent + app.kubernetes.io/name: grafana-agent + app.kubernetes.io/instance: grafana-agent + app.kubernetes.io/version: "vX.Y.Z" + app.kubernetes.io/managed-by: Helm +spec: + type: ClusterIP + selector: + app.kubernetes.io/name: grafana-agent + app.kubernetes.io/instance: grafana-agent + ports: + - name: http-metrics + port: 80 + targetPort: 80 + protocol: "TCP" diff --git a/operations/helm/tests/sidecars/grafana-agent/templates/serviceaccount.yaml b/operations/helm/tests/sidecars/grafana-agent/templates/serviceaccount.yaml new file mode 100644 index 000000000000..1dfd6fff9bdf --- /dev/null +++ b/operations/helm/tests/sidecars/grafana-agent/templates/serviceaccount.yaml @@ -0,0 +1,12 @@ +--- +# Source: grafana-agent/templates/serviceaccount.yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + name: grafana-agent + labels: + helm.sh/chart: grafana-agent + app.kubernetes.io/name: grafana-agent + app.kubernetes.io/instance: grafana-agent + app.kubernetes.io/version: "vX.Y.Z" + app.kubernetes.io/managed-by: Helm From b23c66edb691620857ad49ec1273a80b8c1021b3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jan 2024 13:25:23 -0500 Subject: [PATCH 19/68] build(deps-dev): bump eslint-config-prettier in /web/ui (#5908) Bumps [eslint-config-prettier](https://github.com/prettier/eslint-config-prettier) from 8.8.0 to 9.1.0. - [Changelog](https://github.com/prettier/eslint-config-prettier/blob/main/CHANGELOG.md) - [Commits](https://github.com/prettier/eslint-config-prettier/compare/v8.8.0...v9.1.0) --- updated-dependencies: - dependency-name: eslint-config-prettier dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- web/ui/package.json | 2 +- web/ui/yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/web/ui/package.json b/web/ui/package.json index 8c466a40e980..87bb50119706 100644 --- a/web/ui/package.json +++ b/web/ui/package.json @@ -22,7 +22,7 @@ "@types/react-dom": "^18.2.14", "@types/react-syntax-highlighter": "^15.5.6", "eslint": "^8.40.0", - "eslint-config-prettier": "^8.8.0", + "eslint-config-prettier": "^9.1.0", "eslint-config-react-app": "^7.0.1", "eslint-plugin-prettier": "^4.2.1", "eslint-plugin-simple-import-sort": "^10.0.0", diff --git a/web/ui/yarn.lock b/web/ui/yarn.lock index 66627484b971..60d0d721c513 100644 --- a/web/ui/yarn.lock +++ b/web/ui/yarn.lock @@ -4497,10 +4497,10 @@ escodegen@^2.0.0: optionalDependencies: source-map "~0.6.1" -eslint-config-prettier@^8.8.0: - version "8.8.0" - resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.8.0.tgz#bfda738d412adc917fd7b038857110efe98c9348" - integrity sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA== +eslint-config-prettier@^9.1.0: + version "9.1.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-9.1.0.tgz#31af3d94578645966c082fcb71a5846d3c94867f" + integrity sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw== eslint-config-react-app@^7.0.1: version "7.0.1" From 958f23ba51822cedf4cf0098f3fd7a351ee52a65 Mon Sep 17 00:00:00 2001 From: Berend Date: Mon, 8 Jan 2024 19:38:52 +0100 Subject: [PATCH 20/68] chore(deps): bump github.com/jimmidyson/configmap-reload from v0.8.0 to v0.12.0 and point to ghcr.io registry (#5920) --- operations/helm/charts/grafana-agent/CHANGELOG.md | 5 +++++ operations/helm/charts/grafana-agent/README.md | 4 ++-- operations/helm/charts/grafana-agent/values.yaml | 4 ++-- .../grafana-agent/templates/controllers/daemonset.yaml | 2 +- .../grafana-agent/templates/controllers/statefulset.yaml | 2 +- .../grafana-agent/templates/controllers/daemonset.yaml | 2 +- .../grafana-agent/templates/controllers/daemonset.yaml | 2 +- .../grafana-agent/templates/controllers/daemonset.yaml | 2 +- .../grafana-agent/templates/controllers/deployment.yaml | 2 +- .../grafana-agent/templates/controllers/deployment.yaml | 2 +- .../grafana-agent/templates/controllers/statefulset.yaml | 2 +- .../grafana-agent/templates/controllers/statefulset.yaml | 2 +- .../grafana-agent/templates/controllers/daemonset.yaml | 2 +- .../grafana-agent/templates/controllers/daemonset.yaml | 2 +- .../grafana-agent/templates/controllers/daemonset.yaml | 2 +- .../grafana-agent/templates/controllers/daemonset.yaml | 2 +- .../grafana-agent/templates/controllers/daemonset.yaml | 2 +- .../grafana-agent/templates/controllers/daemonset.yaml | 2 +- .../grafana-agent/templates/controllers/daemonset.yaml | 2 +- .../grafana-agent/templates/controllers/daemonset.yaml | 2 +- .../grafana-agent/templates/controllers/daemonset.yaml | 2 +- .../grafana-agent/templates/controllers/daemonset.yaml | 2 +- .../grafana-agent/templates/controllers/daemonset.yaml | 2 +- .../grafana-agent/templates/controllers/daemonset.yaml | 2 +- .../grafana-agent/templates/controllers/daemonset.yaml | 2 +- .../grafana-agent/templates/controllers/daemonset.yaml | 2 +- .../grafana-agent/templates/controllers/daemonset.yaml | 2 +- .../grafana-agent/templates/controllers/daemonset.yaml | 2 +- 28 files changed, 34 insertions(+), 29 deletions(-) diff --git a/operations/helm/charts/grafana-agent/CHANGELOG.md b/operations/helm/charts/grafana-agent/CHANGELOG.md index 6603ab6fb063..1d739c786eff 100644 --- a/operations/helm/charts/grafana-agent/CHANGELOG.md +++ b/operations/helm/charts/grafana-agent/CHANGELOG.md @@ -23,6 +23,11 @@ Unreleased - Statefulset should use value `.controller.enableStatefulSetAutoDeletePVC` instead of just `.enableStatefulSetAutoDeletePVC`. (@captncraig) +### Other changes + +- Change config reloader image to `ghcr.io/jimmidyson/configmap-reload:v0.12.0` to reflect change in repository and version. (@berendiwema) + + 0.29.0 (2023-11-30) ------------------- diff --git a/operations/helm/charts/grafana-agent/README.md b/operations/helm/charts/grafana-agent/README.md index c9c5d6df16a9..2423a23cbc66 100644 --- a/operations/helm/charts/grafana-agent/README.md +++ b/operations/helm/charts/grafana-agent/README.md @@ -64,9 +64,9 @@ use the older mode (called "static mode"), set the `agent.mode` value to | configReloader.customArgs | list | `[]` | Override the args passed to the container. | | configReloader.enabled | bool | `true` | Enables automatically reloading when the agent config changes. | | configReloader.image.digest | string | `""` | SHA256 digest of image to use for config reloading (either in format "sha256:XYZ" or "XYZ"). When set, will override `configReloader.image.tag` | -| configReloader.image.registry | string | `"docker.io"` | Config reloader image registry (defaults to docker.io) | +| configReloader.image.registry | string | `"ghcr.io"` | Config reloader image registry (defaults to docker.io) | | configReloader.image.repository | string | `"jimmidyson/configmap-reload"` | Repository to get config reloader image from. | -| configReloader.image.tag | string | `"v0.8.0"` | Tag of image to use for config reloading. | +| configReloader.image.tag | string | `"v0.12.0"` | Tag of image to use for config reloading. | | configReloader.resources | object | `{"requests":{"cpu":"1m","memory":"5Mi"}}` | Resource requests and limits to apply to the config reloader container. | | configReloader.securityContext | object | `{}` | Security context to apply to the Grafana configReloader container. | | controller.affinity | object | `{}` | Affinity configuration for pods. | diff --git a/operations/helm/charts/grafana-agent/values.yaml b/operations/helm/charts/grafana-agent/values.yaml index 254a28e69b2d..0143cefe1962 100644 --- a/operations/helm/charts/grafana-agent/values.yaml +++ b/operations/helm/charts/grafana-agent/values.yaml @@ -129,11 +129,11 @@ configReloader: enabled: true image: # -- Config reloader image registry (defaults to docker.io) - registry: "docker.io" + registry: "ghcr.io" # -- Repository to get config reloader image from. repository: jimmidyson/configmap-reload # -- Tag of image to use for config reloading. - tag: v0.8.0 + tag: v0.12.0 # -- SHA256 digest of image to use for config reloading (either in format "sha256:XYZ" or "XYZ"). When set, will override `configReloader.image.tag` digest: "" # -- Override the args passed to the container. diff --git a/operations/helm/tests/additional-serviceaccount-label/grafana-agent/templates/controllers/daemonset.yaml b/operations/helm/tests/additional-serviceaccount-label/grafana-agent/templates/controllers/daemonset.yaml index 7ac89ceb865a..4a6e72f132cf 100644 --- a/operations/helm/tests/additional-serviceaccount-label/grafana-agent/templates/controllers/daemonset.yaml +++ b/operations/helm/tests/additional-serviceaccount-label/grafana-agent/templates/controllers/daemonset.yaml @@ -55,7 +55,7 @@ spec: - name: config mountPath: /etc/agent - name: config-reloader - image: docker.io/jimmidyson/configmap-reload:v0.8.0 + image: ghcr.io/jimmidyson/configmap-reload:v0.12.0 args: - --volume-dir=/etc/agent - --webhook-url=http://localhost:80/-/reload diff --git a/operations/helm/tests/clustering/grafana-agent/templates/controllers/statefulset.yaml b/operations/helm/tests/clustering/grafana-agent/templates/controllers/statefulset.yaml index 92ad19130040..af3b0c1fd7e4 100644 --- a/operations/helm/tests/clustering/grafana-agent/templates/controllers/statefulset.yaml +++ b/operations/helm/tests/clustering/grafana-agent/templates/controllers/statefulset.yaml @@ -60,7 +60,7 @@ spec: - name: config mountPath: /etc/agent - name: config-reloader - image: docker.io/jimmidyson/configmap-reload:v0.8.0 + image: ghcr.io/jimmidyson/configmap-reload:v0.12.0 args: - --volume-dir=/etc/agent - --webhook-url=http://localhost:80/-/reload diff --git a/operations/helm/tests/controller-volumes-extra/grafana-agent/templates/controllers/daemonset.yaml b/operations/helm/tests/controller-volumes-extra/grafana-agent/templates/controllers/daemonset.yaml index 39aa9491fa20..ef17189995f4 100644 --- a/operations/helm/tests/controller-volumes-extra/grafana-agent/templates/controllers/daemonset.yaml +++ b/operations/helm/tests/controller-volumes-extra/grafana-agent/templates/controllers/daemonset.yaml @@ -58,7 +58,7 @@ spec: mountPath: /cache name: cache-volume - name: config-reloader - image: docker.io/jimmidyson/configmap-reload:v0.8.0 + image: ghcr.io/jimmidyson/configmap-reload:v0.12.0 args: - --volume-dir=/etc/agent - --webhook-url=http://localhost:80/-/reload diff --git a/operations/helm/tests/create-daemonset-hostnetwork/grafana-agent/templates/controllers/daemonset.yaml b/operations/helm/tests/create-daemonset-hostnetwork/grafana-agent/templates/controllers/daemonset.yaml index 74c228870934..b43c8b537889 100644 --- a/operations/helm/tests/create-daemonset-hostnetwork/grafana-agent/templates/controllers/daemonset.yaml +++ b/operations/helm/tests/create-daemonset-hostnetwork/grafana-agent/templates/controllers/daemonset.yaml @@ -55,7 +55,7 @@ spec: - name: config mountPath: /etc/agent - name: config-reloader - image: docker.io/jimmidyson/configmap-reload:v0.8.0 + image: ghcr.io/jimmidyson/configmap-reload:v0.12.0 args: - --volume-dir=/etc/agent - --webhook-url=http://localhost:80/-/reload diff --git a/operations/helm/tests/create-daemonset/grafana-agent/templates/controllers/daemonset.yaml b/operations/helm/tests/create-daemonset/grafana-agent/templates/controllers/daemonset.yaml index 7ac89ceb865a..4a6e72f132cf 100644 --- a/operations/helm/tests/create-daemonset/grafana-agent/templates/controllers/daemonset.yaml +++ b/operations/helm/tests/create-daemonset/grafana-agent/templates/controllers/daemonset.yaml @@ -55,7 +55,7 @@ spec: - name: config mountPath: /etc/agent - name: config-reloader - image: docker.io/jimmidyson/configmap-reload:v0.8.0 + image: ghcr.io/jimmidyson/configmap-reload:v0.12.0 args: - --volume-dir=/etc/agent - --webhook-url=http://localhost:80/-/reload diff --git a/operations/helm/tests/create-deployment-autoscaling/grafana-agent/templates/controllers/deployment.yaml b/operations/helm/tests/create-deployment-autoscaling/grafana-agent/templates/controllers/deployment.yaml index 478a47d32f56..74959bc95b9e 100644 --- a/operations/helm/tests/create-deployment-autoscaling/grafana-agent/templates/controllers/deployment.yaml +++ b/operations/helm/tests/create-deployment-autoscaling/grafana-agent/templates/controllers/deployment.yaml @@ -58,7 +58,7 @@ spec: - name: config mountPath: /etc/agent - name: config-reloader - image: docker.io/jimmidyson/configmap-reload:v0.8.0 + image: ghcr.io/jimmidyson/configmap-reload:v0.12.0 args: - --volume-dir=/etc/agent - --webhook-url=http://localhost:80/-/reload diff --git a/operations/helm/tests/create-deployment/grafana-agent/templates/controllers/deployment.yaml b/operations/helm/tests/create-deployment/grafana-agent/templates/controllers/deployment.yaml index 8fbd88183c0f..e6b30b603cd8 100644 --- a/operations/helm/tests/create-deployment/grafana-agent/templates/controllers/deployment.yaml +++ b/operations/helm/tests/create-deployment/grafana-agent/templates/controllers/deployment.yaml @@ -56,7 +56,7 @@ spec: - name: config mountPath: /etc/agent - name: config-reloader - image: docker.io/jimmidyson/configmap-reload:v0.8.0 + image: ghcr.io/jimmidyson/configmap-reload:v0.12.0 args: - --volume-dir=/etc/agent - --webhook-url=http://localhost:80/-/reload diff --git a/operations/helm/tests/create-statefulset-autoscaling/grafana-agent/templates/controllers/statefulset.yaml b/operations/helm/tests/create-statefulset-autoscaling/grafana-agent/templates/controllers/statefulset.yaml index 06151482680e..9ad9d83989c9 100644 --- a/operations/helm/tests/create-statefulset-autoscaling/grafana-agent/templates/controllers/statefulset.yaml +++ b/operations/helm/tests/create-statefulset-autoscaling/grafana-agent/templates/controllers/statefulset.yaml @@ -60,7 +60,7 @@ spec: - name: config mountPath: /etc/agent - name: config-reloader - image: docker.io/jimmidyson/configmap-reload:v0.8.0 + image: ghcr.io/jimmidyson/configmap-reload:v0.12.0 args: - --volume-dir=/etc/agent - --webhook-url=http://localhost:80/-/reload diff --git a/operations/helm/tests/create-statefulset/grafana-agent/templates/controllers/statefulset.yaml b/operations/helm/tests/create-statefulset/grafana-agent/templates/controllers/statefulset.yaml index cfaf3fa7aa65..14069e356960 100644 --- a/operations/helm/tests/create-statefulset/grafana-agent/templates/controllers/statefulset.yaml +++ b/operations/helm/tests/create-statefulset/grafana-agent/templates/controllers/statefulset.yaml @@ -58,7 +58,7 @@ spec: - name: config mountPath: /etc/agent - name: config-reloader - image: docker.io/jimmidyson/configmap-reload:v0.8.0 + image: ghcr.io/jimmidyson/configmap-reload:v0.12.0 args: - --volume-dir=/etc/agent - --webhook-url=http://localhost:80/-/reload diff --git a/operations/helm/tests/custom-config/grafana-agent/templates/controllers/daemonset.yaml b/operations/helm/tests/custom-config/grafana-agent/templates/controllers/daemonset.yaml index 7ac89ceb865a..4a6e72f132cf 100644 --- a/operations/helm/tests/custom-config/grafana-agent/templates/controllers/daemonset.yaml +++ b/operations/helm/tests/custom-config/grafana-agent/templates/controllers/daemonset.yaml @@ -55,7 +55,7 @@ spec: - name: config mountPath: /etc/agent - name: config-reloader - image: docker.io/jimmidyson/configmap-reload:v0.8.0 + image: ghcr.io/jimmidyson/configmap-reload:v0.12.0 args: - --volume-dir=/etc/agent - --webhook-url=http://localhost:80/-/reload diff --git a/operations/helm/tests/default-values/grafana-agent/templates/controllers/daemonset.yaml b/operations/helm/tests/default-values/grafana-agent/templates/controllers/daemonset.yaml index 7ac89ceb865a..4a6e72f132cf 100644 --- a/operations/helm/tests/default-values/grafana-agent/templates/controllers/daemonset.yaml +++ b/operations/helm/tests/default-values/grafana-agent/templates/controllers/daemonset.yaml @@ -55,7 +55,7 @@ spec: - name: config mountPath: /etc/agent - name: config-reloader - image: docker.io/jimmidyson/configmap-reload:v0.8.0 + image: ghcr.io/jimmidyson/configmap-reload:v0.12.0 args: - --volume-dir=/etc/agent - --webhook-url=http://localhost:80/-/reload diff --git a/operations/helm/tests/enable-servicemonitor/grafana-agent/templates/controllers/daemonset.yaml b/operations/helm/tests/enable-servicemonitor/grafana-agent/templates/controllers/daemonset.yaml index 7ac89ceb865a..4a6e72f132cf 100644 --- a/operations/helm/tests/enable-servicemonitor/grafana-agent/templates/controllers/daemonset.yaml +++ b/operations/helm/tests/enable-servicemonitor/grafana-agent/templates/controllers/daemonset.yaml @@ -55,7 +55,7 @@ spec: - name: config mountPath: /etc/agent - name: config-reloader - image: docker.io/jimmidyson/configmap-reload:v0.8.0 + image: ghcr.io/jimmidyson/configmap-reload:v0.12.0 args: - --volume-dir=/etc/agent - --webhook-url=http://localhost:80/-/reload diff --git a/operations/helm/tests/envFrom/grafana-agent/templates/controllers/daemonset.yaml b/operations/helm/tests/envFrom/grafana-agent/templates/controllers/daemonset.yaml index 2d5c5f77964a..47e8370cba61 100644 --- a/operations/helm/tests/envFrom/grafana-agent/templates/controllers/daemonset.yaml +++ b/operations/helm/tests/envFrom/grafana-agent/templates/controllers/daemonset.yaml @@ -58,7 +58,7 @@ spec: - name: config mountPath: /etc/agent - name: config-reloader - image: docker.io/jimmidyson/configmap-reload:v0.8.0 + image: ghcr.io/jimmidyson/configmap-reload:v0.12.0 args: - --volume-dir=/etc/agent - --webhook-url=http://localhost:80/-/reload diff --git a/operations/helm/tests/existing-config/grafana-agent/templates/controllers/daemonset.yaml b/operations/helm/tests/existing-config/grafana-agent/templates/controllers/daemonset.yaml index 683d4c72adce..204bc2f541ff 100644 --- a/operations/helm/tests/existing-config/grafana-agent/templates/controllers/daemonset.yaml +++ b/operations/helm/tests/existing-config/grafana-agent/templates/controllers/daemonset.yaml @@ -55,7 +55,7 @@ spec: - name: config mountPath: /etc/agent - name: config-reloader - image: docker.io/jimmidyson/configmap-reload:v0.8.0 + image: ghcr.io/jimmidyson/configmap-reload:v0.12.0 args: - --volume-dir=/etc/agent - --webhook-url=http://localhost:80/-/reload diff --git a/operations/helm/tests/extra-env/grafana-agent/templates/controllers/daemonset.yaml b/operations/helm/tests/extra-env/grafana-agent/templates/controllers/daemonset.yaml index ff83778a94a9..a68d13450e34 100644 --- a/operations/helm/tests/extra-env/grafana-agent/templates/controllers/daemonset.yaml +++ b/operations/helm/tests/extra-env/grafana-agent/templates/controllers/daemonset.yaml @@ -64,7 +64,7 @@ spec: - name: config mountPath: /etc/agent - name: config-reloader - image: docker.io/jimmidyson/configmap-reload:v0.8.0 + image: ghcr.io/jimmidyson/configmap-reload:v0.12.0 args: - --volume-dir=/etc/agent - --webhook-url=http://localhost:80/-/reload diff --git a/operations/helm/tests/extra-ports/grafana-agent/templates/controllers/daemonset.yaml b/operations/helm/tests/extra-ports/grafana-agent/templates/controllers/daemonset.yaml index 4566af378b4c..4b2b1c4bad5c 100644 --- a/operations/helm/tests/extra-ports/grafana-agent/templates/controllers/daemonset.yaml +++ b/operations/helm/tests/extra-ports/grafana-agent/templates/controllers/daemonset.yaml @@ -58,7 +58,7 @@ spec: - name: config mountPath: /etc/agent - name: config-reloader - image: docker.io/jimmidyson/configmap-reload:v0.8.0 + image: ghcr.io/jimmidyson/configmap-reload:v0.12.0 args: - --volume-dir=/etc/agent - --webhook-url=http://localhost:80/-/reload diff --git a/operations/helm/tests/faro-ingress/grafana-agent/templates/controllers/daemonset.yaml b/operations/helm/tests/faro-ingress/grafana-agent/templates/controllers/daemonset.yaml index cb4f0c8964f6..c4d490e0fc70 100644 --- a/operations/helm/tests/faro-ingress/grafana-agent/templates/controllers/daemonset.yaml +++ b/operations/helm/tests/faro-ingress/grafana-agent/templates/controllers/daemonset.yaml @@ -58,7 +58,7 @@ spec: - name: config mountPath: /etc/agent - name: config-reloader - image: docker.io/jimmidyson/configmap-reload:v0.8.0 + image: ghcr.io/jimmidyson/configmap-reload:v0.12.0 args: - --volume-dir=/etc/agent - --webhook-url=http://localhost:80/-/reload diff --git a/operations/helm/tests/global-image-pullsecrets/grafana-agent/templates/controllers/daemonset.yaml b/operations/helm/tests/global-image-pullsecrets/grafana-agent/templates/controllers/daemonset.yaml index e229da2bf950..1a6efea09785 100644 --- a/operations/helm/tests/global-image-pullsecrets/grafana-agent/templates/controllers/daemonset.yaml +++ b/operations/helm/tests/global-image-pullsecrets/grafana-agent/templates/controllers/daemonset.yaml @@ -60,7 +60,7 @@ spec: - name: config mountPath: /etc/agent - name: config-reloader - image: docker.io/jimmidyson/configmap-reload:v0.8.0 + image: ghcr.io/jimmidyson/configmap-reload:v0.12.0 args: - --volume-dir=/etc/agent - --webhook-url=http://localhost:80/-/reload diff --git a/operations/helm/tests/global-image-registry/grafana-agent/templates/controllers/daemonset.yaml b/operations/helm/tests/global-image-registry/grafana-agent/templates/controllers/daemonset.yaml index 09768a686b48..692304acd2f1 100644 --- a/operations/helm/tests/global-image-registry/grafana-agent/templates/controllers/daemonset.yaml +++ b/operations/helm/tests/global-image-registry/grafana-agent/templates/controllers/daemonset.yaml @@ -55,7 +55,7 @@ spec: - name: config mountPath: /etc/agent - name: config-reloader - image: quay.io/jimmidyson/configmap-reload:v0.8.0 + image: quay.io/jimmidyson/configmap-reload:v0.12.0 args: - --volume-dir=/etc/agent - --webhook-url=http://localhost:80/-/reload diff --git a/operations/helm/tests/initcontainers/grafana-agent/templates/controllers/daemonset.yaml b/operations/helm/tests/initcontainers/grafana-agent/templates/controllers/daemonset.yaml index 512c32eece2e..ccf576637bed 100644 --- a/operations/helm/tests/initcontainers/grafana-agent/templates/controllers/daemonset.yaml +++ b/operations/helm/tests/initcontainers/grafana-agent/templates/controllers/daemonset.yaml @@ -76,7 +76,7 @@ spec: mountPath: /etc/geoip name: geoip - name: config-reloader - image: docker.io/jimmidyson/configmap-reload:v0.8.0 + image: ghcr.io/jimmidyson/configmap-reload:v0.12.0 args: - --volume-dir=/etc/agent - --webhook-url=http://localhost:80/-/reload diff --git a/operations/helm/tests/local-image-pullsecrets/grafana-agent/templates/controllers/daemonset.yaml b/operations/helm/tests/local-image-pullsecrets/grafana-agent/templates/controllers/daemonset.yaml index c3a0fb4cafe1..9aa16540da65 100644 --- a/operations/helm/tests/local-image-pullsecrets/grafana-agent/templates/controllers/daemonset.yaml +++ b/operations/helm/tests/local-image-pullsecrets/grafana-agent/templates/controllers/daemonset.yaml @@ -57,7 +57,7 @@ spec: - name: config mountPath: /etc/agent - name: config-reloader - image: docker.io/jimmidyson/configmap-reload:v0.8.0 + image: ghcr.io/jimmidyson/configmap-reload:v0.12.0 args: - --volume-dir=/etc/agent - --webhook-url=http://localhost:80/-/reload diff --git a/operations/helm/tests/local-image-registry/grafana-agent/templates/controllers/daemonset.yaml b/operations/helm/tests/local-image-registry/grafana-agent/templates/controllers/daemonset.yaml index 09768a686b48..692304acd2f1 100644 --- a/operations/helm/tests/local-image-registry/grafana-agent/templates/controllers/daemonset.yaml +++ b/operations/helm/tests/local-image-registry/grafana-agent/templates/controllers/daemonset.yaml @@ -55,7 +55,7 @@ spec: - name: config mountPath: /etc/agent - name: config-reloader - image: quay.io/jimmidyson/configmap-reload:v0.8.0 + image: quay.io/jimmidyson/configmap-reload:v0.12.0 args: - --volume-dir=/etc/agent - --webhook-url=http://localhost:80/-/reload diff --git a/operations/helm/tests/nodeselectors-and-tolerations/grafana-agent/templates/controllers/daemonset.yaml b/operations/helm/tests/nodeselectors-and-tolerations/grafana-agent/templates/controllers/daemonset.yaml index 6de1e5ad8593..8cb19e413aa5 100644 --- a/operations/helm/tests/nodeselectors-and-tolerations/grafana-agent/templates/controllers/daemonset.yaml +++ b/operations/helm/tests/nodeselectors-and-tolerations/grafana-agent/templates/controllers/daemonset.yaml @@ -55,7 +55,7 @@ spec: - name: config mountPath: /etc/agent - name: config-reloader - image: docker.io/jimmidyson/configmap-reload:v0.8.0 + image: ghcr.io/jimmidyson/configmap-reload:v0.12.0 args: - --volume-dir=/etc/agent - --webhook-url=http://localhost:80/-/reload diff --git a/operations/helm/tests/sidecars/grafana-agent/templates/controllers/daemonset.yaml b/operations/helm/tests/sidecars/grafana-agent/templates/controllers/daemonset.yaml index 0b22a92e6773..f2d72440edf6 100644 --- a/operations/helm/tests/sidecars/grafana-agent/templates/controllers/daemonset.yaml +++ b/operations/helm/tests/sidecars/grafana-agent/templates/controllers/daemonset.yaml @@ -58,7 +58,7 @@ spec: mountPath: /etc/geoip name: geoip - name: config-reloader - image: docker.io/jimmidyson/configmap-reload:v0.8.0 + image: ghcr.io/jimmidyson/configmap-reload:v0.12.0 args: - --volume-dir=/etc/agent - --webhook-url=http://localhost:80/-/reload diff --git a/operations/helm/tests/static-mode/grafana-agent/templates/controllers/daemonset.yaml b/operations/helm/tests/static-mode/grafana-agent/templates/controllers/daemonset.yaml index aedb6a176381..34b4d0a38504 100644 --- a/operations/helm/tests/static-mode/grafana-agent/templates/controllers/daemonset.yaml +++ b/operations/helm/tests/static-mode/grafana-agent/templates/controllers/daemonset.yaml @@ -52,7 +52,7 @@ spec: - name: config mountPath: /etc/agent - name: config-reloader - image: docker.io/jimmidyson/configmap-reload:v0.8.0 + image: ghcr.io/jimmidyson/configmap-reload:v0.12.0 args: - --volume-dir=/etc/agent - --webhook-url=http://localhost:80/-/reload From a3c26178f7bde727673763232304e0b81656887d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jan 2024 13:44:23 -0500 Subject: [PATCH 21/68] build(deps): bump actions/setup-go from 4 to 5 (#5952) Bumps [actions/setup-go](https://github.com/actions/setup-go) from 4 to 5. - [Release notes](https://github.com/actions/setup-go/releases) - [Commits](https://github.com/actions/setup-go/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/setup-go dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/integration-tests.yml | 2 +- .github/workflows/test.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 80540ae4848e..4b9f7077ed57 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -14,7 +14,7 @@ jobs: - name: Checkout code uses: actions/checkout@v4 - name: Setup Go - uses: actions/setup-go@v4 + uses: actions/setup-go@v5 with: go-version: "1.21" - name: Set OTEL Exporter Endpoint diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 229de6f55dbe..59d4fbe34540 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -18,7 +18,7 @@ jobs: - name: Checkout code uses: actions/checkout@v4 - name: Set up Go 1.21 - uses: actions/setup-go@v4 + uses: actions/setup-go@v5 with: go-version: "1.21" cache: true From 5be7184590f329f7915b831cd8909196dced447d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jan 2024 13:44:45 -0500 Subject: [PATCH 22/68] build(deps): bump actions/setup-python from 4 to 5 (#5954) Bumps [actions/setup-python](https://github.com/actions/setup-python) from 4 to 5. - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](https://github.com/actions/setup-python/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/setup-python dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/helm-test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/helm-test.yml b/.github/workflows/helm-test.yml index 20a3745c8fe1..9d4738bcd6cb 100644 --- a/.github/workflows/helm-test.yml +++ b/.github/workflows/helm-test.yml @@ -51,7 +51,7 @@ jobs: version: v3.10.3 - name: Install Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.9' check-latest: true From 9e6545d5a816ad51f222c10a44ea1668a4ef1f38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=90=E1=BB=97=20Tr=E1=BB=8Dng=20H=E1=BA=A3i?= <41283691+hainenber@users.noreply.github.com> Date: Tue, 9 Jan 2024 01:45:54 +0700 Subject: [PATCH 23/68] feat(helm/chart/template): set namespace for RBAC's service account (#6061) Signed-off-by: hainenber --- operations/helm/charts/grafana-agent/CHANGELOG.md | 13 ++++++++----- .../grafana-agent/templates/serviceaccount.yaml | 1 + .../grafana-agent/templates/serviceaccount.yaml | 1 + .../grafana-agent/templates/serviceaccount.yaml | 1 + .../grafana-agent/templates/serviceaccount.yaml | 1 + .../grafana-agent/templates/serviceaccount.yaml | 1 + .../grafana-agent/templates/serviceaccount.yaml | 1 + .../grafana-agent/templates/serviceaccount.yaml | 1 + .../grafana-agent/templates/serviceaccount.yaml | 1 + .../grafana-agent/templates/serviceaccount.yaml | 1 + .../grafana-agent/templates/serviceaccount.yaml | 1 + .../grafana-agent/templates/serviceaccount.yaml | 1 + .../grafana-agent/templates/serviceaccount.yaml | 1 + .../grafana-agent/templates/serviceaccount.yaml | 1 + .../grafana-agent/templates/serviceaccount.yaml | 1 + .../grafana-agent/templates/serviceaccount.yaml | 1 + .../grafana-agent/templates/serviceaccount.yaml | 1 + .../grafana-agent/templates/serviceaccount.yaml | 1 + .../grafana-agent/templates/serviceaccount.yaml | 1 + .../grafana-agent/templates/serviceaccount.yaml | 1 + .../grafana-agent/templates/serviceaccount.yaml | 1 + .../grafana-agent/templates/serviceaccount.yaml | 1 + .../grafana-agent/templates/serviceaccount.yaml | 1 + .../grafana-agent/templates/serviceaccount.yaml | 1 + .../grafana-agent/templates/serviceaccount.yaml | 1 + .../grafana-agent/templates/serviceaccount.yaml | 1 + .../grafana-agent/templates/serviceaccount.yaml | 1 + 27 files changed, 34 insertions(+), 5 deletions(-) diff --git a/operations/helm/charts/grafana-agent/CHANGELOG.md b/operations/helm/charts/grafana-agent/CHANGELOG.md index 1d739c786eff..5fdfcb54ba54 100644 --- a/operations/helm/charts/grafana-agent/CHANGELOG.md +++ b/operations/helm/charts/grafana-agent/CHANGELOG.md @@ -10,6 +10,14 @@ internal API changes are not present. Unreleased ---------- +### Bugfixes + +- Configure namespace for service account when RBAC resources is created. (@hainenber) + +### Other changes + +- Change config reloader image to `ghcr.io/jimmidyson/configmap-reload:v0.12.0` to reflect change in repository and version. (@berendiwema) + 0.30.0 (2024-01-05) ------------------- @@ -23,11 +31,6 @@ Unreleased - Statefulset should use value `.controller.enableStatefulSetAutoDeletePVC` instead of just `.enableStatefulSetAutoDeletePVC`. (@captncraig) -### Other changes - -- Change config reloader image to `ghcr.io/jimmidyson/configmap-reload:v0.12.0` to reflect change in repository and version. (@berendiwema) - - 0.29.0 (2023-11-30) ------------------- diff --git a/operations/helm/charts/grafana-agent/templates/serviceaccount.yaml b/operations/helm/charts/grafana-agent/templates/serviceaccount.yaml index 766201635e77..f2d2c90c6ec6 100644 --- a/operations/helm/charts/grafana-agent/templates/serviceaccount.yaml +++ b/operations/helm/charts/grafana-agent/templates/serviceaccount.yaml @@ -3,6 +3,7 @@ apiVersion: v1 kind: ServiceAccount metadata: name: {{ include "grafana-agent.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} labels: {{- include "grafana-agent.labels" . | nindent 4 }} {{- with .Values.serviceAccount.additionalLabels }} diff --git a/operations/helm/tests/additional-serviceaccount-label/grafana-agent/templates/serviceaccount.yaml b/operations/helm/tests/additional-serviceaccount-label/grafana-agent/templates/serviceaccount.yaml index ba80344cee51..08eca9f756b2 100644 --- a/operations/helm/tests/additional-serviceaccount-label/grafana-agent/templates/serviceaccount.yaml +++ b/operations/helm/tests/additional-serviceaccount-label/grafana-agent/templates/serviceaccount.yaml @@ -4,6 +4,7 @@ apiVersion: v1 kind: ServiceAccount metadata: name: grafana-agent + namespace: default labels: helm.sh/chart: grafana-agent app.kubernetes.io/name: grafana-agent diff --git a/operations/helm/tests/clustering/grafana-agent/templates/serviceaccount.yaml b/operations/helm/tests/clustering/grafana-agent/templates/serviceaccount.yaml index 1dfd6fff9bdf..65d7e0df383f 100644 --- a/operations/helm/tests/clustering/grafana-agent/templates/serviceaccount.yaml +++ b/operations/helm/tests/clustering/grafana-agent/templates/serviceaccount.yaml @@ -4,6 +4,7 @@ apiVersion: v1 kind: ServiceAccount metadata: name: grafana-agent + namespace: default labels: helm.sh/chart: grafana-agent app.kubernetes.io/name: grafana-agent diff --git a/operations/helm/tests/controller-volumes-extra/grafana-agent/templates/serviceaccount.yaml b/operations/helm/tests/controller-volumes-extra/grafana-agent/templates/serviceaccount.yaml index 1dfd6fff9bdf..65d7e0df383f 100644 --- a/operations/helm/tests/controller-volumes-extra/grafana-agent/templates/serviceaccount.yaml +++ b/operations/helm/tests/controller-volumes-extra/grafana-agent/templates/serviceaccount.yaml @@ -4,6 +4,7 @@ apiVersion: v1 kind: ServiceAccount metadata: name: grafana-agent + namespace: default labels: helm.sh/chart: grafana-agent app.kubernetes.io/name: grafana-agent diff --git a/operations/helm/tests/create-daemonset-hostnetwork/grafana-agent/templates/serviceaccount.yaml b/operations/helm/tests/create-daemonset-hostnetwork/grafana-agent/templates/serviceaccount.yaml index 1dfd6fff9bdf..65d7e0df383f 100644 --- a/operations/helm/tests/create-daemonset-hostnetwork/grafana-agent/templates/serviceaccount.yaml +++ b/operations/helm/tests/create-daemonset-hostnetwork/grafana-agent/templates/serviceaccount.yaml @@ -4,6 +4,7 @@ apiVersion: v1 kind: ServiceAccount metadata: name: grafana-agent + namespace: default labels: helm.sh/chart: grafana-agent app.kubernetes.io/name: grafana-agent diff --git a/operations/helm/tests/create-daemonset/grafana-agent/templates/serviceaccount.yaml b/operations/helm/tests/create-daemonset/grafana-agent/templates/serviceaccount.yaml index 1dfd6fff9bdf..65d7e0df383f 100644 --- a/operations/helm/tests/create-daemonset/grafana-agent/templates/serviceaccount.yaml +++ b/operations/helm/tests/create-daemonset/grafana-agent/templates/serviceaccount.yaml @@ -4,6 +4,7 @@ apiVersion: v1 kind: ServiceAccount metadata: name: grafana-agent + namespace: default labels: helm.sh/chart: grafana-agent app.kubernetes.io/name: grafana-agent diff --git a/operations/helm/tests/create-deployment-autoscaling/grafana-agent/templates/serviceaccount.yaml b/operations/helm/tests/create-deployment-autoscaling/grafana-agent/templates/serviceaccount.yaml index 1dfd6fff9bdf..65d7e0df383f 100644 --- a/operations/helm/tests/create-deployment-autoscaling/grafana-agent/templates/serviceaccount.yaml +++ b/operations/helm/tests/create-deployment-autoscaling/grafana-agent/templates/serviceaccount.yaml @@ -4,6 +4,7 @@ apiVersion: v1 kind: ServiceAccount metadata: name: grafana-agent + namespace: default labels: helm.sh/chart: grafana-agent app.kubernetes.io/name: grafana-agent diff --git a/operations/helm/tests/create-deployment/grafana-agent/templates/serviceaccount.yaml b/operations/helm/tests/create-deployment/grafana-agent/templates/serviceaccount.yaml index 1dfd6fff9bdf..65d7e0df383f 100644 --- a/operations/helm/tests/create-deployment/grafana-agent/templates/serviceaccount.yaml +++ b/operations/helm/tests/create-deployment/grafana-agent/templates/serviceaccount.yaml @@ -4,6 +4,7 @@ apiVersion: v1 kind: ServiceAccount metadata: name: grafana-agent + namespace: default labels: helm.sh/chart: grafana-agent app.kubernetes.io/name: grafana-agent diff --git a/operations/helm/tests/create-statefulset-autoscaling/grafana-agent/templates/serviceaccount.yaml b/operations/helm/tests/create-statefulset-autoscaling/grafana-agent/templates/serviceaccount.yaml index 1dfd6fff9bdf..65d7e0df383f 100644 --- a/operations/helm/tests/create-statefulset-autoscaling/grafana-agent/templates/serviceaccount.yaml +++ b/operations/helm/tests/create-statefulset-autoscaling/grafana-agent/templates/serviceaccount.yaml @@ -4,6 +4,7 @@ apiVersion: v1 kind: ServiceAccount metadata: name: grafana-agent + namespace: default labels: helm.sh/chart: grafana-agent app.kubernetes.io/name: grafana-agent diff --git a/operations/helm/tests/create-statefulset/grafana-agent/templates/serviceaccount.yaml b/operations/helm/tests/create-statefulset/grafana-agent/templates/serviceaccount.yaml index 1dfd6fff9bdf..65d7e0df383f 100644 --- a/operations/helm/tests/create-statefulset/grafana-agent/templates/serviceaccount.yaml +++ b/operations/helm/tests/create-statefulset/grafana-agent/templates/serviceaccount.yaml @@ -4,6 +4,7 @@ apiVersion: v1 kind: ServiceAccount metadata: name: grafana-agent + namespace: default labels: helm.sh/chart: grafana-agent app.kubernetes.io/name: grafana-agent diff --git a/operations/helm/tests/custom-config/grafana-agent/templates/serviceaccount.yaml b/operations/helm/tests/custom-config/grafana-agent/templates/serviceaccount.yaml index 1dfd6fff9bdf..65d7e0df383f 100644 --- a/operations/helm/tests/custom-config/grafana-agent/templates/serviceaccount.yaml +++ b/operations/helm/tests/custom-config/grafana-agent/templates/serviceaccount.yaml @@ -4,6 +4,7 @@ apiVersion: v1 kind: ServiceAccount metadata: name: grafana-agent + namespace: default labels: helm.sh/chart: grafana-agent app.kubernetes.io/name: grafana-agent diff --git a/operations/helm/tests/default-values/grafana-agent/templates/serviceaccount.yaml b/operations/helm/tests/default-values/grafana-agent/templates/serviceaccount.yaml index 1dfd6fff9bdf..65d7e0df383f 100644 --- a/operations/helm/tests/default-values/grafana-agent/templates/serviceaccount.yaml +++ b/operations/helm/tests/default-values/grafana-agent/templates/serviceaccount.yaml @@ -4,6 +4,7 @@ apiVersion: v1 kind: ServiceAccount metadata: name: grafana-agent + namespace: default labels: helm.sh/chart: grafana-agent app.kubernetes.io/name: grafana-agent diff --git a/operations/helm/tests/enable-servicemonitor/grafana-agent/templates/serviceaccount.yaml b/operations/helm/tests/enable-servicemonitor/grafana-agent/templates/serviceaccount.yaml index 1dfd6fff9bdf..65d7e0df383f 100644 --- a/operations/helm/tests/enable-servicemonitor/grafana-agent/templates/serviceaccount.yaml +++ b/operations/helm/tests/enable-servicemonitor/grafana-agent/templates/serviceaccount.yaml @@ -4,6 +4,7 @@ apiVersion: v1 kind: ServiceAccount metadata: name: grafana-agent + namespace: default labels: helm.sh/chart: grafana-agent app.kubernetes.io/name: grafana-agent diff --git a/operations/helm/tests/envFrom/grafana-agent/templates/serviceaccount.yaml b/operations/helm/tests/envFrom/grafana-agent/templates/serviceaccount.yaml index 1dfd6fff9bdf..65d7e0df383f 100644 --- a/operations/helm/tests/envFrom/grafana-agent/templates/serviceaccount.yaml +++ b/operations/helm/tests/envFrom/grafana-agent/templates/serviceaccount.yaml @@ -4,6 +4,7 @@ apiVersion: v1 kind: ServiceAccount metadata: name: grafana-agent + namespace: default labels: helm.sh/chart: grafana-agent app.kubernetes.io/name: grafana-agent diff --git a/operations/helm/tests/existing-config/grafana-agent/templates/serviceaccount.yaml b/operations/helm/tests/existing-config/grafana-agent/templates/serviceaccount.yaml index 1dfd6fff9bdf..65d7e0df383f 100644 --- a/operations/helm/tests/existing-config/grafana-agent/templates/serviceaccount.yaml +++ b/operations/helm/tests/existing-config/grafana-agent/templates/serviceaccount.yaml @@ -4,6 +4,7 @@ apiVersion: v1 kind: ServiceAccount metadata: name: grafana-agent + namespace: default labels: helm.sh/chart: grafana-agent app.kubernetes.io/name: grafana-agent diff --git a/operations/helm/tests/extra-env/grafana-agent/templates/serviceaccount.yaml b/operations/helm/tests/extra-env/grafana-agent/templates/serviceaccount.yaml index 1dfd6fff9bdf..65d7e0df383f 100644 --- a/operations/helm/tests/extra-env/grafana-agent/templates/serviceaccount.yaml +++ b/operations/helm/tests/extra-env/grafana-agent/templates/serviceaccount.yaml @@ -4,6 +4,7 @@ apiVersion: v1 kind: ServiceAccount metadata: name: grafana-agent + namespace: default labels: helm.sh/chart: grafana-agent app.kubernetes.io/name: grafana-agent diff --git a/operations/helm/tests/extra-ports/grafana-agent/templates/serviceaccount.yaml b/operations/helm/tests/extra-ports/grafana-agent/templates/serviceaccount.yaml index 1dfd6fff9bdf..65d7e0df383f 100644 --- a/operations/helm/tests/extra-ports/grafana-agent/templates/serviceaccount.yaml +++ b/operations/helm/tests/extra-ports/grafana-agent/templates/serviceaccount.yaml @@ -4,6 +4,7 @@ apiVersion: v1 kind: ServiceAccount metadata: name: grafana-agent + namespace: default labels: helm.sh/chart: grafana-agent app.kubernetes.io/name: grafana-agent diff --git a/operations/helm/tests/faro-ingress/grafana-agent/templates/serviceaccount.yaml b/operations/helm/tests/faro-ingress/grafana-agent/templates/serviceaccount.yaml index 1dfd6fff9bdf..65d7e0df383f 100644 --- a/operations/helm/tests/faro-ingress/grafana-agent/templates/serviceaccount.yaml +++ b/operations/helm/tests/faro-ingress/grafana-agent/templates/serviceaccount.yaml @@ -4,6 +4,7 @@ apiVersion: v1 kind: ServiceAccount metadata: name: grafana-agent + namespace: default labels: helm.sh/chart: grafana-agent app.kubernetes.io/name: grafana-agent diff --git a/operations/helm/tests/global-image-pullsecrets/grafana-agent/templates/serviceaccount.yaml b/operations/helm/tests/global-image-pullsecrets/grafana-agent/templates/serviceaccount.yaml index 1dfd6fff9bdf..65d7e0df383f 100644 --- a/operations/helm/tests/global-image-pullsecrets/grafana-agent/templates/serviceaccount.yaml +++ b/operations/helm/tests/global-image-pullsecrets/grafana-agent/templates/serviceaccount.yaml @@ -4,6 +4,7 @@ apiVersion: v1 kind: ServiceAccount metadata: name: grafana-agent + namespace: default labels: helm.sh/chart: grafana-agent app.kubernetes.io/name: grafana-agent diff --git a/operations/helm/tests/global-image-registry/grafana-agent/templates/serviceaccount.yaml b/operations/helm/tests/global-image-registry/grafana-agent/templates/serviceaccount.yaml index 1dfd6fff9bdf..65d7e0df383f 100644 --- a/operations/helm/tests/global-image-registry/grafana-agent/templates/serviceaccount.yaml +++ b/operations/helm/tests/global-image-registry/grafana-agent/templates/serviceaccount.yaml @@ -4,6 +4,7 @@ apiVersion: v1 kind: ServiceAccount metadata: name: grafana-agent + namespace: default labels: helm.sh/chart: grafana-agent app.kubernetes.io/name: grafana-agent diff --git a/operations/helm/tests/initcontainers/grafana-agent/templates/serviceaccount.yaml b/operations/helm/tests/initcontainers/grafana-agent/templates/serviceaccount.yaml index 1dfd6fff9bdf..65d7e0df383f 100644 --- a/operations/helm/tests/initcontainers/grafana-agent/templates/serviceaccount.yaml +++ b/operations/helm/tests/initcontainers/grafana-agent/templates/serviceaccount.yaml @@ -4,6 +4,7 @@ apiVersion: v1 kind: ServiceAccount metadata: name: grafana-agent + namespace: default labels: helm.sh/chart: grafana-agent app.kubernetes.io/name: grafana-agent diff --git a/operations/helm/tests/local-image-pullsecrets/grafana-agent/templates/serviceaccount.yaml b/operations/helm/tests/local-image-pullsecrets/grafana-agent/templates/serviceaccount.yaml index 1dfd6fff9bdf..65d7e0df383f 100644 --- a/operations/helm/tests/local-image-pullsecrets/grafana-agent/templates/serviceaccount.yaml +++ b/operations/helm/tests/local-image-pullsecrets/grafana-agent/templates/serviceaccount.yaml @@ -4,6 +4,7 @@ apiVersion: v1 kind: ServiceAccount metadata: name: grafana-agent + namespace: default labels: helm.sh/chart: grafana-agent app.kubernetes.io/name: grafana-agent diff --git a/operations/helm/tests/local-image-registry/grafana-agent/templates/serviceaccount.yaml b/operations/helm/tests/local-image-registry/grafana-agent/templates/serviceaccount.yaml index 1dfd6fff9bdf..65d7e0df383f 100644 --- a/operations/helm/tests/local-image-registry/grafana-agent/templates/serviceaccount.yaml +++ b/operations/helm/tests/local-image-registry/grafana-agent/templates/serviceaccount.yaml @@ -4,6 +4,7 @@ apiVersion: v1 kind: ServiceAccount metadata: name: grafana-agent + namespace: default labels: helm.sh/chart: grafana-agent app.kubernetes.io/name: grafana-agent diff --git a/operations/helm/tests/nodeselectors-and-tolerations/grafana-agent/templates/serviceaccount.yaml b/operations/helm/tests/nodeselectors-and-tolerations/grafana-agent/templates/serviceaccount.yaml index 1dfd6fff9bdf..65d7e0df383f 100644 --- a/operations/helm/tests/nodeselectors-and-tolerations/grafana-agent/templates/serviceaccount.yaml +++ b/operations/helm/tests/nodeselectors-and-tolerations/grafana-agent/templates/serviceaccount.yaml @@ -4,6 +4,7 @@ apiVersion: v1 kind: ServiceAccount metadata: name: grafana-agent + namespace: default labels: helm.sh/chart: grafana-agent app.kubernetes.io/name: grafana-agent diff --git a/operations/helm/tests/sidecars/grafana-agent/templates/serviceaccount.yaml b/operations/helm/tests/sidecars/grafana-agent/templates/serviceaccount.yaml index 1dfd6fff9bdf..65d7e0df383f 100644 --- a/operations/helm/tests/sidecars/grafana-agent/templates/serviceaccount.yaml +++ b/operations/helm/tests/sidecars/grafana-agent/templates/serviceaccount.yaml @@ -4,6 +4,7 @@ apiVersion: v1 kind: ServiceAccount metadata: name: grafana-agent + namespace: default labels: helm.sh/chart: grafana-agent app.kubernetes.io/name: grafana-agent diff --git a/operations/helm/tests/static-mode/grafana-agent/templates/serviceaccount.yaml b/operations/helm/tests/static-mode/grafana-agent/templates/serviceaccount.yaml index 1dfd6fff9bdf..65d7e0df383f 100644 --- a/operations/helm/tests/static-mode/grafana-agent/templates/serviceaccount.yaml +++ b/operations/helm/tests/static-mode/grafana-agent/templates/serviceaccount.yaml @@ -4,6 +4,7 @@ apiVersion: v1 kind: ServiceAccount metadata: name: grafana-agent + namespace: default labels: helm.sh/chart: grafana-agent app.kubernetes.io/name: grafana-agent From 2a9c98c7ec4469aaca7e08cb247f7bf835cb9078 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jan 2024 13:46:03 -0500 Subject: [PATCH 24/68] build(deps-dev): bump @types/react-syntax-highlighter in /web/ui (#5951) Bumps [@types/react-syntax-highlighter](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react-syntax-highlighter) from 15.5.6 to 15.5.11. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react-syntax-highlighter) --- updated-dependencies: - dependency-name: "@types/react-syntax-highlighter" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- web/ui/package.json | 2 +- web/ui/yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/web/ui/package.json b/web/ui/package.json index 87bb50119706..ac422d7246f8 100644 --- a/web/ui/package.json +++ b/web/ui/package.json @@ -20,7 +20,7 @@ "@types/d3-zoom": "^3.0.2", "@types/react": "^18.2.6", "@types/react-dom": "^18.2.14", - "@types/react-syntax-highlighter": "^15.5.6", + "@types/react-syntax-highlighter": "^15.5.11", "eslint": "^8.40.0", "eslint-config-prettier": "^9.1.0", "eslint-config-react-app": "^7.0.1", diff --git a/web/ui/yarn.lock b/web/ui/yarn.lock index 60d0d721c513..85e807484347 100644 --- a/web/ui/yarn.lock +++ b/web/ui/yarn.lock @@ -2291,10 +2291,10 @@ dependencies: "@types/react" "*" -"@types/react-syntax-highlighter@^15.5.6": - version "15.5.6" - resolved "https://registry.yarnpkg.com/@types/react-syntax-highlighter/-/react-syntax-highlighter-15.5.6.tgz#77c95e6b74d2be23208fcdcf187b93b47025f1b1" - integrity sha512-i7wFuLbIAFlabTeD2I1cLjEOrG/xdMa/rpx2zwzAoGHuXJDhSqp9BSfDlMHSh9JSuNfxHk9eEmMX6D55GiyjGg== +"@types/react-syntax-highlighter@^15.5.11": + version "15.5.11" + resolved "https://registry.yarnpkg.com/@types/react-syntax-highlighter/-/react-syntax-highlighter-15.5.11.tgz#e050745b22eff81fc13cb0c763dd0d063413bbf1" + integrity sha512-ZqIJl+Pg8kD+47kxUjvrlElrraSUrYa4h0dauY/U/FTUuprSCqvUj+9PNQNQzVc6AJgIWUUxn87/gqsMHNbRjw== dependencies: "@types/react" "*" From d2aa711eb54bc0b280d22e93d271114dd13d46b5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Jan 2024 13:47:30 -0500 Subject: [PATCH 25/68] build(deps): bump aquasecurity/trivy-action from 0.14.0 to 0.16.1 (#6067) Bumps [aquasecurity/trivy-action](https://github.com/aquasecurity/trivy-action) from 0.14.0 to 0.16.1. - [Release notes](https://github.com/aquasecurity/trivy-action/releases) - [Commits](https://github.com/aquasecurity/trivy-action/compare/2b6a709cf9c4025c5438138008beaddbb02086f0...d43c1f16c00cfd3978dde6c07f4bbcf9eb6993ca) --- updated-dependencies: - dependency-name: aquasecurity/trivy-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/trivy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/trivy.yml b/.github/workflows/trivy.yml index 4403f0515b02..88f799776b5d 100644 --- a/.github/workflows/trivy.yml +++ b/.github/workflows/trivy.yml @@ -26,7 +26,7 @@ jobs: - name: Checkout code uses: actions/checkout@v4 - name: Run Trivy vulnerability scanner - uses: aquasecurity/trivy-action@2b6a709cf9c4025c5438138008beaddbb02086f0 + uses: aquasecurity/trivy-action@d43c1f16c00cfd3978dde6c07f4bbcf9eb6993ca with: image-ref: 'grafana/agent:main' format: 'template' From 2afa3ed66641744cdcf97d63d9794b722b806aa8 Mon Sep 17 00:00:00 2001 From: Erik Baranowski <39704712+erikbaranowski@users.noreply.github.com> Date: Mon, 8 Jan 2024 15:22:43 -0500 Subject: [PATCH 26/68] Fix windows tests 3 (#6068) * update hash for windows static converter test Signed-off-by: Erik Baranowski <39704712+erikbaranowski@users.noreply.github.com> * Increase loki wal test time delta to 2s from 1.1s due to windows test speed Signed-off-by: Erik Baranowski <39704712+erikbaranowski@users.noreply.github.com> --------- Signed-off-by: Erik Baranowski <39704712+erikbaranowski@users.noreply.github.com> --- component/common/loki/wal/watcher_test.go | 10 +++++----- .../testdata-v2_windows/integrations_v2.river | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/component/common/loki/wal/watcher_test.go b/component/common/loki/wal/watcher_test.go index 15644d740a28..959dad3a5ff5 100644 --- a/component/common/loki/wal/watcher_test.go +++ b/component/common/loki/wal/watcher_test.go @@ -685,9 +685,9 @@ func TestWatcher_StopAndDrainWAL(t *testing.T) { watcher.Drain() watcher.Stop() - // expecting 15s (missing 15 entries * 1 sec delay in AppendEntries) +/- 1.1s (taking into account the drain timeout + // expecting 15s (missing 15 entries * 1 sec delay in AppendEntries) +/- 2.0s (taking into account the drain timeout // has one extra second. - require.InDelta(t, time.Second*15, time.Since(now), float64(time.Millisecond*1100), "expected the drain procedure to take around 15s") + require.InDelta(t, time.Second*15, time.Since(now), float64(time.Millisecond*2000), "expected the drain procedure to take around 15s") require.Equal(t, int(writeTo.entriesReceived.Load()), 20, "expected the watcher to fully drain the WAL") }) @@ -737,9 +737,9 @@ func TestWatcher_StopAndDrainWAL(t *testing.T) { watcher.Drain() watcher.Stop() - // expecting 15s (missing 15 entries * 1 sec delay in AppendEntries) +/- 1.1s (taking into account the drain timeout + // expecting 15s (missing 15 entries * 1 sec delay in AppendEntries) +/- 2.0s (taking into account the drain timeout // has one extra second. - require.InDelta(t, time.Second*15, time.Since(now), float64(time.Millisecond*1100), "expected the drain procedure to take around 15s") + require.InDelta(t, time.Second*15, time.Since(now), float64(time.Millisecond*2000), "expected the drain procedure to take around 15s") require.Equal(t, int(writeTo.entriesReceived.Load()), 20, "expected the watcher to fully drain the WAL") }) @@ -790,7 +790,7 @@ func TestWatcher_StopAndDrainWAL(t *testing.T) { watcher.Drain() watcher.Stop() - require.InDelta(t, time.Second*10, time.Since(now), float64(time.Millisecond*1100), "expected the drain procedure to take around 15s") + require.InDelta(t, time.Second*10, time.Since(now), float64(time.Millisecond*2000), "expected the drain procedure to take around 15s") require.Less(t, int(writeTo.entriesReceived.Load()), 20, "expected watcher to have not consumed WAL fully") require.InDelta(t, 15, int(writeTo.entriesReceived.Load()), 1.0, "expected Watcher to consume at most +/- 1 entry from the WAL") }) diff --git a/converter/internal/staticconvert/testdata-v2_windows/integrations_v2.river b/converter/internal/staticconvert/testdata-v2_windows/integrations_v2.river index 4f9e09a37ed4..8d95a97c8b7b 100644 --- a/converter/internal/staticconvert/testdata-v2_windows/integrations_v2.river +++ b/converter/internal/staticconvert/testdata-v2_windows/integrations_v2.river @@ -1,6 +1,6 @@ prometheus.remote_write "metrics_default" { endpoint { - name = "default-8be96f" + name = "default-149bbd" url = "http://localhost:9009/api/prom/push" queue_config { } From 631378ea4d768bf34f54602fabee6260d7c01df8 Mon Sep 17 00:00:00 2001 From: annelaurefroment <49911675+annelaurefroment@users.noreply.github.com> Date: Mon, 8 Jan 2024 20:46:19 +0000 Subject: [PATCH 27/68] Update cadvisor-config.md (#6024) adding more details about label formats for the `store_container_labels` and `allowlisted_container_labels` parameters This was requested in this escalation: https://github.com/grafana/support-escalations/issues/5770 Co-authored-by: Clayton Cornell <131809008+clayton-cornell@users.noreply.github.com> --- .../static/configuration/integrations/cadvisor-config.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/sources/static/configuration/integrations/cadvisor-config.md b/docs/sources/static/configuration/integrations/cadvisor-config.md index adf92dcff827..a4a33b4df219 100644 --- a/docs/sources/static/configuration/integrations/cadvisor-config.md +++ b/docs/sources/static/configuration/integrations/cadvisor-config.md @@ -60,10 +60,10 @@ Full reference of options: # cAdvisor-specific configuration options # - # Convert container labels and environment variables into labels on prometheus metrics for each container. If false, then only metrics exported are container name, first alias, and image name. + # Convert container labels and environment variables into labels on Prometheus metrics for each container. If false, then the only metrics exported are container name, first alias, and image name. `.` aren't valid in Prometheus label names, so if there are any in the container label, they will transformed to `_` when converted to the Prometheus label. [store_container_labels: | default = true] - # List of container labels to be converted to labels on prometheus metrics for each container. store_container_labels must be set to false for this to take effect. + # List of container labels to be converted to labels on Prometheus metrics for each container. store_container_labels must be set to false for this to take effect. This must match the format of the container label, not the converted Prometheus label (`.` are converted to `_` in the Prometheus label). allowlisted_container_labels: [ - ] From 341cab723e38c0a7e8884dca830f5810bfda9a35 Mon Sep 17 00:00:00 2001 From: Pete Wall Date: Tue, 9 Jan 2024 01:14:33 -0600 Subject: [PATCH 28/68] Append, rather than set, '/pods' to the path in discovery.kubelet (#6013) * Append, rather than set, '/pods' to the path in discovery.kubelet --------- Signed-off-by: Pete Wall Co-authored-by: Paulin Todev --- CHANGELOG.md | 2 ++ component/discovery/kubelet/kubelet.go | 5 ++--- component/discovery/kubelet/kubelet_test.go | 19 +++++++++++++++++++ .../reference/components/discovery.kubelet.md | 6 +++++- 4 files changed, 28 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 774fbdd73c03..b9d7e66231e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -101,6 +101,8 @@ v0.39.0-rc.0 (2024-01-05) - `discovery.lightsail` now supports additional parameters for configuring HTTP client settings. (@ptodev) - Add `sample_age_limit` to remote_write config to drop samples older than a specified duration. (@marctc) +- Handle paths in the Kubelet URL for `discovery.kubelet`. (@petewall) + ### Bugfixes - Update `pyroscope.ebpf` to fix a logical bug causing to profile to many kthreads instead of regular processes https://github.com/grafana/pyroscope/pull/2778 (@korniltsev) diff --git a/component/discovery/kubelet/kubelet.go b/component/discovery/kubelet/kubelet.go index ff952e2ada6e..1fecc1e88f8e 100644 --- a/component/discovery/kubelet/kubelet.go +++ b/component/discovery/kubelet/kubelet.go @@ -129,11 +129,10 @@ func NewKubeletDiscovery(args Arguments) (*Discovery, error) { Transport: transport, Timeout: 30 * time.Second, } - // ensure the path is the kubelet pods endpoint - args.URL.Path = "/pods" + // Append the path to the kubelet pods endpoint return &Discovery{ client: client, - url: args.URL.String(), + url: args.URL.String() + "/pods", targetNamespaces: args.Namespaces, }, nil } diff --git a/component/discovery/kubelet/kubelet_test.go b/component/discovery/kubelet/kubelet_test.go index b7d2c750d9d2..183f789aef70 100644 --- a/component/discovery/kubelet/kubelet_test.go +++ b/component/discovery/kubelet/kubelet_test.go @@ -1,12 +1,14 @@ package kubelet import ( + "net/url" "testing" "github.com/prometheus/prometheus/discovery/targetgroup" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "github.com/grafana/agent/component/common/config" "github.com/grafana/river" "github.com/stretchr/testify/require" ) @@ -105,3 +107,20 @@ func TestDiscoveryPodWithoutPod(t *testing.T) { require.NoError(t, err) require.Len(t, kubeletDiscovery.discoveredPodSources, 2) } + +func TestWithDefaultKubeletHost(t *testing.T) { + kubeletDiscovery, err := NewKubeletDiscovery(DefaultConfig) + require.NoError(t, err) + require.Equal(t, "https://localhost:10250/pods", kubeletDiscovery.url) +} + +func TestWithCustomPath(t *testing.T) { + kubeletProxyUrl, _ := url.Parse("https://kubernetes.default.svc.cluster.local:443/api/v1/nodes/cluster-node-1/proxy") + kubeletDiscovery, err := NewKubeletDiscovery(Arguments{ + URL: config.URL{ + URL: kubeletProxyUrl, + }, + }) + require.NoError(t, err) + require.Equal(t, "https://kubernetes.default.svc.cluster.local:443/api/v1/nodes/cluster-node-1/proxy/pods", kubeletDiscovery.url) +} diff --git a/docs/sources/flow/reference/components/discovery.kubelet.md b/docs/sources/flow/reference/components/discovery.kubelet.md index 0000a74def4e..7ef29244a01e 100644 --- a/docs/sources/flow/reference/components/discovery.kubelet.md +++ b/docs/sources/flow/reference/components/discovery.kubelet.md @@ -35,7 +35,7 @@ The following arguments are supported: Name | Type | Description | Default | Required ---- | ---- | ----------- | ------- | -------- -`url` | `string` | URL of the Kubelet server. | | no +`url` | `string` | URL of the Kubelet server. | "https://localhost:10250" | no `bearer_token` | `secret` | Bearer token to authenticate with. | | no `bearer_token_file` | `string` | File containing a bearer token to authenticate with. | | no `refresh_interval` | `duration` | How often the Kubelet should be polled for scrape targets | `5s` | no @@ -49,6 +49,10 @@ One of the following authentication methods must be provided if kubelet authenti The `namespaces` list limits the namespaces to discover resources in. If omitted, all namespaces are searched. +`discovery.kubelet` appends a `/pods` path to `url` to request the available pods. +You can have additional paths in the `url`. +For example, if `url` is `https://kubernetes.default.svc.cluster.local:443/api/v1/nodes/cluster-node-1/proxy`, then `discovery.kubelet` sends a request on `https://kubernetes.default.svc.cluster.local:443/api/v1/nodes/cluster-node-1/proxy/pods` + ## Blocks The following blocks are supported inside the definition of From ed8cca65ce87dabbecac61a6869bee4fe1e47406 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Jan 2024 09:59:48 +0100 Subject: [PATCH 29/68] build(deps): bump actions/stale from 8 to 9 (#5955) Bumps [actions/stale](https://github.com/actions/stale) from 8 to 9. - [Release notes](https://github.com/actions/stale/releases) - [Changelog](https://github.com/actions/stale/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/stale/compare/v8...v9) --- updated-dependencies: - dependency-name: actions/stale dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/needs-attention.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/needs-attention.yml b/.github/workflows/needs-attention.yml index 6143be1fb2be..3e2d93a25ca6 100644 --- a/.github/workflows/needs-attention.yml +++ b/.github/workflows/needs-attention.yml @@ -10,7 +10,7 @@ jobs: needs-attention: runs-on: ubuntu-latest steps: - - uses: actions/stale@v8 + - uses: actions/stale@v9 with: days-before-stale: 30 days-before-close: -1 # never close automatically From e6b8ac7761b29d1f1f422a3e50b1b954d51965af Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Jan 2024 10:01:51 +0100 Subject: [PATCH 30/68] build(deps): bump github/codeql-action from 2 to 3 (#5998) Bumps [github/codeql-action](https://github.com/github/codeql-action) from 2 to 3. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/v2...v3) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/trivy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/trivy.yml b/.github/workflows/trivy.yml index 88f799776b5d..57fd6e855873 100644 --- a/.github/workflows/trivy.yml +++ b/.github/workflows/trivy.yml @@ -35,6 +35,6 @@ jobs: severity: 'CRITICAL,HIGH,MEDIUM,LOW' - name: Upload Trivy scan results to GitHub Security tab - uses: github/codeql-action/upload-sarif@v2 + uses: github/codeql-action/upload-sarif@v3 with: sarif_file: 'trivy-results.sarif' \ No newline at end of file From e6480313edc53fb0c1fff025a68a59f72e729b59 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=90=E1=BB=97=20Tr=E1=BB=8Dng=20H=E1=BA=A3i?= <41283691+hainenber@users.noreply.github.com> Date: Tue, 9 Jan 2024 21:10:34 +0700 Subject: [PATCH 31/68] build(dep): remove obsolete go mod replace (#5925) Signed-off-by: hainenber Co-authored-by: mattdurham --- go.mod | 4 ---- 1 file changed, 4 deletions(-) diff --git a/go.mod b/go.mod index 5e98e5fb0d4c..5ab46601a9bf 100644 --- a/go.mod +++ b/go.mod @@ -712,10 +712,6 @@ replace ( // https://github.com/grafana/cadvisor/tree/grafana-v0.47-noglobals github.com/google/cadvisor => github.com/grafana/cadvisor v0.0.0-20231110094609-5f7917925dea - // TODO(mattdurham): this is so you can debug on windows, when PR is merged into perflib, can you use that - // and eventually remove if windows_exporter shifts to it. https://github.com/leoluk/perflib_exporter/pull/43 - github.com/leoluk/perflib_exporter => github.com/grafana/perflib_exporter v0.1.1-0.20230511173423-6166026bd090 - github.com/prometheus-community/postgres_exporter => github.com/grafana/postgres_exporter v0.8.1-0.20210722175051-db35d7c2f520 // TODO(marctc): remove once this PR is merged upstream: https://github.com/prometheus/mysqld_exporter/pull/774 From e8b7b295faa18b35161e46ddf1c9875d66c88d1f Mon Sep 17 00:00:00 2001 From: Robert Fratto Date: Tue, 9 Jan 2024 10:35:56 -0500 Subject: [PATCH 32/68] misc: copy folders to operations/ (#6080) This change copies folders from `production/` to `operations/` that we intend to keep (the static mode mixin and operator related manifests). I tried to originally make symlinks and move the folders, but this doesn't work in the GitHub UI, where it fails to navigate to a file within a symlinked directory. Since there are references to such files, symlinks won't work for us here. Once references to the productions folder are completely eliminated, the folder will be removed. Related to #6077. --- .../agent-static-mixin/alerts.libsonnet | 414 + .../agent-static-mixin/config.libsonnet | 13 + .../agent-static-mixin/dashboards.libsonnet | 789 ++ .../agent-static-mixin/debugging.libsonnet | 128 + .../agent-static-mixin/jsonnetfile.json | 25 + operations/agent-static-mixin/mixin.libsonnet | 4 + operations/agent-static-mixin/utils.libsonnet | 34 + .../monitoring.coreos.com_podmonitors.yaml | 679 ++ .../crds/monitoring.coreos.com_probes.yaml | 722 ++ ...monitoring.coreos.com_servicemonitors.yaml | 709 ++ .../monitoring.grafana.com_grafanaagents.yaml | 7795 +++++++++++++++++ .../monitoring.grafana.com_integrations.yaml | 1738 ++++ .../monitoring.grafana.com_logsinstances.yaml | 500 ++ ...nitoring.grafana.com_metricsinstances.yaml | 861 ++ .../crds/monitoring.grafana.com_podlogs.yaml | 588 ++ .../templates/agent-operator.yaml | 645 ++ production/README.md | 1 + 17 files changed, 15645 insertions(+) create mode 100644 operations/agent-static-mixin/alerts.libsonnet create mode 100644 operations/agent-static-mixin/config.libsonnet create mode 100644 operations/agent-static-mixin/dashboards.libsonnet create mode 100644 operations/agent-static-mixin/debugging.libsonnet create mode 100644 operations/agent-static-mixin/jsonnetfile.json create mode 100644 operations/agent-static-mixin/mixin.libsonnet create mode 100644 operations/agent-static-mixin/utils.libsonnet create mode 100644 operations/agent-static-operator/crds/monitoring.coreos.com_podmonitors.yaml create mode 100644 operations/agent-static-operator/crds/monitoring.coreos.com_probes.yaml create mode 100644 operations/agent-static-operator/crds/monitoring.coreos.com_servicemonitors.yaml create mode 100644 operations/agent-static-operator/crds/monitoring.grafana.com_grafanaagents.yaml create mode 100644 operations/agent-static-operator/crds/monitoring.grafana.com_integrations.yaml create mode 100644 operations/agent-static-operator/crds/monitoring.grafana.com_logsinstances.yaml create mode 100644 operations/agent-static-operator/crds/monitoring.grafana.com_metricsinstances.yaml create mode 100644 operations/agent-static-operator/crds/monitoring.grafana.com_podlogs.yaml create mode 100644 operations/agent-static-operator/templates/agent-operator.yaml create mode 100644 production/README.md diff --git a/operations/agent-static-mixin/alerts.libsonnet b/operations/agent-static-mixin/alerts.libsonnet new file mode 100644 index 000000000000..51fe81e0e539 --- /dev/null +++ b/operations/agent-static-mixin/alerts.libsonnet @@ -0,0 +1,414 @@ +local config = import 'config.libsonnet'; +local _config = config._config; + +{ + prometheusAlerts+:: { + groups+: [ + { + name: 'grafana-agent-tracing', + rules: [ + { + alert: 'AgentTracingReceiverErrors', + // TODO(@mapno): add recording rule for total spans + expr: ||| + 100 * sum(rate(traces_receiver_refused_spans{receiver!="otlp/lb"}[1m])) by (%(group_by_cluster)s, receiver) + / + (sum(rate(traces_receiver_refused_spans{receiver!="otlp/lb"}[1m])) by (%(group_by_cluster)s, receiver) + sum(rate(traces_receiver_accepted_spans{receiver!="otlp/lb"}[1m])) by (%(group_by_cluster)s, receiver)) + > 10 + ||| % _config, + 'for': '15m', + labels: { + severity: 'warning', + }, + annotations: { + message: ||| + Receiver {{ $labels.receiver }} is experiencing {{ printf "%.2f" $value }}% errors. + |||, + }, + }, + { + alert: 'AgentTracingExporterErrors', + // TODO(@mapno): add recording rule for total spans + expr: ||| + 100 * sum(rate(traces_exporter_send_failed_spans{exporter!="otlp"}[1m])) by (%(group_by_cluster)s, exporter) + / + (sum(rate(traces_exporter_send_failed_spans{exporter!="otlp"}[1m])) by (%(group_by_cluster)s, exporter) + sum(rate(traces_exporter_sent_spans{exporter!="otlp"}[1m])) by (%(group_by_cluster)s, exporter)) + > 10 + ||| % _config, + 'for': '15m', + labels: { + severity: 'warning', + }, + annotations: { + message: ||| + Exporter {{ $labels.exporter }} is experiencing {{ printf "%.2f" $value }}% errors. + |||, + }, + }, + { + alert: 'AgentTracingLoadBalancingErrors', + expr: ||| + 100 * sum(rate(traces_loadbalancer_backend_outcome{success="false"}[1m])) by (%(group_by_cluster)s) + / + sum(rate(traces_loadbalancer_backend_outcome{success="true"}[1m])) by (%(group_by_cluster)s) + > 10 + ||| % _config, + 'for': '15m', + labels: { + severity: 'warning', + }, + annotations: { + message: ||| + Load balancing is experiencing {{ printf "%.2f" $value }}% errors. + |||, + }, + }, + ], + }, + { + name: 'GrafanaAgentSmokeChecks', + rules: [ + { + alert: 'GrafanaAgentDown', + expr: ||| + up{ + namespace="agent-smoke-test", + pod=~"grafana-agent-smoke-test-(0|cluster-0|cluster-1|cluster-2)", + } == 0 + |||, + 'for': '5m', + annotations: { + summary: '{{ $labels.job }} is down', + }, + }, + { + alert: 'GrafanaAgentFlapping', + expr: ||| + avg_over_time(up{ + namespace="agent-smoke-test", + pod=~"grafana-agent-smoke-test-(0|cluster-0|cluster-1|cluster-2)", + }[5m]) < 1 + |||, + 'for': '15m', + annotations: { + summary: '{{ $labels.job }} is flapping', + }, + }, + + // Checks that the CPU usage doesn't go too high. This was generated from internal usage where + // every 1,000 active series used roughly 0.0013441% of CPU. This alert only fires if there is a + // minimum load threshold of at least 1000 active series. + { + alert: 'GrafanaAgentCPUHigh', + expr: ||| + (sum by (pod) (rate(container_cpu_usage_seconds_total{cluster=~".+", namespace=~"agent-smoke-test", container=~".+", pod="grafana-agent-smoke-test-cluster-2"}[5m])) + / + (sum by (pod) (agent_wal_storage_active_series{cluster=~".+", namespace=~"agent-smoke-test", container=~".+", pod="grafana-agent-smoke-test-cluster-2"}) / 1000) + > 0.0013441) + and + sum by (pod) (agent_wal_storage_active_series{cluster=~".+", namespace=~"agent-smoke-test", container=~".+", pod="grafana-agent-smoke-test-cluster-2"}) > 1000 + |||, + 'for': '1h', + annotations: { + summary: '{{ $labels.pod }} is using more than 0.0013441 CPU per 1000 series over the last 5 minutes', + }, + }, + + // We assume roughly ~8KB per series. Check that each deployment + // doesn't go too far above this. + // + // We aggregate the memory of the scraping service together since an individual + // node with a really small number of active series will throw this metric off. + { + alert: 'GrafanaAgentMemHigh', + expr: ||| + sum without (pod, instance) (go_memstats_heap_inuse_bytes{job=~"agent-smoke-test/grafana-agent-smoke-test.*"}) / + sum without (pod, instance, instance_group_name) (agent_wal_storage_active_series{job=~"agent-smoke-test/grafana-agent-smoke-test.*"}) / 1e3 > 10 + |||, + 'for': '1h', + annotations: { + summary: '{{ $labels.job }} has used more than 10KB per series for more than 5 minutes', + }, + }, + { + alert: 'GrafanaAgentContainerRestarts', + expr: ||| + sum by (pod) (rate(kube_pod_container_status_restarts_total{namespace="agent-smoke-test"}[10m])) > 0 + |||, + annotations: { + summary: '{{ $labels.pod }} has a high rate of container restarts', + }, + }, + ], + }, + { + name: 'GrafanaAgentCrowChecks', + rules: [ + { + alert: 'CrowDown', + expr: ||| + up{job=~"agent-smoke-test/crow-.*"} == 0 + |||, + 'for': '5m', + annotations: { + summary: 'Crow {{ $labels.job }} is down.', + }, + }, + { + alert: 'CrowFlapping', + expr: ||| + avg_over_time(up{job=~"agent-smoke-test/crow-.*"}[5m]) < 1 + |||, + 'for': '15m', + annotations: { + summary: 'Crow {{ $labels.job }} is flapping.', + }, + }, + { + alert: 'CrowNotScraped', + expr: ||| + rate(crow_test_samples_total[5m]) == 0 + |||, + 'for': '15m', + annotations: { + summary: 'Crow {{ $labels.job }} is not being scraped.', + }, + }, + { + alert: 'CrowFailures', + expr: ||| + ( + rate(crow_test_sample_results_total{result="success"}[5m]) + / + ignoring(result) sum without (result) (rate(crow_test_sample_results_total[5m])) + ) + < 1 + |||, + 'for': '15m', + annotations: { + summary: 'Crow {{ $labels.job }} has had failures for at least 5m', + }, + }, + ], + }, + { + name: 'VultureChecks', + rules: [ + { + alert: 'VultureDown', + expr: ||| + up{job=~"agent-smoke-test/vulture"} == 0 + |||, + 'for': '5m', + annotations: { + summary: 'Vulture {{ $labels.job }} is down.', + }, + }, + { + alert: 'VultureFlapping', + expr: ||| + avg_over_time(up{job=~"agent-smoke-test/vulture"}[5m]) < 1 + |||, + 'for': '15m', + annotations: { + summary: 'Vulture {{ $labels.job }} is flapping.', + }, + }, + { + alert: 'VultureNotScraped', + expr: ||| + rate(tempo_vulture_trace_total[1m]) == 0 + |||, + 'for': '5m', + annotations: { + summary: 'Vulture {{ $labels.job }} is not being scraped.', + }, + }, + { + alert: 'VultureFailures', + expr: ||| + (rate(tempo_vulture_error_total[5m]) / rate(tempo_vulture_trace_total[5m])) > 0.3 + |||, + 'for': '5m', + annotations: { + summary: 'Vulture {{ $labels.job }} has had failures for at least 5m', + }, + }, + ], + }, + { + name: 'GrafanaAgentConfig', + rules: [ + { + alert: 'AgentRemoteConfigBadAPIRequests', + expr: ||| + 100 * sum(rate(agent_remote_config_fetches_total{status_code=~"(4|5).."}[10m])) by (%(group_by_cluster)s) + / + sum(rate(agent_remote_config_fetches_total[10m])) by (%(group_by_cluster)s) + > 5 + ||| % _config, + 'for': '10m', + labels: { + severity: 'warning', + }, + annotations: { + message: ||| + Receiving HTTP {{ $labels.status_code }} errors from API in {{ printf "%.2f" $value }}% of cases. + |||, + }, + }, + { + alert: 'AgentRemoteConfigBadAPIRequests', + expr: ||| + 100 * sum(rate(agent_remote_config_fetches_total{status_code=~"(4|5).."}[10m])) by (%(group_by_cluster)s) + / + sum(rate(agent_remote_config_fetches_total[10m])) by (%(group_by_cluster)s) + > 10 + ||| % _config, + 'for': '10m', + labels: { + severity: 'critical', + }, + annotations: { + message: ||| + Receiving HTTP {{ $labels.status_code }} errors from API in {{ printf "%.2f" $value }}% of cases. + |||, + }, + }, + { + alert: 'AgentRemoteConfigFetchErrors', + expr: ||| + 100 * sum(rate(agent_remote_config_fetch_errors_total[10m])) by (%(group_by_cluster)s) + / + sum(rate(agent_remote_config_fetches_total[10m])) by (%(group_by_cluster)s) + > 5 + ||| % _config, + 'for': '10m', + labels: { + severity: 'warning', + }, + annotations: { + message: ||| + Failing to reach Agent Management API. + |||, + }, + }, + { + alert: 'AgentRemoteConfigFetchErrors', + expr: ||| + 100 * sum(rate(agent_remote_config_fetch_errors_total[10m])) by (%(group_by_cluster)s) + / + sum(rate(agent_remote_config_fetches_total[10m])) by (%(group_by_cluster)s) + > 10 + ||| % _config, + 'for': '10m', + labels: { + severity: 'critical', + }, + annotations: { + message: ||| + Failing to reach Agent Management API. + |||, + }, + }, + { + alert: 'AgentRemoteConfigInvalidAPIResponse', + expr: ||| + 100 * sum(rate(agent_remote_config_invalid_total{reason=~".+"}[10m])) by (%(group_by_cluster)s) + / + sum(rate(agent_remote_config_fetches_total[10m])) by (%(group_by_cluster)s) + > 5 + ||| % _config, + 'for': '10m', + labels: { + severity: 'warning', + }, + annotations: { + message: ||| + API is responding with {{ $labels.reason }} in {{ printf "%.2f" $value }}% of cases. + |||, + }, + }, + { + alert: 'AgentRemoteConfigInvalidAPIResponse', + expr: ||| + 100 * sum(rate(agent_remote_config_invalid_total{reason=~".+"}[10m])) by (%(group_by_cluster)s) + / + sum(rate(agent_remote_config_fetches_total[10m])) by (%(group_by_cluster)s) + > 10 + ||| % _config, + 'for': '10m', + labels: { + severity: 'critical', + }, + annotations: { + message: ||| + API is responding with {{ $labels.reason }} in {{ printf "%.2f" $value }}% of cases. + |||, + }, + }, + { + alert: 'AgentFailureToReloadConfig', + expr: ||| + avg_over_time(agent_config_last_load_successful[10m]) < 0.9 + ||| % _config, + 'for': '10m', + labels: { + severity: 'warning', + }, + annotations: { + message: ||| + Instance {{ $labels.instance }} failed to successfully reload the config. + |||, + }, + }, + { + alert: 'AgentFailureToReloadConfig', + expr: ||| + avg_over_time(agent_config_last_load_successful[10m]) < 0.9 + ||| % _config, + 'for': '30m', + labels: { + severity: 'critical', + }, + annotations: { + message: ||| + Instance {{ $labels.instance }} failed to successfully reload the config. + |||, + }, + }, + { + alert: 'AgentManagementFallbackToEmptyConfig', + expr: ||| + sum(rate(agent_management_config_fallbacks_total{fallback_to="empty_config"}[10m])) by (%(group_by_cluster)s) > 0 + ||| % _config, + 'for': '10m', + labels: { + severity: 'warning', + }, + annotations: { + message: ||| + Instance {{ $labels.instance }} fell back to empty configuration. + |||, + }, + }, + { + alert: 'AgentManagementFallbackToEmptyConfig', + expr: ||| + sum(rate(agent_management_config_fallbacks_total{fallback_to="empty_config"}[10m])) by (%(group_by_cluster)s) > 0 + ||| % _config, + 'for': '30m', + labels: { + severity: 'critical', + }, + annotations: { + message: ||| + Instance {{ $labels.instance }} fell back to empty configuration. + |||, + }, + }, + ], + }, + ], + }, +} diff --git a/operations/agent-static-mixin/config.libsonnet b/operations/agent-static-mixin/config.libsonnet new file mode 100644 index 000000000000..8a7df26c0d3a --- /dev/null +++ b/operations/agent-static-mixin/config.libsonnet @@ -0,0 +1,13 @@ +{ + local makeGroupBy(groups) = std.join(', ', groups), + + _config+:: { + namespace: '.*', + + // Groups labels to uniquely identify and group by clusters + cluster_selectors: ['cluster', 'namespace'], + + // Each group-by label list is `, `-separated and unique identifies + group_by_cluster: makeGroupBy($._config.cluster_selectors), + }, +} diff --git a/operations/agent-static-mixin/dashboards.libsonnet b/operations/agent-static-mixin/dashboards.libsonnet new file mode 100644 index 000000000000..834ec5181312 --- /dev/null +++ b/operations/agent-static-mixin/dashboards.libsonnet @@ -0,0 +1,789 @@ +local utils = import './utils.libsonnet'; +local g = import 'grafana-builder/grafana.libsonnet'; +local grafana = import 'grafonnet/grafana.libsonnet'; + +local dashboard = grafana.dashboard; +local row = grafana.row; +local singlestat = grafana.singlestat; +local prometheus = grafana.prometheus; +local graphPanel = grafana.graphPanel; +local tablePanel = grafana.tablePanel; +local template = grafana.template; + +{ + grafanaDashboards+:: { + 'agent.json': + utils.injectUtils(g.dashboard('Agent')) + .addMultiTemplate('cluster', 'agent_build_info', 'cluster') + .addMultiTemplate('namespace', 'agent_build_info', 'namespace') + .addMultiTemplate('container', 'agent_build_info', 'container') + .addMultiTemplateWithAll('pod', 'agent_build_info{container=~"$container"}', 'pod', all='grafana-agent-.*') + .addRow( + g.row('Agent Stats') + .addPanel( + g.panel('Agent Stats') + + g.tablePanel([ + 'count by (pod, container, version) (agent_build_info{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"})', + 'max by (pod, container) (time() - process_start_time_seconds{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"})', + ], { + pod: { alias: 'Pod' }, + container: { alias: 'Container' }, + version: { alias: 'Version' }, + 'Value #A': { alias: 'Count', type: 'hidden' }, + 'Value #B': { alias: 'Uptime' }, + }) + ) + ) + .addRow( + g.row('Prometheus Discovery') + .addPanel( + g.panel('Target Sync') + + g.queryPanel('sum(rate(prometheus_target_sync_length_seconds_sum{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"}[5m])) by (pod, scrape_job) * 1e3', '{{pod}}/{{scrape_job}}') + + { yaxes: g.yaxes('ms') } + ) + .addPanel( + g.panel('Targets') + + g.queryPanel('sum by (pod) (prometheus_sd_discovered_targets{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"})', '{{pod}}') + + g.stack + ) + ) + .addRow( + g.row('Prometheus Retrieval') + .addPanel( + g.panel('Average Scrape Interval Duration') + + g.queryPanel(||| + rate(prometheus_target_interval_length_seconds_sum{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"}[5m]) + / + rate(prometheus_target_interval_length_seconds_count{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"}[5m]) + * 1e3 + |||, '{{pod}} {{interval}} configured') + + { yaxes: g.yaxes('ms') } + ) + .addPanel( + g.panel('Scrape failures') + + g.queryPanel([ + 'sum by (job) (rate(prometheus_target_scrapes_exceeded_sample_limit_total{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"}[1m]))', + 'sum by (job) (rate(prometheus_target_scrapes_sample_duplicate_timestamp_total{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"}[1m]))', + 'sum by (job) (rate(prometheus_target_scrapes_sample_out_of_bounds_total{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"}[1m]))', + 'sum by (job) (rate(prometheus_target_scrapes_sample_out_of_order_total{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"}[1m]))', + ], [ + 'exceeded sample limit: {{job}}', + 'duplicate timestamp: {{job}}', + 'out of bounds: {{job}}', + 'out of order: {{job}}', + ]) + + g.stack + ) + .addPanel( + g.panel('Appended Samples') + + g.queryPanel('sum by (job, instance_group_name) (rate(agent_wal_samples_appended_total{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"}[5m]))', '{{job}} {{instance_group_name}}') + + g.stack + ) + ), + + // Remote write specific dashboard. + 'agent-remote-write.json': + local timestampComparison = + graphPanel.new( + 'Highest Timestamp In vs. Highest Timestamp Sent', + datasource='$datasource', + span=6, + ) + .addTarget(prometheus.target( + ||| + ( + prometheus_remote_storage_highest_timestamp_in_seconds{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"} + - + ignoring(url, remote_name) group_right(pod) + prometheus_remote_storage_queue_highest_sent_timestamp_seconds{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"} + ) + |||, + legendFormat='{{cluster}}:{{pod}}-{{instance_group_name}}-{{url}}', + )); + + local remoteSendLatency = + graphPanel.new( + 'Latency [1m]', + datasource='$datasource', + span=6, + ) + .addTarget(prometheus.target( + 'rate(prometheus_remote_storage_sent_batch_duration_seconds_sum{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"}[1m]) / rate(prometheus_remote_storage_sent_batch_duration_seconds_count{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"}[1m])', + legendFormat='mean {{cluster}}:{{pod}}-{{instance_group_name}}-{{url}}', + )) + .addTarget(prometheus.target( + 'histogram_quantile(0.99, rate(prometheus_remote_storage_sent_batch_duration_seconds_bucket{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"}[1m]))', + legendFormat='p99 {{cluster}}:{{pod}}-{{instance_group_name}}-{{url}}', + )); + + local samplesInRate = + graphPanel.new( + 'Rate in [5m]', + datasource='$datasource', + span=6, + ) + .addTarget(prometheus.target( + 'rate(agent_wal_samples_appended_total{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"}[5m])', + legendFormat='{{cluster}}:{{pod}}-{{instance_group_name}}-{{url}}', + )); + + local samplesOutRate = + graphPanel.new( + 'Rate succeeded [5m]', + datasource='$datasource', + span=6, + ) + .addTarget(prometheus.target( + 'rate(prometheus_remote_storage_succeeded_samples_total{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"}[5m]) or rate(prometheus_remote_storage_samples_total{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"}[5m])', + legendFormat='{{cluster}}:{{pod}}-{{instance_group_name}}-{{url}}', + )); + + local currentShards = + graphPanel.new( + 'Current Shards', + datasource='$datasource', + span=12, + min_span=6, + ) + .addTarget(prometheus.target( + 'prometheus_remote_storage_shards{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"}', + legendFormat='{{cluster}}:{{pod}}-{{instance_group_name}}-{{url}}', + )); + + local maxShards = + graphPanel.new( + 'Max Shards', + datasource='$datasource', + span=4, + ) + .addTarget(prometheus.target( + 'prometheus_remote_storage_shards_max{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"}', + legendFormat='{{cluster}}:{{pod}}-{{instance_group_name}}-{{url}}', + )); + + local minShards = + graphPanel.new( + 'Min Shards', + datasource='$datasource', + span=4, + ) + .addTarget(prometheus.target( + 'prometheus_remote_storage_shards_min{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"}', + legendFormat='{{cluster}}:{{pod}}-{{instance_group_name}}-{{url}}', + )); + + local desiredShards = + graphPanel.new( + 'Desired Shards', + datasource='$datasource', + span=4, + ) + .addTarget(prometheus.target( + 'prometheus_remote_storage_shards_desired{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"}', + legendFormat='{{cluster}}:{{pod}}-{{instance_group_name}}-{{url}}', + )); + + local shardsCapacity = + graphPanel.new( + 'Shard Capacity', + datasource='$datasource', + span=6, + ) + .addTarget(prometheus.target( + 'prometheus_remote_storage_shard_capacity{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"}', + legendFormat='{{cluster}}:{{pod}}-{{instance_group_name}}-{{url}}', + )); + + local pendingSamples = + graphPanel.new( + 'Pending Samples', + datasource='$datasource', + span=6, + ) + .addTarget(prometheus.target( + 'prometheus_remote_storage_samples_pending{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"}', + legendFormat='{{cluster}}:{{pod}}-{{instance_group_name}}-{{url}}', + )); + + local queueSegment = + graphPanel.new( + 'Remote Write Current Segment', + datasource='$datasource', + span=6, + formatY1='none', + ) + .addTarget(prometheus.target( + 'prometheus_wal_watcher_current_segment{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"}', + legendFormat='{{cluster}}:{{pod}}-{{instance_group_name}}-{{url}}', + )); + + local droppedSamples = + graphPanel.new( + 'Dropped Samples', + datasource='$datasource', + span=6, + ) + .addTarget(prometheus.target( + 'rate(prometheus_remote_storage_samples_dropped_total{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"}[5m])', + legendFormat='{{cluster}}:{{pod}}-{{instance_group_name}}-{{url}}', + )); + + local failedSamples = + graphPanel.new( + 'Failed Samples', + datasource='$datasource', + span=6, + ) + .addTarget(prometheus.target( + 'rate(prometheus_remote_storage_samples_failed_total{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"}[5m])', + legendFormat='{{cluster}}:{{pod}}-{{instance_group_name}}-{{url}}', + )); + + local retriedSamples = + graphPanel.new( + 'Retried Samples', + datasource='$datasource', + span=6, + ) + .addTarget(prometheus.target( + 'rate(prometheus_remote_storage_samples_retried_total{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"}[5m])', + legendFormat='{{cluster}}:{{pod}}-{{instance_group_name}}-{{url}}', + )); + + local enqueueRetries = + graphPanel.new( + 'Enqueue Retries', + datasource='$datasource', + span=6, + ) + .addTarget(prometheus.target( + 'rate(prometheus_remote_storage_enqueue_retries_total{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"}[5m])', + legendFormat='{{cluster}}:{{pod}}-{{instance_group_name}}-{{url}}', + )); + + dashboard.new('Agent Prometheus Remote Write', tags=['grafana-agent-mixin'], editable=true, refresh='30s', time_from='now-1h') + .addTemplate( + { + hide: 0, + label: null, + name: 'datasource', + options: [], + query: 'prometheus', + refresh: 1, + regex: '', + type: 'datasource', + }, + ) + .addTemplate( + template.new( + 'cluster', + '$datasource', + 'label_values(agent_build_info, cluster)', + refresh='time', + current={ + selected: true, + text: 'All', + value: '$__all', + }, + includeAll=true, + ), + ) + .addTemplate( + template.new( + 'namespace', + '$datasource', + 'label_values(agent_build_info, namespace)', + refresh='time', + current={ + selected: true, + text: 'All', + value: '$__all', + }, + includeAll=true, + ), + ) + .addTemplate( + template.new( + 'container', + '$datasource', + 'label_values(agent_build_info, container)', + refresh='time', + current={ + selected: true, + text: 'All', + value: '$__all', + }, + includeAll=true, + ), + ) + .addTemplate( + template.new( + 'pod', + '$datasource', + 'label_values(agent_build_info{container=~"$container"}, pod)', + refresh='time', + current={ + selected: true, + text: 'All', + value: '$__all', + }, + includeAll=true, + ), + ) + .addTemplate( + template.new( + 'url', + '$datasource', + 'label_values(prometheus_remote_storage_shards{cluster=~"$cluster", pod=~"$pod"}, url)', + refresh='time', + includeAll=true, + ) + ) + .addRow( + row.new('Timestamps') + .addPanel(timestampComparison) + .addPanel(remoteSendLatency) + ) + .addRow( + row.new('Samples') + .addPanel(samplesInRate) + .addPanel(samplesOutRate) + .addPanel(pendingSamples) + .addPanel(droppedSamples) + .addPanel(failedSamples) + .addPanel(retriedSamples) + ) + .addRow( + row.new('Shards') + .addPanel(currentShards) + .addPanel(maxShards) + .addPanel(minShards) + .addPanel(desiredShards) + ) + .addRow( + row.new('Shard Details') + .addPanel(shardsCapacity) + ) + .addRow( + row.new('Segments') + .addPanel(queueSegment) + ) + .addRow( + row.new('Misc. Rates') + .addPanel(enqueueRetries) + ), + + 'agent-tracing-pipeline.json': + local acceptedSpans = + graphPanel.new( + 'Accepted spans', + datasource='$datasource', + interval='1m', + span=3, + legend_show=false, + fill=0, + ) + .addTarget(prometheus.target( + ||| + rate(traces_receiver_accepted_spans{cluster=~"$cluster",namespace=~"$namespace",container=~"$container",pod=~"$pod",receiver!="otlp/lb"}[$__rate_interval]) + |||, + legendFormat='{{ pod }} - {{ receiver }}/{{ transport }}', + )); + + local refusedSpans = + graphPanel.new( + 'Refused spans', + datasource='$datasource', + interval='1m', + span=3, + legend_show=false, + fill=0, + ) + .addTarget(prometheus.target( + ||| + rate(traces_receiver_refused_spans{cluster=~"$cluster",namespace=~"$namespace",container=~"$container",pod=~"$pod",receiver!="otlp/lb"}[$__rate_interval]) + |||, + legendFormat='{{ pod }} - {{ receiver }}/{{ transport }}', + )); + + local sentSpans = + graphPanel.new( + 'Exported spans', + datasource='$datasource', + interval='1m', + span=3, + legend_show=false, + fill=0, + ) + .addTarget(prometheus.target( + ||| + rate(traces_exporter_sent_spans{cluster=~"$cluster",namespace=~"$namespace",container=~"$container",pod=~"$pod",exporter!="otlp"}[$__rate_interval]) + |||, + legendFormat='{{ pod }} - {{ exporter }}', + )); + + local exportedFailedSpans = + graphPanel.new( + 'Exported failed spans', + datasource='$datasource', + interval='1m', + span=3, + legend_show=false, + fill=0, + ) + .addTarget(prometheus.target( + ||| + rate(traces_exporter_send_failed_spans{cluster=~"$cluster",namespace=~"$namespace",container=~"$container",pod=~"$pod",exporter!="otlp"}[$__rate_interval]) + |||, + legendFormat='{{ pod }} - {{ exporter }}', + )); + + local receivedSpans(receiverFilter, width) = + graphPanel.new( + 'Received spans', + datasource='$datasource', + interval='1m', + span=width, + fill=1, + ) + .addTarget(prometheus.target( + ||| + sum(rate(traces_receiver_accepted_spans{cluster=~"$cluster",namespace=~"$namespace",container=~"$container",pod=~"$pod",%s}[$__rate_interval])) + ||| % receiverFilter, + legendFormat='Accepted', + )) + .addTarget(prometheus.target( + ||| + sum(rate(traces_receiver_refused_spans{cluster=~"$cluster",namespace=~"$namespace",container=~"$container",pod=~"$pod",%s}[$__rate_interval])) + ||| % receiverFilter, + legendFormat='Refused', + )); + + local exportedSpans(exporterFilter, width) = + graphPanel.new( + 'Exported spans', + datasource='$datasource', + interval='1m', + span=width, + fill=1, + ) + .addTarget(prometheus.target( + ||| + sum(rate(traces_exporter_sent_spans{cluster=~"$cluster",namespace=~"$namespace",container=~"$container",pod=~"$pod",%s}[$__rate_interval])) + ||| % exporterFilter, + legendFormat='Sent', + )) + .addTarget(prometheus.target( + ||| + sum(rate(traces_exporter_send_failed_spans{cluster=~"$cluster",namespace=~"$namespace",container=~"$container",pod=~"$pod",%s}[$__rate_interval])) + ||| % exporterFilter, + legendFormat='Send failed', + )); + + local loadBalancedSpans = + graphPanel.new( + 'Load-balanced spans', + datasource='$datasource', + interval='1m', + span=3, + fill=1, + stack=true, + ) + .addTarget(prometheus.target( + ||| + rate(traces_loadbalancer_backend_outcome{cluster=~"$cluster",namespace=~"$namespace",success="true",container=~"$container",pod=~"$pod"}[$__rate_interval]) + |||, + legendFormat='{{ pod }}', + )); + + local peersNum = + graphPanel.new( + 'Number of peers', + datasource='$datasource', + interval='1m', + span=3, + legend_show=false, + fill=0, + ) + .addTarget(prometheus.target( + ||| + traces_loadbalancer_num_backends{cluster=~"$cluster",namespace=~"$namespace",container=~"$container",pod=~"$pod"} + |||, + legendFormat='{{ pod }}', + )); + + dashboard.new('Agent Tracing Pipeline', tags=['grafana-agent-mixin'], editable=true, refresh='30s', time_from='now-1h') + .addTemplate( + { + hide: 0, + label: null, + name: 'datasource', + options: [], + query: 'prometheus', + refresh: 1, + regex: '', + type: 'datasource', + }, + ) + .addTemplate( + template.new( + 'cluster', + '$datasource', + 'label_values(agent_build_info, cluster)', + refresh='time', + current={ + selected: true, + text: 'All', + value: '$__all', + }, + includeAll=true, + ), + ) + .addTemplate( + template.new( + 'namespace', + '$datasource', + 'label_values(agent_build_info, namespace)', + refresh='time', + current={ + selected: true, + text: 'All', + value: '$__all', + }, + includeAll=true, + ), + ) + .addTemplate( + template.new( + 'container', + '$datasource', + 'label_values(agent_build_info, container)', + refresh='time', + current={ + selected: true, + text: 'All', + value: '$__all', + }, + includeAll=true, + ), + ) + .addTemplate( + template.new( + 'pod', + '$datasource', + 'label_values(agent_build_info{container=~"$container"}, pod)', + refresh='time', + current={ + selected: true, + text: 'All', + value: '$__all', + }, + includeAll=true, + ), + ) + .addRow( + row.new('Write / Read') + .addPanel(acceptedSpans) + .addPanel(refusedSpans) + .addPanel(sentSpans) + .addPanel(exportedFailedSpans) + .addPanel(receivedSpans('receiver!="otlp/lb"', 6)) + .addPanel(exportedSpans('exporter!="otlp"', 6)) + ) + .addRow( + row.new('Load balancing') + .addPanel(loadBalancedSpans) + .addPanel(peersNum) + .addPanel(receivedSpans('receiver="otlp/lb"', 3)) + .addPanel(exportedSpans('exporter="otlp"', 3)) + ), + + 'agent-logs-pipeline.json': + local sumByPodRateCounter(title, metric, format='short') = + graphPanel.new( + title, + datasource='$datasource', + interval='1m', + span=6, + fill=1, + stack=true, + format=format + ) + .addTarget(prometheus.target( + ||| + sum by($groupBy) (rate(%s{cluster=~"$cluster",namespace=~"$namespace",container=~"$container",pod=~"$pod"}[$__rate_interval])) + ||| % [metric], + legendFormat='{{$groupBy}}', + )); + + local sumByPodGague(title, metric) = + graphPanel.new( + title, + datasource='$datasource', + interval='1m', + span=6, + fill=1, + stack=true, + ) + .addTarget(prometheus.target( + ||| + sum by($groupBy) (%s{cluster=~"$cluster",namespace=~"$namespace",container=~"$container",pod=~"$pod"}) + ||| % [metric], + legendFormat='{{$groupBy}}', + )); + + local requestSuccessRate() = + graphPanel.new( + 'Write requests success rate [%]', + datasource='$datasource', + interval='1m', + fill=0, + span=6, + format='%', + ) + .addTarget(prometheus.target( + ||| + sum by($groupBy) (rate(promtail_request_duration_seconds_bucket{status_code=~"2..", cluster=~"$cluster",namespace=~"$namespace",container=~"$container",pod=~"$pod"}[$__rate_interval])) + / + sum by($groupBy) (rate(promtail_request_duration_seconds_bucket{cluster=~"$cluster",namespace=~"$namespace",container=~"$container",pod=~"$pod"}[$__rate_interval])) + * 100 + |||, + legendFormat='{{$groupBy}}', + )); + + local histogramQuantile(title, metric, q) = + graphPanel.new( + title, + datasource='$datasource', + interval='1m', + span=6, + fill=0, + format='s', + ) + .addTarget(prometheus.target( + ||| + histogram_quantile( + %f, + sum by (le, $groupBy) + (rate(%s{cluster=~"$cluster",namespace=~"$namespace",container=~"$container",pod=~"$pod"}[$__rate_interval])) + ) + ||| % [q, metric], + legendFormat='{{$groupBy}}', + )); + + local histogramAverage(title, metric) = + graphPanel.new( + title, + datasource='$datasource', + interval='1m', + span=6, + fill=0, + format='s', + ) + .addTarget(prometheus.target( + ||| + (sum by (le, $groupBy) (rate(%s_sum{cluster=~"$cluster",namespace=~"$namespace",container=~"$container",pod=~"$pod"}[$__rate_interval]))) + / + (sum by (le, $groupBy) (rate(%s_count{cluster=~"$cluster",namespace=~"$namespace",container=~"$container",pod=~"$pod"}[$__rate_interval]))) + ||| % [metric, metric], + legendFormat='{{$groupBy}}', + )); + + + dashboard.new('Agent Logs Pipeline', tags=['grafana-agent-mixin'], editable=true, refresh='30s', time_from='now-1h') + .addTemplate( + { + hide: 0, + label: null, + name: 'datasource', + options: [], + query: 'prometheus', + refresh: 1, + regex: '', + type: 'datasource', + }, + ) + .addTemplate( + template.new( + 'cluster', + '$datasource', + 'label_values(agent_build_info, cluster)', + refresh='time', + current={ + selected: true, + text: 'All', + value: '$__all', + }, + includeAll=true, + ), + ) + .addTemplate( + template.new( + 'namespace', + '$datasource', + 'label_values(agent_build_info, namespace)', + refresh='time', + current={ + selected: true, + text: 'All', + value: '$__all', + }, + includeAll=true, + ), + ) + .addTemplate( + template.new( + 'container', + '$datasource', + 'label_values(agent_build_info, container)', + refresh='time', + current={ + selected: true, + text: 'All', + value: '$__all', + }, + includeAll=true, + ), + ) + .addTemplate( + template.new( + 'pod', + '$datasource', + 'label_values(agent_build_info{container=~"$container"}, pod)', + refresh='time', + current={ + selected: true, + text: 'All', + value: '$__all', + }, + includeAll=true, + ), + ) + .addTemplate( + template.custom( + 'groupBy', + 'pod,cluster,namespace', + 'pod', + ), + ) + .addRow( + row.new('Errors', height=500) + .addPanel(sumByPodRateCounter('Dropped bytes rate [B/s]', 'promtail_dropped_bytes_total', format='Bps')) + .addPanel(requestSuccessRate()) + ) + .addRow( + row.new('Latencies', height=500) + .addPanel(histogramQuantile('Write latencies p99 [s]', 'promtail_request_duration_seconds_bucket', 0.99)) + .addPanel(histogramQuantile('Write latencies p90 [s]', 'promtail_request_duration_seconds_bucket', 0.90)) + .addPanel(histogramQuantile('Write latencies p50 [s]', 'promtail_request_duration_seconds_bucket', 0.50)) + .addPanel(histogramAverage('Write latencies average [s]', 'promtail_request_duration_seconds')) + ) + .addRow( + row.new('Logs volume', height=500) + .addPanel(sumByPodRateCounter('Bytes read rate [B/s]', 'promtail_read_bytes_total', format='Bps')) + .addPanel(sumByPodRateCounter('Lines read rate [lines/s]', 'promtail_read_lines_total')) + .addPanel(sumByPodGague('Active files count', 'promtail_files_active_total')) + .addPanel(sumByPodRateCounter('Entries sent rate [entries/s]', 'promtail_sent_entries_total')) + ), + }, +} diff --git a/operations/agent-static-mixin/debugging.libsonnet b/operations/agent-static-mixin/debugging.libsonnet new file mode 100644 index 000000000000..711184d333f7 --- /dev/null +++ b/operations/agent-static-mixin/debugging.libsonnet @@ -0,0 +1,128 @@ +local utils = import './utils.libsonnet'; +local g = import 'grafana-builder/grafana.libsonnet'; + +{ + grafanaDashboards+:: { + 'agent-operational.json': + utils.injectUtils(g.dashboard('Agent Operational')) + .addMultiTemplate('cluster', 'agent_build_info', 'cluster') + .addMultiTemplate('namespace', 'agent_build_info{cluster=~"$cluster"}', 'namespace') + .addMultiTemplate('container', 'agent_build_info{cluster=~"$cluster", namespace="$namespace"}', 'container') + .addMultiTemplate('pod', 'agent_build_info{cluster=~"$cluster", namespace="$namespace", container="$container"}', 'pod') + .addRow( + g.row('General') + .addPanel( + g.panel('GCs [count/s]') + + g.queryPanel( + 'rate(go_gc_duration_seconds_count{cluster=~"$cluster", namespace=~"$namespace", container=~"$container", pod=~"$pod"}[5m])', + '{{pod}}', + ) + ) + .addPanel( + g.panel('Go Heap In Use') + + { yaxes: g.yaxes('decbytes') } + + g.queryPanel( + 'go_memstats_heap_inuse_bytes{cluster=~"$cluster", namespace=~"$namespace", container=~"$container", pod=~"$pod"}', + '{{pod}}', + ) + ) + .addPanel( + g.panel('Goroutines') + + g.queryPanel( + 'go_goroutines{cluster=~"$cluster", namespace=~"$namespace", container=~"$container", pod=~"$pod"}', + '{{pod}}', + ) + ) + .addPanel( + g.panel('CPU Usage [time/s]') + + g.queryPanel( + 'rate(container_cpu_usage_seconds_total{cluster=~"$cluster", namespace=~"$namespace", container=~"$container", pod=~"$pod"}[5m])', + '{{pod}}', + ) + ) + .addPanel( + g.panel('Working Set Size') + + { yaxes: g.yaxes('decbytes') } + + g.queryPanel( + 'container_memory_working_set_bytes{cluster=~"$cluster", namespace=~"$namespace", container=~"$container", pod=~"$pod"}', + '{{pod}}', + ) + ) + .addPanel( + g.panel('Promtail Bad Words') + + g.queryPanel( + 'rate(promtail_custom_bad_words_total{cluster=~"$cluster", exported_namespace=~"$namespace", exported_job=~"$job"}[5m])', + '{{job}}', + ) + ) + ) + .addRow( + g.row('Network') + .addPanel( + g.panel('Received Bytes [B/s]') + + { yaxes: g.yaxes('Bps') } + + g.queryPanel( + 'sum by (pod) (rate(container_network_receive_bytes_total{cluster=~"$cluster", namespace=~"$namespace", pod=~"$pod"}[5m]))', + '{{pod}}', + ) + ) + .addPanel( + g.panel('Transmitted Bytes [B/s]') + + { yaxes: g.yaxes('Bps') } + + g.queryPanel( + 'sum by (pod) (rate(container_network_transmit_bytes_total{cluster=~"$cluster", namespace=~"$namespace", pod=~"$pod"}[5m]))', + '{{pod}}', + ) + ) + ) + .addRow( + g.row('Prometheus Read') + .addPanel( + g.panel('Heap Used per Series per Pod') + + { yaxes: g.yaxes('decbytes') } + + g.queryPanel( + ||| + (sum by (pod) (avg_over_time(go_memstats_heap_inuse_bytes{cluster=~"$cluster", namespace=~"$namespace", container=~"$container", pod=~"$pod"}[1m]))) + / + (sum by (pod) (agent_wal_storage_active_series{cluster=~"$cluster", namespace=~"$namespace", container=~"$container", pod=~"$pod"})) + |||, + '{{pod}}', + ) + ) + .addPanel( + g.panel('Avg Heap Used per Series') + + { yaxes: g.yaxes('decbytes') } + + g.queryPanel( + ||| + (sum by (container) (avg_over_time(go_memstats_heap_inuse_bytes{cluster=~"$cluster", namespace=~"$namespace", container=~"$container", pod=~"$pod"}[1m]))) + / + (sum by (container) (agent_wal_storage_active_series{cluster=~"$cluster", namespace=~"$namespace", container=~"$container", pod=~"$pod"})) + |||, + '{{container}}', + ) + ) + .addPanel( + g.panel('Series Count per Pod') + + g.queryPanel( + 'sum by (pod) (agent_wal_storage_active_series{cluster=~"$cluster", namespace=~"$namespace", container=~"$container", pod=~"$pod"})', + '{{pod}}', + ) + ) + .addPanel( + g.panel('Series per Config') + + g.queryPanel( + 'sum by (instance_group_name) (agent_wal_storage_active_series{cluster=~"$cluster", namespace=~"$namespace", container=~"$container", pod=~"$pod"})', + '{{instance_group_name}}', + ) + ) + .addPanel( + g.panel('Total Series') + + g.queryPanel( + 'sum by (container) (agent_wal_storage_active_series{cluster=~"$cluster", namespace=~"$namespace", container=~"$container", pod=~"$pod"})', + '{{container}}', + ) + ) + ), + }, +} + diff --git a/operations/agent-static-mixin/jsonnetfile.json b/operations/agent-static-mixin/jsonnetfile.json new file mode 100644 index 000000000000..e5a27a96ad6a --- /dev/null +++ b/operations/agent-static-mixin/jsonnetfile.json @@ -0,0 +1,25 @@ +{ + "dependencies": [ + { + "name": "grafana-builder", + "source": { + "git": { + "remote": "https://github.com/grafana/jsonnet-libs", + "subdir": "grafana-builder" + } + }, + "version": "master" + }, + { + "name": "grafonnet", + "source": { + "git": { + "remote": "https://github.com/grafana/grafonnet-lib", + "subdir": "grafonnet" + } + }, + "version": "master" + } + ] +} + diff --git a/operations/agent-static-mixin/mixin.libsonnet b/operations/agent-static-mixin/mixin.libsonnet new file mode 100644 index 000000000000..2a015d681601 --- /dev/null +++ b/operations/agent-static-mixin/mixin.libsonnet @@ -0,0 +1,4 @@ +{ grafanaDashboardFolder: 'Grafana Agent' } ++ (import 'dashboards.libsonnet') ++ (import 'debugging.libsonnet') ++ (import 'alerts.libsonnet') diff --git a/operations/agent-static-mixin/utils.libsonnet b/operations/agent-static-mixin/utils.libsonnet new file mode 100644 index 000000000000..5467553a7d52 --- /dev/null +++ b/operations/agent-static-mixin/utils.libsonnet @@ -0,0 +1,34 @@ +{ + injectUtils(dashboard):: dashboard { + tags: ['grafana-agent-mixin'], + refresh: '30s', + addMultiTemplateWithAll(name, metric_name, label_name, all='.*', hide=0):: self { + templating+: { + list+: [{ + allValue: all, + current: { + selected: true, + text: 'All', + value: '$__all', + }, + datasource: '$datasource', + hide: hide, + includeAll: true, + label: name, + multi: true, + name: name, + options: [], + query: 'label_values(%s, %s)' % [metric_name, label_name], + refresh: 1, + regex: '', + sort: 2, + tagValuesQuery: '', + tags: [], + tagsQuery: '', + type: 'query', + useTags: false, + }], + }, + }, + }, +} diff --git a/operations/agent-static-operator/crds/monitoring.coreos.com_podmonitors.yaml b/operations/agent-static-operator/crds/monitoring.coreos.com_podmonitors.yaml new file mode 100644 index 000000000000..3e1fae0fc527 --- /dev/null +++ b/operations/agent-static-operator/crds/monitoring.coreos.com_podmonitors.yaml @@ -0,0 +1,679 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.9.2 + creationTimestamp: null + name: podmonitors.monitoring.coreos.com +spec: + group: monitoring.coreos.com + names: + categories: + - prometheus-operator + kind: PodMonitor + listKind: PodMonitorList + plural: podmonitors + shortNames: + - pmon + singular: podmonitor + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: PodMonitor defines monitoring for a set of pods. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Specification of desired Pod selection for target discovery + by Prometheus. + properties: + attachMetadata: + description: Attaches node metadata to discovered targets. Requires + Prometheus v2.35.0 and above. + properties: + node: + description: When set to true, Prometheus must have permissions + to get Nodes. + type: boolean + type: object + jobLabel: + description: The label to use to retrieve the job name from. + type: string + labelLimit: + description: Per-scrape limit on number of labels that will be accepted + for a sample. Only valid in Prometheus versions 2.27.0 and newer. + format: int64 + type: integer + labelNameLengthLimit: + description: Per-scrape limit on length of labels name that will be + accepted for a sample. Only valid in Prometheus versions 2.27.0 + and newer. + format: int64 + type: integer + labelValueLengthLimit: + description: Per-scrape limit on length of labels value that will + be accepted for a sample. Only valid in Prometheus versions 2.27.0 + and newer. + format: int64 + type: integer + namespaceSelector: + description: Selector to select which namespaces the Endpoints objects + are discovered from. + properties: + any: + description: Boolean describing whether all namespaces are selected + in contrast to a list restricting them. + type: boolean + matchNames: + description: List of namespace names to select from. + items: + type: string + type: array + type: object + podMetricsEndpoints: + description: A list of endpoints allowed as part of this PodMonitor. + items: + description: PodMetricsEndpoint defines a scrapeable endpoint of + a Kubernetes Pod serving Prometheus metrics. + properties: + authorization: + description: Authorization section for this endpoint + properties: + credentials: + description: The secret's key that contains the credentials + of the request + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: + description: Set the authentication type. Defaults to Bearer, + Basic will cause an error + type: string + type: object + basicAuth: + description: 'BasicAuth allow an endpoint to authenticate over + basic authentication. More info: https://prometheus.io/docs/operating/configuration/#endpoint' + properties: + password: + description: The secret in the service monitor namespace + that contains the password for authentication. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: The secret in the service monitor namespace + that contains the username for authentication. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearerTokenSecret: + description: Secret to mount to read bearer token for scraping + targets. The secret needs to be in the same namespace as the + pod monitor and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + enableHttp2: + description: Whether to enable HTTP2. + type: boolean + filterRunning: + description: 'Drop pods that are not running. (Failed, Succeeded). + Enabled by default. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase' + type: boolean + followRedirects: + description: FollowRedirects configures whether scrape requests + follow HTTP 3xx redirects. + type: boolean + honorLabels: + description: HonorLabels chooses the metric's labels on collisions + with target labels. + type: boolean + honorTimestamps: + description: HonorTimestamps controls whether Prometheus respects + the timestamps present in scraped data. + type: boolean + interval: + description: Interval at which metrics should be scraped If + not specified Prometheus' global scrape interval is used. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + metricRelabelings: + description: MetricRelabelConfigs to apply to samples before + ingestion. + items: + description: 'RelabelConfig allows dynamic rewriting of the + label set, being applied to samples before ingestion. It + defines ``-section of Prometheus + configuration. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs' + properties: + action: + default: replace + description: Action to perform based on regex matching. + Default is 'replace'. uppercase and lowercase actions + require Prometheus >= 2.36. + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + description: Modulus to take of the hash of the source + label values. + format: int64 + type: integer + regex: + description: Regular expression against which the extracted + value is matched. Default is '(.*)' + type: string + replacement: + description: Replacement value against which a regex replace + is performed if the regular expression matches. Regex + capture groups are available. Default is '$1' + type: string + separator: + description: Separator placed between concatenated source + label values. default is ';'. + type: string + sourceLabels: + description: The source labels select values from existing + labels. Their content is concatenated using the configured + separator and matched against the configured regular + expression for the replace, keep, and drop actions. + items: + description: LabelName is a valid Prometheus label name + which may only contain ASCII letters, numbers, as + well as underscores. + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + description: Label to which the resulting value is written + in a replace action. It is mandatory for replace actions. + Regex capture groups are available. + type: string + type: object + type: array + oauth2: + description: OAuth2 for the URL. Only valid in Prometheus versions + 2.27.0 and newer. + properties: + clientId: + description: The secret or configmap containing the OAuth2 + client id + properties: + configMap: + description: ConfigMap containing data to use for the + targets. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: The secret containing the OAuth2 client secret + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: Parameters to append to the token URL + type: object + scopes: + description: OAuth2 scopes used for the token request + items: + type: string + type: array + tokenUrl: + description: The URL to fetch the token from + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + params: + additionalProperties: + items: + type: string + type: array + description: Optional HTTP URL parameters + type: object + path: + description: HTTP path to scrape for metrics. If empty, Prometheus + uses the default value (e.g. `/metrics`). + type: string + port: + description: Name of the pod port this endpoint refers to. Mutually + exclusive with targetPort. + type: string + proxyUrl: + description: ProxyURL eg http://proxyserver:2195 Directs scrapes + to proxy through this endpoint. + type: string + relabelings: + description: 'RelabelConfigs to apply to samples before scraping. + Prometheus Operator automatically adds relabelings for a few + standard Kubernetes fields. The original scrape job''s name + is available via the `__tmp_prometheus_job_name` label. More + info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config' + items: + description: 'RelabelConfig allows dynamic rewriting of the + label set, being applied to samples before ingestion. It + defines ``-section of Prometheus + configuration. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs' + properties: + action: + default: replace + description: Action to perform based on regex matching. + Default is 'replace'. uppercase and lowercase actions + require Prometheus >= 2.36. + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + description: Modulus to take of the hash of the source + label values. + format: int64 + type: integer + regex: + description: Regular expression against which the extracted + value is matched. Default is '(.*)' + type: string + replacement: + description: Replacement value against which a regex replace + is performed if the regular expression matches. Regex + capture groups are available. Default is '$1' + type: string + separator: + description: Separator placed between concatenated source + label values. default is ';'. + type: string + sourceLabels: + description: The source labels select values from existing + labels. Their content is concatenated using the configured + separator and matched against the configured regular + expression for the replace, keep, and drop actions. + items: + description: LabelName is a valid Prometheus label name + which may only contain ASCII letters, numbers, as + well as underscores. + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + description: Label to which the resulting value is written + in a replace action. It is mandatory for replace actions. + Regex capture groups are available. + type: string + type: object + type: array + scheme: + description: HTTP scheme to use for scraping. `http` and `https` + are the expected values unless you rewrite the `__scheme__` + label via relabeling. If empty, Prometheus uses the default + value `http`. + enum: + - http + - https + type: string + scrapeTimeout: + description: Timeout after which the scrape is ended If not + specified, the Prometheus global scrape interval is used. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: 'Deprecated: Use ''port'' instead.' + x-kubernetes-int-or-string: true + tlsConfig: + description: TLS configuration to use when scraping the endpoint. + properties: + ca: + description: Certificate authority used when verifying server + certificates. + properties: + configMap: + description: ConfigMap containing data to use for the + targets. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the + targets. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the + targets. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + type: object + type: array + podTargetLabels: + description: PodTargetLabels transfers labels on the Kubernetes Pod + onto the target. + items: + type: string + type: array + sampleLimit: + description: SampleLimit defines per-scrape limit on number of scraped + samples that will be accepted. + format: int64 + type: integer + selector: + description: Selector to select Pod objects. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. + The requirements are ANDed. + items: + description: A label selector requirement is a selector that + contains values, a key, and an operator that relates the key + and values. + properties: + key: + description: key is the label key that the selector applies + to. + type: string + operator: + description: operator represents a key's relationship to + a set of values. Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of string values. If the + operator is In or NotIn, the values array must be non-empty. + If the operator is Exists or DoesNotExist, the values + array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single + {key,value} in the matchLabels map is equivalent to an element + of matchExpressions, whose key field is "key", the operator + is "In", and the values array contains only "value". The requirements + are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + targetLimit: + description: TargetLimit defines a limit on the number of scraped + targets that will be accepted. + format: int64 + type: integer + required: + - podMetricsEndpoints + - selector + type: object + required: + - spec + type: object + served: true + storage: true diff --git a/operations/agent-static-operator/crds/monitoring.coreos.com_probes.yaml b/operations/agent-static-operator/crds/monitoring.coreos.com_probes.yaml new file mode 100644 index 000000000000..7ece55d2ac5e --- /dev/null +++ b/operations/agent-static-operator/crds/monitoring.coreos.com_probes.yaml @@ -0,0 +1,722 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.9.2 + creationTimestamp: null + name: probes.monitoring.coreos.com +spec: + group: monitoring.coreos.com + names: + categories: + - prometheus-operator + kind: Probe + listKind: ProbeList + plural: probes + shortNames: + - prb + singular: probe + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: Probe defines monitoring for a set of static targets or ingresses. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Specification of desired Ingress selection for target discovery + by Prometheus. + properties: + authorization: + description: Authorization section for this endpoint + properties: + credentials: + description: The secret's key that contains the credentials of + the request + properties: + key: + description: The key of the secret to select from. Must be + a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must be + defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: + description: Set the authentication type. Defaults to Bearer, + Basic will cause an error + type: string + type: object + basicAuth: + description: 'BasicAuth allow an endpoint to authenticate over basic + authentication. More info: https://prometheus.io/docs/operating/configuration/#endpoint' + properties: + password: + description: The secret in the service monitor namespace that + contains the password for authentication. + properties: + key: + description: The key of the secret to select from. Must be + a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must be + defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: The secret in the service monitor namespace that + contains the username for authentication. + properties: + key: + description: The key of the secret to select from. Must be + a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must be + defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearerTokenSecret: + description: Secret to mount to read bearer token for scraping targets. + The secret needs to be in the same namespace as the probe and accessible + by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must be a + valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + interval: + description: Interval at which targets are probed using the configured + prober. If not specified Prometheus' global scrape interval is used. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + jobName: + description: The job name assigned to scraped metrics by default. + type: string + labelLimit: + description: Per-scrape limit on number of labels that will be accepted + for a sample. Only valid in Prometheus versions 2.27.0 and newer. + format: int64 + type: integer + labelNameLengthLimit: + description: Per-scrape limit on length of labels name that will be + accepted for a sample. Only valid in Prometheus versions 2.27.0 + and newer. + format: int64 + type: integer + labelValueLengthLimit: + description: Per-scrape limit on length of labels value that will + be accepted for a sample. Only valid in Prometheus versions 2.27.0 + and newer. + format: int64 + type: integer + metricRelabelings: + description: MetricRelabelConfigs to apply to samples before ingestion. + items: + description: 'RelabelConfig allows dynamic rewriting of the label + set, being applied to samples before ingestion. It defines ``-section + of Prometheus configuration. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs' + properties: + action: + default: replace + description: Action to perform based on regex matching. Default + is 'replace'. uppercase and lowercase actions require Prometheus + >= 2.36. + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + description: Modulus to take of the hash of the source label + values. + format: int64 + type: integer + regex: + description: Regular expression against which the extracted + value is matched. Default is '(.*)' + type: string + replacement: + description: Replacement value against which a regex replace + is performed if the regular expression matches. Regex capture + groups are available. Default is '$1' + type: string + separator: + description: Separator placed between concatenated source label + values. default is ';'. + type: string + sourceLabels: + description: The source labels select values from existing labels. + Their content is concatenated using the configured separator + and matched against the configured regular expression for + the replace, keep, and drop actions. + items: + description: LabelName is a valid Prometheus label name which + may only contain ASCII letters, numbers, as well as underscores. + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + description: Label to which the resulting value is written in + a replace action. It is mandatory for replace actions. Regex + capture groups are available. + type: string + type: object + type: array + module: + description: 'The module to use for probing specifying how to probe + the target. Example module configuring in the blackbox exporter: + https://github.com/prometheus/blackbox_exporter/blob/master/example.yml' + type: string + oauth2: + description: OAuth2 for the URL. Only valid in Prometheus versions + 2.27.0 and newer. + properties: + clientId: + description: The secret or configmap containing the OAuth2 client + id + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: The secret containing the OAuth2 client secret + properties: + key: + description: The key of the secret to select from. Must be + a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must be + defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: Parameters to append to the token URL + type: object + scopes: + description: OAuth2 scopes used for the token request + items: + type: string + type: array + tokenUrl: + description: The URL to fetch the token from + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + prober: + description: Specification for the prober to use for probing targets. + The prober.URL parameter is required. Targets cannot be probed if + left empty. + properties: + path: + default: /probe + description: Path to collect metrics from. Defaults to `/probe`. + type: string + proxyUrl: + description: Optional ProxyURL. + type: string + scheme: + description: HTTP scheme to use for scraping. `http` and `https` + are the expected values unless you rewrite the `__scheme__` + label via relabeling. If empty, Prometheus uses the default + value `http`. + enum: + - http + - https + type: string + url: + description: Mandatory URL of the prober. + type: string + required: + - url + type: object + sampleLimit: + description: SampleLimit defines per-scrape limit on number of scraped + samples that will be accepted. + format: int64 + type: integer + scrapeTimeout: + description: Timeout for scraping metrics from the Prometheus exporter. + If not specified, the Prometheus global scrape timeout is used. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + targetLimit: + description: TargetLimit defines a limit on the number of scraped + targets that will be accepted. + format: int64 + type: integer + targets: + description: Targets defines a set of static or dynamically discovered + targets to probe. + properties: + ingress: + description: ingress defines the Ingress objects to probe and + the relabeling configuration. If `staticConfig` is also defined, + `staticConfig` takes precedence. + properties: + namespaceSelector: + description: From which namespaces to select Ingress objects. + properties: + any: + description: Boolean describing whether all namespaces + are selected in contrast to a list restricting them. + type: boolean + matchNames: + description: List of namespace names to select from. + items: + type: string + type: array + type: object + relabelingConfigs: + description: 'RelabelConfigs to apply to the label set of + the target before it gets scraped. The original ingress + address is available via the `__tmp_prometheus_ingress_address` + label. It can be used to customize the probed URL. The original + scrape job''s name is available via the `__tmp_prometheus_job_name` + label. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config' + items: + description: 'RelabelConfig allows dynamic rewriting of + the label set, being applied to samples before ingestion. + It defines ``-section of Prometheus + configuration. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs' + properties: + action: + default: replace + description: Action to perform based on regex matching. + Default is 'replace'. uppercase and lowercase actions + require Prometheus >= 2.36. + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + description: Modulus to take of the hash of the source + label values. + format: int64 + type: integer + regex: + description: Regular expression against which the extracted + value is matched. Default is '(.*)' + type: string + replacement: + description: Replacement value against which a regex + replace is performed if the regular expression matches. + Regex capture groups are available. Default is '$1' + type: string + separator: + description: Separator placed between concatenated source + label values. default is ';'. + type: string + sourceLabels: + description: The source labels select values from existing + labels. Their content is concatenated using the configured + separator and matched against the configured regular + expression for the replace, keep, and drop actions. + items: + description: LabelName is a valid Prometheus label + name which may only contain ASCII letters, numbers, + as well as underscores. + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + description: Label to which the resulting value is written + in a replace action. It is mandatory for replace actions. + Regex capture groups are available. + type: string + type: object + type: array + selector: + description: Selector to select the Ingress objects. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. + If the operator is In or NotIn, the values array + must be non-empty. If the operator is Exists or + DoesNotExist, the values array must be empty. + This array is replaced during a strategic merge + patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is + "key", the operator is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + staticConfig: + description: 'staticConfig defines the static list of targets + to probe and the relabeling configuration. If `ingress` is also + defined, `staticConfig` takes precedence. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#static_config.' + properties: + labels: + additionalProperties: + type: string + description: Labels assigned to all metrics scraped from the + targets. + type: object + relabelingConfigs: + description: 'RelabelConfigs to apply to the label set of + the targets before it gets scraped. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config' + items: + description: 'RelabelConfig allows dynamic rewriting of + the label set, being applied to samples before ingestion. + It defines ``-section of Prometheus + configuration. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs' + properties: + action: + default: replace + description: Action to perform based on regex matching. + Default is 'replace'. uppercase and lowercase actions + require Prometheus >= 2.36. + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + description: Modulus to take of the hash of the source + label values. + format: int64 + type: integer + regex: + description: Regular expression against which the extracted + value is matched. Default is '(.*)' + type: string + replacement: + description: Replacement value against which a regex + replace is performed if the regular expression matches. + Regex capture groups are available. Default is '$1' + type: string + separator: + description: Separator placed between concatenated source + label values. default is ';'. + type: string + sourceLabels: + description: The source labels select values from existing + labels. Their content is concatenated using the configured + separator and matched against the configured regular + expression for the replace, keep, and drop actions. + items: + description: LabelName is a valid Prometheus label + name which may only contain ASCII letters, numbers, + as well as underscores. + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + description: Label to which the resulting value is written + in a replace action. It is mandatory for replace actions. + Regex capture groups are available. + type: string + type: object + type: array + static: + description: The list of hosts to probe. + items: + type: string + type: array + type: object + type: object + tlsConfig: + description: TLS configuration to use when scraping the endpoint. + properties: + ca: + description: Certificate authority used when verifying server + certificates. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the targets. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keySecret: + description: Secret containing the client key file for the targets. + properties: + key: + description: The key of the secret to select from. Must be + a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must be + defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + type: object + required: + - spec + type: object + served: true + storage: true diff --git a/operations/agent-static-operator/crds/monitoring.coreos.com_servicemonitors.yaml b/operations/agent-static-operator/crds/monitoring.coreos.com_servicemonitors.yaml new file mode 100644 index 000000000000..5d661184cfb4 --- /dev/null +++ b/operations/agent-static-operator/crds/monitoring.coreos.com_servicemonitors.yaml @@ -0,0 +1,709 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.9.2 + creationTimestamp: null + name: servicemonitors.monitoring.coreos.com +spec: + group: monitoring.coreos.com + names: + categories: + - prometheus-operator + kind: ServiceMonitor + listKind: ServiceMonitorList + plural: servicemonitors + shortNames: + - smon + singular: servicemonitor + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + description: ServiceMonitor defines monitoring for a set of services. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Specification of desired Service selection for target discovery + by Prometheus. + properties: + attachMetadata: + description: Attaches node metadata to discovered targets. Requires + Prometheus v2.37.0 and above. + properties: + node: + description: When set to true, Prometheus must have permissions + to get Nodes. + type: boolean + type: object + endpoints: + description: A list of endpoints allowed as part of this ServiceMonitor. + items: + description: Endpoint defines a scrapeable endpoint serving Prometheus + metrics. + properties: + authorization: + description: Authorization section for this endpoint + properties: + credentials: + description: The secret's key that contains the credentials + of the request + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: + description: Set the authentication type. Defaults to Bearer, + Basic will cause an error + type: string + type: object + basicAuth: + description: 'BasicAuth allow an endpoint to authenticate over + basic authentication More info: https://prometheus.io/docs/operating/configuration/#endpoints' + properties: + password: + description: The secret in the service monitor namespace + that contains the password for authentication. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: The secret in the service monitor namespace + that contains the username for authentication. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearerTokenFile: + description: File to read bearer token for scraping targets. + type: string + bearerTokenSecret: + description: Secret to mount to read bearer token for scraping + targets. The secret needs to be in the same namespace as the + service monitor and accessible by the Prometheus Operator. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + enableHttp2: + description: Whether to enable HTTP2. + type: boolean + filterRunning: + description: 'Drop pods that are not running. (Failed, Succeeded). + Enabled by default. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase' + type: boolean + followRedirects: + description: FollowRedirects configures whether scrape requests + follow HTTP 3xx redirects. + type: boolean + honorLabels: + description: HonorLabels chooses the metric's labels on collisions + with target labels. + type: boolean + honorTimestamps: + description: HonorTimestamps controls whether Prometheus respects + the timestamps present in scraped data. + type: boolean + interval: + description: Interval at which metrics should be scraped If + not specified Prometheus' global scrape interval is used. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + metricRelabelings: + description: MetricRelabelConfigs to apply to samples before + ingestion. + items: + description: 'RelabelConfig allows dynamic rewriting of the + label set, being applied to samples before ingestion. It + defines ``-section of Prometheus + configuration. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs' + properties: + action: + default: replace + description: Action to perform based on regex matching. + Default is 'replace'. uppercase and lowercase actions + require Prometheus >= 2.36. + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + description: Modulus to take of the hash of the source + label values. + format: int64 + type: integer + regex: + description: Regular expression against which the extracted + value is matched. Default is '(.*)' + type: string + replacement: + description: Replacement value against which a regex replace + is performed if the regular expression matches. Regex + capture groups are available. Default is '$1' + type: string + separator: + description: Separator placed between concatenated source + label values. default is ';'. + type: string + sourceLabels: + description: The source labels select values from existing + labels. Their content is concatenated using the configured + separator and matched against the configured regular + expression for the replace, keep, and drop actions. + items: + description: LabelName is a valid Prometheus label name + which may only contain ASCII letters, numbers, as + well as underscores. + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + description: Label to which the resulting value is written + in a replace action. It is mandatory for replace actions. + Regex capture groups are available. + type: string + type: object + type: array + oauth2: + description: OAuth2 for the URL. Only valid in Prometheus versions + 2.27.0 and newer. + properties: + clientId: + description: The secret or configmap containing the OAuth2 + client id + properties: + configMap: + description: ConfigMap containing data to use for the + targets. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: The secret containing the OAuth2 client secret + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: Parameters to append to the token URL + type: object + scopes: + description: OAuth2 scopes used for the token request + items: + type: string + type: array + tokenUrl: + description: The URL to fetch the token from + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + params: + additionalProperties: + items: + type: string + type: array + description: Optional HTTP URL parameters + type: object + path: + description: HTTP path to scrape for metrics. If empty, Prometheus + uses the default value (e.g. `/metrics`). + type: string + port: + description: Name of the service port this endpoint refers to. + Mutually exclusive with targetPort. + type: string + proxyUrl: + description: ProxyURL eg http://proxyserver:2195 Directs scrapes + to proxy through this endpoint. + type: string + relabelings: + description: 'RelabelConfigs to apply to samples before scraping. + Prometheus Operator automatically adds relabelings for a few + standard Kubernetes fields. The original scrape job''s name + is available via the `__tmp_prometheus_job_name` label. More + info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config' + items: + description: 'RelabelConfig allows dynamic rewriting of the + label set, being applied to samples before ingestion. It + defines ``-section of Prometheus + configuration. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs' + properties: + action: + default: replace + description: Action to perform based on regex matching. + Default is 'replace'. uppercase and lowercase actions + require Prometheus >= 2.36. + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + description: Modulus to take of the hash of the source + label values. + format: int64 + type: integer + regex: + description: Regular expression against which the extracted + value is matched. Default is '(.*)' + type: string + replacement: + description: Replacement value against which a regex replace + is performed if the regular expression matches. Regex + capture groups are available. Default is '$1' + type: string + separator: + description: Separator placed between concatenated source + label values. default is ';'. + type: string + sourceLabels: + description: The source labels select values from existing + labels. Their content is concatenated using the configured + separator and matched against the configured regular + expression for the replace, keep, and drop actions. + items: + description: LabelName is a valid Prometheus label name + which may only contain ASCII letters, numbers, as + well as underscores. + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + description: Label to which the resulting value is written + in a replace action. It is mandatory for replace actions. + Regex capture groups are available. + type: string + type: object + type: array + scheme: + description: HTTP scheme to use for scraping. `http` and `https` + are the expected values unless you rewrite the `__scheme__` + label via relabeling. If empty, Prometheus uses the default + value `http`. + enum: + - http + - https + type: string + scrapeTimeout: + description: Timeout after which the scrape is ended If not + specified, the Prometheus global scrape timeout is used unless + it is less than `Interval` in which the latter is used. + pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ + type: string + targetPort: + anyOf: + - type: integer + - type: string + description: Name or number of the target port of the Pod behind + the Service, the port must be specified with container port + property. Mutually exclusive with port. + x-kubernetes-int-or-string: true + tlsConfig: + description: TLS configuration to use when scraping the endpoint + properties: + ca: + description: Certificate authority used when verifying server + certificates. + properties: + configMap: + description: ConfigMap containing data to use for the + targets. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + caFile: + description: Path to the CA cert in the Prometheus container + to use for the targets. + type: string + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the + targets. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + description: Path to the client cert file in the Prometheus + container for the targets. + type: string + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keyFile: + description: Path to the client key file in the Prometheus + container for the targets. + type: string + keySecret: + description: Secret containing the client key file for the + targets. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + type: object + type: array + jobLabel: + description: "JobLabel selects the label from the associated Kubernetes + service which will be used as the `job` label for all metrics. \n + For example: If in `ServiceMonitor.spec.jobLabel: foo` and in `Service.metadata.labels.foo: + bar`, then the `job=\"bar\"` label is added to all metrics. \n If + the value of this field is empty or if the label doesn't exist for + the given Service, the `job` label of the metrics defaults to the + name of the Kubernetes Service." + type: string + labelLimit: + description: Per-scrape limit on number of labels that will be accepted + for a sample. Only valid in Prometheus versions 2.27.0 and newer. + format: int64 + type: integer + labelNameLengthLimit: + description: Per-scrape limit on length of labels name that will be + accepted for a sample. Only valid in Prometheus versions 2.27.0 + and newer. + format: int64 + type: integer + labelValueLengthLimit: + description: Per-scrape limit on length of labels value that will + be accepted for a sample. Only valid in Prometheus versions 2.27.0 + and newer. + format: int64 + type: integer + namespaceSelector: + description: Selector to select which namespaces the Kubernetes Endpoints + objects are discovered from. + properties: + any: + description: Boolean describing whether all namespaces are selected + in contrast to a list restricting them. + type: boolean + matchNames: + description: List of namespace names to select from. + items: + type: string + type: array + type: object + podTargetLabels: + description: PodTargetLabels transfers labels on the Kubernetes `Pod` + onto the created metrics. + items: + type: string + type: array + sampleLimit: + description: SampleLimit defines per-scrape limit on number of scraped + samples that will be accepted. + format: int64 + type: integer + selector: + description: Selector to select Endpoints objects. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. + The requirements are ANDed. + items: + description: A label selector requirement is a selector that + contains values, a key, and an operator that relates the key + and values. + properties: + key: + description: key is the label key that the selector applies + to. + type: string + operator: + description: operator represents a key's relationship to + a set of values. Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of string values. If the + operator is In or NotIn, the values array must be non-empty. + If the operator is Exists or DoesNotExist, the values + array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single + {key,value} in the matchLabels map is equivalent to an element + of matchExpressions, whose key field is "key", the operator + is "In", and the values array contains only "value". The requirements + are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + targetLabels: + description: TargetLabels transfers labels from the Kubernetes `Service` + onto the created metrics. + items: + type: string + type: array + targetLimit: + description: TargetLimit defines a limit on the number of scraped + targets that will be accepted. + format: int64 + type: integer + required: + - endpoints + - selector + type: object + required: + - spec + type: object + served: true + storage: true diff --git a/operations/agent-static-operator/crds/monitoring.grafana.com_grafanaagents.yaml b/operations/agent-static-operator/crds/monitoring.grafana.com_grafanaagents.yaml new file mode 100644 index 000000000000..fab68b18e6f6 --- /dev/null +++ b/operations/agent-static-operator/crds/monitoring.grafana.com_grafanaagents.yaml @@ -0,0 +1,7795 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.9.2 + creationTimestamp: null + name: grafanaagents.monitoring.grafana.com +spec: + group: monitoring.grafana.com + names: + categories: + - agent-operator + kind: GrafanaAgent + listKind: GrafanaAgentList + plural: grafanaagents + singular: grafanaagent + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: GrafanaAgent defines a Grafana Agent deployment. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Spec holds the specification of the desired behavior for + the Grafana Agent cluster. + properties: + affinity: + description: Affinity, if specified, controls pod scheduling constraints. + properties: + nodeAffinity: + description: Describes node affinity scheduling rules for the + pod. + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to + nodes that satisfy the affinity expressions specified by + this field, but it may choose a node that violates one or + more of the expressions. The node that is most preferred + is the one with the greatest sum of weights, i.e. for each + node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, + etc.), compute a sum by iterating through the elements of + this field and adding "weight" to the sum if the node matches + the corresponding matchExpressions; the node(s) with the + highest sum are the most preferred. + items: + description: An empty preferred scheduling term matches + all objects with implicit weight 0 (i.e. it's a no-op). + A null preferred scheduling term matches no objects (i.e. + is also a no-op). + properties: + preference: + description: A node selector term, associated with the + corresponding weight. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + weight: + description: Weight associated with matching the corresponding + nodeSelectorTerm, in the range 1-100. + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this + field are not met at scheduling time, the pod will not be + scheduled onto the node. If the affinity requirements specified + by this field cease to be met at some point during pod execution + (e.g. due to an update), the system may or may not try to + eventually evict the pod from its node. + properties: + nodeSelectorTerms: + description: Required. A list of node selector terms. + The terms are ORed. + items: + description: A null or empty node selector term matches + no objects. The requirements of them are ANDed. The + TopologySelectorTerm type implements a subset of the + NodeSelectorTerm. + properties: + matchExpressions: + description: A list of node selector requirements + by node's labels. + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + description: A list of node selector requirements + by node's fields. + items: + description: A node selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: The label key that the selector + applies to. + type: string + operator: + description: Represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists, DoesNotExist. Gt, and + Lt. + type: string + values: + description: An array of string values. If + the operator is In or NotIn, the values + array must be non-empty. If the operator + is Exists or DoesNotExist, the values array + must be empty. If the operator is Gt or + Lt, the values array must have a single + element, which will be interpreted as an + integer. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + x-kubernetes-map-type: atomic + type: array + required: + - nodeSelectorTerms + type: object + x-kubernetes-map-type: atomic + type: object + podAffinity: + description: Describes pod affinity scheduling rules (e.g. co-locate + this pod in the same node, zone, etc. as some other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to + nodes that satisfy the affinity expressions specified by + this field, but it may choose a node that violates one or + more of the expressions. The node that is most preferred + is the one with the greatest sum of weights, i.e. for each + node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling affinity expressions, + etc.), compute a sum by iterating through the elements of + this field and adding "weight" to the sum if the node has + pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by this + field and the ones listed in the namespaces field. + null selector and null or empty namespaces list + means "this pod's namespace". An empty selector + ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. The + term is applied to the union of the namespaces + listed in this field and the ones selected by + namespaceSelector. null or empty namespaces list + and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the corresponding + podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the affinity requirements specified by this + field are not met at scheduling time, the pod will not be + scheduled onto the node. If the affinity requirements specified + by this field cease to be met at some point during pod execution + (e.g. due to a pod label update), the system may or may + not try to eventually evict the pod from its node. When + there are multiple elements, the lists of nodes corresponding + to each podAffinityTerm are intersected, i.e. all terms + must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not co-located + (anti-affinity) with, where co-located is defined as running + on a node whose value of the label with key + matches that of any node on which a pod of the set of + pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied to the + union of the namespaces selected by this field and + the ones listed in the namespaces field. null selector + and null or empty namespaces list means "this pod's + namespace". An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list of namespace + names that the term applies to. The term is applied + to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. null or + empty namespaces list and null namespaceSelector means + "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where + co-located is defined as running on a node whose value + of the label with key topologyKey matches that of + any node on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + description: Describes pod anti-affinity scheduling rules (e.g. + avoid putting this pod in the same node, zone, etc. as some + other pod(s)). + properties: + preferredDuringSchedulingIgnoredDuringExecution: + description: The scheduler will prefer to schedule pods to + nodes that satisfy the anti-affinity expressions specified + by this field, but it may choose a node that violates one + or more of the expressions. The node that is most preferred + is the one with the greatest sum of weights, i.e. for each + node that meets all of the scheduling requirements (resource + request, requiredDuringScheduling anti-affinity expressions, + etc.), compute a sum by iterating through the elements of + this field and adding "weight" to the sum if the node has + pods which matches the corresponding podAffinityTerm; the + node(s) with the highest sum are the most preferred. + items: + description: The weights of all of the matched WeightedPodAffinityTerm + fields are added per-node to find the most preferred node(s) + properties: + podAffinityTerm: + description: Required. A pod affinity term, associated + with the corresponding weight. + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied + to the union of the namespaces selected by this + field and the ones listed in the namespaces field. + null selector and null or empty namespaces list + means "this pod's namespace". An empty selector + ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list + of namespace names that the term applies to. The + term is applied to the union of the namespaces + listed in this field and the ones selected by + namespaceSelector. null or empty namespaces list + and null namespaceSelector means "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods + matching the labelSelector in the specified namespaces, + where co-located is defined as running on a node + whose value of the label with key topologyKey + matches that of any node on which any of the selected + pods is running. Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + weight: + description: weight associated with matching the corresponding + podAffinityTerm, in the range 1-100. + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + description: If the anti-affinity requirements specified by + this field are not met at scheduling time, the pod will + not be scheduled onto the node. If the anti-affinity requirements + specified by this field cease to be met at some point during + pod execution (e.g. due to a pod label update), the system + may or may not try to eventually evict the pod from its + node. When there are multiple elements, the lists of nodes + corresponding to each podAffinityTerm are intersected, i.e. + all terms must be satisfied. + items: + description: Defines a set of pods (namely those matching + the labelSelector relative to the given namespace(s)) + that this pod should be co-located (affinity) or not co-located + (anti-affinity) with, where co-located is defined as running + on a node whose value of the label with key + matches that of any node on which a pod of the set of + pods is running + properties: + labelSelector: + description: A label query over a set of resources, + in this case pods. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaceSelector: + description: A label query over the set of namespaces + that the term applies to. The term is applied to the + union of the namespaces selected by this field and + the ones listed in the namespaces field. null selector + and null or empty namespaces list means "this pod's + namespace". An empty selector ({}) matches all namespaces. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are ANDed. + items: + description: A label selector requirement is a + selector that contains values, a key, and an + operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are + In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If the + operator is Exists or DoesNotExist, the + values array must be empty. This array is + replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". The + requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + namespaces: + description: namespaces specifies a static list of namespace + names that the term applies to. The term is applied + to the union of the namespaces listed in this field + and the ones selected by namespaceSelector. null or + empty namespaces list and null namespaceSelector means + "this pod's namespace". + items: + type: string + type: array + topologyKey: + description: This pod should be co-located (affinity) + or not co-located (anti-affinity) with the pods matching + the labelSelector in the specified namespaces, where + co-located is defined as running on a node whose value + of the label with key topologyKey matches that of + any node on which any of the selected pods is running. + Empty topologyKey is not allowed. + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + apiServer: + description: APIServerConfig lets you specify a host and auth methods + to access the Kubernetes API server. If left empty, the Agent assumes + that it is running inside of the cluster and will discover API servers + automatically and use the pod's CA certificate and bearer token + file at /var/run/secrets/kubernetes.io/serviceaccount. + properties: + authorization: + description: Authorization section for accessing apiserver + properties: + credentials: + description: The secret's key that contains the credentials + of the request + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + credentialsFile: + description: File to read a secret from, mutually exclusive + with Credentials (from SafeAuthorization) + type: string + type: + description: Set the authentication type. Defaults to Bearer, + Basic will cause an error + type: string + type: object + basicAuth: + description: BasicAuth allow an endpoint to authenticate over + basic authentication + properties: + password: + description: The secret in the service monitor namespace that + contains the password for authentication. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: The secret in the service monitor namespace that + contains the username for authentication. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearerToken: + description: Bearer token for accessing apiserver. + type: string + bearerTokenFile: + description: File to read bearer token for accessing apiserver. + type: string + host: + description: Host of apiserver. A valid string consisting of a + hostname or IP followed by an optional port number + type: string + tlsConfig: + description: TLS Config to use for accessing apiserver. + properties: + ca: + description: Certificate authority used when verifying server + certificates. + properties: + configMap: + description: ConfigMap containing data to use for the + targets. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + caFile: + description: Path to the CA cert in the Prometheus container + to use for the targets. + type: string + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the + targets. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + description: Path to the client cert file in the Prometheus + container for the targets. + type: string + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keyFile: + description: Path to the client key file in the Prometheus + container for the targets. + type: string + keySecret: + description: Secret containing the client key file for the + targets. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + required: + - host + type: object + configMaps: + description: ConfigMaps is a list of config maps in the same namespace + as the GrafanaAgent object which will be mounted into each running + Grafana Agent pod. The ConfigMaps are mounted into /var/lib/grafana-agent/extra-configmaps/. + items: + type: string + type: array + configReloaderImage: + description: Image, when specified, overrides the image used to run + Config Reloader. Specify the image along with a tag. You still need + to set the version to ensure Grafana Agent Operator knows which + version of Grafana Agent is being configured. + type: string + configReloaderVersion: + description: Version of Config Reloader to be deployed. + type: string + containers: + description: 'Containers lets you inject additional containers or + modify operator-generated containers. This can be used to add an + authentication proxy to a Grafana Agent pod or to change the behavior + of an operator-generated container. Containers described here modify + an operator-generated container if they share the same name and + if modifications are done via a strategic merge patch. The current + container names are: `grafana-agent` and `config-reloader`. Overriding + containers is entirely outside the scope of what the Grafana Agent + team supports and by doing so, you accept that this behavior may + break at any time without notice.' + items: + description: A single application container that you want to run + within a pod. + properties: + args: + description: 'Arguments to the entrypoint. The container image''s + CMD is used if this is not provided. Variable references $(VAR_NAME) + are expanded using the container''s environment. If a variable + cannot be resolved, the reference in the input string will + be unchanged. Double $$ are reduced to a single $, which allows + for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references + will never be expanded, regardless of whether the variable + exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + command: + description: 'Entrypoint array. Not executed within a shell. + The container image''s ENTRYPOINT is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container''s + environment. If a variable cannot be resolved, the reference + in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: + i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether + the variable exists or not. Cannot be updated. More info: + https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + env: + description: List of environment variables to set in the container. + Cannot be updated. + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be + a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. + If a variable cannot be resolved, the reference in the + input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) + syntax: i.e. "$$(VAR_NAME)" will produce the string + literal "$(VAR_NAME)". Escaped references will never + be expanded, regardless of whether the variable exists + or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: 'Selects a field of the pod: supports + metadata.name, metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, limits.ephemeral-storage, requests.cpu, + requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + envFrom: + description: List of sources to populate environment variables + in the container. The keys defined within a source must be + a C_IDENTIFIER. All invalid keys will be reported as an event + when the container is starting. When a key exists in multiple + sources, the value associated with the last source will take + precedence. Values defined by an Env with a duplicate key + will take precedence. Cannot be updated. + items: + description: EnvFromSource represents the source of a set + of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap must be + defined + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + description: An optional identifier to prepend to each + key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + image: + description: 'Container image name. More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config management + to default or override container images in workload controllers + like Deployments and StatefulSets.' + type: string + imagePullPolicy: + description: 'Image pull policy. One of Always, Never, IfNotPresent. + Defaults to Always if :latest tag is specified, or IfNotPresent + otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images' + type: string + lifecycle: + description: Actions that the management system should take + in response to container lifecycle events. Cannot be updated. + properties: + postStart: + description: 'PostStart is called immediately after a container + is created. If the handler fails, the container is terminated + and restarted according to its restart policy. Other management + of the container blocks until the hook completes. More + info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory for + the command is root ('/') in the container's + filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, you need + to explicitly call out to that shell. Exit status + of 0 is treated as live/healthy and non-zero is + unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to + the pod IP. You probably want to set "Host" in + httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the + host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported + as a LifecycleHandler and kept for the backward compatibility. + There are no validation of this field and lifecycle + hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: 'PreStop is called immediately before a container + is terminated due to an API request or management event + such as liveness/startup probe failure, preemption, resource + contention, etc. The handler is not called if the container + crashes or exits. The Pod''s termination grace period + countdown begins before the PreStop hook is executed. + Regardless of the outcome of the handler, the container + will eventually terminate within the Pod''s termination + grace period (unless delayed by finalizers). Other management + of the container blocks until the hook completes or until + the termination grace period is reached. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory for + the command is root ('/') in the container's + filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, you need + to explicitly call out to that shell. Exit status + of 0 is treated as live/healthy and non-zero is + unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to + the pod IP. You probably want to set "Host" in + httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the + host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported + as a LifecycleHandler and kept for the backward compatibility. + There are no validation of this field and lifecycle + hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: 'Periodic probe of container liveness. Container + will be restarted if the probe fails. Cannot be updated. More + info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory for the + command is root ('/') in the container's filesystem. + The command is simply exec'd, it is not run inside + a shell, so traditional shell instructions ('|', etc) + won't work. To use a shell, you need to explicitly + call out to that shell. Exit status of 0 is treated + as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe + to be considered failed after having succeeded. Defaults + to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to + place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior + is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the + pod IP. You probably want to set "Host" in httpHeaders + instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP + allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on + the container. Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has + started before liveness probes are initiated. More info: + https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe + to be considered successful after having failed. Defaults + to 1. Must be 1 for liveness and startup. Minimum value + is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP + port. + properties: + host: + description: 'Optional: Host name to connect to, defaults + to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on + the container. Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs + to terminate gracefully upon probe failure. The grace + period is the duration in seconds after the processes + running in the pod are sent a termination signal and the + time when the processes are forcibly halted with a kill + signal. Set this value longer than the expected cleanup + time for your process. If this value is nil, the pod's + terminationGracePeriodSeconds will be used. Otherwise, + this value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates + stop immediately via the kill signal (no opportunity to + shut down). This is a beta field and requires enabling + ProbeTerminationGracePeriod feature gate. Minimum value + is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times + out. Defaults to 1 second. Minimum value is 1. More info: + https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + name: + description: Name of the container specified as a DNS_LABEL. + Each container in a pod must have a unique name (DNS_LABEL). + Cannot be updated. + type: string + ports: + description: List of ports to expose from the container. Not + specifying a port here DOES NOT prevent that port from being + exposed. Any port which is listening on the default "0.0.0.0" + address inside a container will be accessible from the network. + Modifying this array with strategic merge patch may corrupt + the data. For more information See https://github.com/kubernetes/kubernetes/issues/108255. + Cannot be updated. + items: + description: ContainerPort represents a network port in a + single container. + properties: + containerPort: + description: Number of port to expose on the pod's IP + address. This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external port to. + type: string + hostPort: + description: Number of port to expose on the host. If + specified, this must be a valid port number, 0 < x < + 65536. If HostNetwork is specified, this must match + ContainerPort. Most containers do not need this. + format: int32 + type: integer + name: + description: If specified, this must be an IANA_SVC_NAME + and unique within the pod. Each named port in a pod + must have a unique name. Name for the port that can + be referred to by services. + type: string + protocol: + default: TCP + description: Protocol for port. Must be UDP, TCP, or SCTP. + Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: 'Periodic probe of container service readiness. + Container will be removed from service endpoints if the probe + fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory for the + command is root ('/') in the container's filesystem. + The command is simply exec'd, it is not run inside + a shell, so traditional shell instructions ('|', etc) + won't work. To use a shell, you need to explicitly + call out to that shell. Exit status of 0 is treated + as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe + to be considered failed after having succeeded. Defaults + to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to + place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior + is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the + pod IP. You probably want to set "Host" in httpHeaders + instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP + allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on + the container. Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has + started before liveness probes are initiated. More info: + https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe + to be considered successful after having failed. Defaults + to 1. Must be 1 for liveness and startup. Minimum value + is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP + port. + properties: + host: + description: 'Optional: Host name to connect to, defaults + to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on + the container. Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs + to terminate gracefully upon probe failure. The grace + period is the duration in seconds after the processes + running in the pod are sent a termination signal and the + time when the processes are forcibly halted with a kill + signal. Set this value longer than the expected cleanup + time for your process. If this value is nil, the pod's + terminationGracePeriodSeconds will be used. Otherwise, + this value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates + stop immediately via the kill signal (no opportunity to + shut down). This is a beta field and requires enabling + ProbeTerminationGracePeriod feature gate. Minimum value + is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times + out. Defaults to 1 second. Minimum value is 1. More info: + https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource resize + policy for the container. + properties: + resourceName: + description: 'Name of the resource to which this resource + resize policy applies. Supported values: cpu, memory.' + type: string + restartPolicy: + description: Restart policy to apply when specified resource + is resized. If not specified, it defaults to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + description: 'Compute Resources required by this container. + Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only + be set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry + in pod.spec.resourceClaims of the Pod where this + field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests + cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + restartPolicy: + description: 'RestartPolicy defines the restart behavior of + individual containers in a pod. This field may only be set + for init containers, and the only allowed value is "Always". + For non-init containers or when this field is not specified, + the restart behavior is defined by the Pod''s restart policy + and the container type. Setting the RestartPolicy as "Always" + for the init container will have the following effect: this + init container will be continually restarted on exit until + all regular containers have terminated. Once all regular containers + have completed, all init containers with restartPolicy "Always" + will be shut down. This lifecycle differs from normal init + containers and is often referred to as a "sidecar" container. + Although this init container still starts in the init container + sequence, it does not wait for the container to complete before + proceeding to the next init container. Instead, the next init + container starts immediately after this init container is + started, or after any startupProbe has successfully completed.' + type: string + securityContext: + description: 'SecurityContext defines the security options the + container should be run with. If set, the fields of SecurityContext + override the equivalent fields of PodSecurityContext. More + info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/' + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether + a process can gain more privileges than its parent process. + This bool directly controls if the no_new_privs flag will + be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be set + when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by + the container runtime. Note that this field cannot be + set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes + in privileged containers are essentially equivalent to + root on the host. Defaults to false. Note that this field + cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to + use for the containers. The default is DefaultProcMount + which uses the container runtime defaults for readonly + paths and masked paths. This requires the ProcMountType + feature flag to be enabled. Note that this field cannot + be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root + filesystem. Default is false. Note that this field cannot + be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be set + in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a + non-root user. If true, the Kubelet will validate the + image at runtime to ensure that it does not run as UID + 0 (root) and fail to start the container if it does. If + unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both + SecurityContext and PodSecurityContext, the value specified + in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata + if unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a + random SELinux context for each container. May also be + set in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & container + level, the container options override the pod options. + Note that this field cannot be set when spec.os.name is + windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile + must be preconfigured on the node to work. Must be + a descending path, relative to the kubelet's configured + seccomp profile location. Must be set if type is "Localhost". + Must NOT be set for any other type. + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - + a profile defined in a file on the node should be + used. RuntimeDefault - the container runtime default + profile should be used. Unconfined - no profile should + be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all + containers. If unspecified, the options from the PodSecurityContext + will be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is + linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named + by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. All of a Pod's + containers must have the same effective HostProcess + value (it is not allowed to have a mix of HostProcess + containers and non-HostProcess containers). In addition, + if HostProcess is true then HostNetwork must also + be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set + in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object + startupProbe: + description: 'StartupProbe indicates that the Pod has successfully + initialized. If specified, no other probes are executed until + this completes successfully. If this probe fails, the Pod + will be restarted, just as if the livenessProbe failed. This + can be used to provide different probe parameters at the beginning + of a Pod''s lifecycle, when it might take a long time to load + data or warm a cache, than during steady-state operation. + This cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory for the + command is root ('/') in the container's filesystem. + The command is simply exec'd, it is not run inside + a shell, so traditional shell instructions ('|', etc) + won't work. To use a shell, you need to explicitly + call out to that shell. Exit status of 0 is treated + as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe + to be considered failed after having succeeded. Defaults + to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to + place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior + is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the + pod IP. You probably want to set "Host" in httpHeaders + instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP + allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on + the container. Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has + started before liveness probes are initiated. More info: + https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe + to be considered successful after having failed. Defaults + to 1. Must be 1 for liveness and startup. Minimum value + is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP + port. + properties: + host: + description: 'Optional: Host name to connect to, defaults + to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on + the container. Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs + to terminate gracefully upon probe failure. The grace + period is the duration in seconds after the processes + running in the pod are sent a termination signal and the + time when the processes are forcibly halted with a kill + signal. Set this value longer than the expected cleanup + time for your process. If this value is nil, the pod's + terminationGracePeriodSeconds will be used. Otherwise, + this value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates + stop immediately via the kill signal (no opportunity to + shut down). This is a beta field and requires enabling + ProbeTerminationGracePeriod feature gate. Minimum value + is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times + out. Defaults to 1 second. Minimum value is 1. More info: + https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + stdin: + description: Whether this container should allocate a buffer + for stdin in the container runtime. If this is not set, reads + from stdin in the container will always result in EOF. Default + is false. + type: boolean + stdinOnce: + description: Whether the container runtime should close the + stdin channel after it has been opened by a single attach. + When stdin is true the stdin stream will remain open across + multiple attach sessions. If stdinOnce is set to true, stdin + is opened on container start, is empty until the first client + attaches to stdin, and then remains open and accepts data + until the client disconnects, at which time stdin is closed + and remains closed until the container is restarted. If this + flag is false, a container processes that reads from stdin + will never receive an EOF. Default is false + type: boolean + terminationMessagePath: + description: 'Optional: Path at which the file to which the + container''s termination message will be written is mounted + into the container''s filesystem. Message written is intended + to be brief final status, such as an assertion failure message. + Will be truncated by the node if greater than 4096 bytes. + The total message length across all containers will be limited + to 12kb. Defaults to /dev/termination-log. Cannot be updated.' + type: string + terminationMessagePolicy: + description: Indicate how the termination message should be + populated. File will use the contents of terminationMessagePath + to populate the container status message on both success and + failure. FallbackToLogsOnError will use the last chunk of + container log output if the termination message file is empty + and the container exited with an error. The log output is + limited to 2048 bytes or 80 lines, whichever is smaller. Defaults + to File. Cannot be updated. + type: string + tty: + description: Whether this container should allocate a TTY for + itself, also requires 'stdin' to be true. Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices to be + used by the container. + items: + description: volumeDevice describes a mapping of a raw block + device within a container. + properties: + devicePath: + description: devicePath is the path inside of the container + that the device will be mapped to. + type: string + name: + description: name must match the name of a persistentVolumeClaim + in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: Pod volumes to mount into the container's filesystem. + Cannot be updated. + items: + description: VolumeMount describes a mounting of a Volume + within a container. + properties: + mountPath: + description: Path within the container at which the volume + should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts are + propagated from the host to container and the other + way around. When not set, MountPropagationNone is used. + This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write otherwise + (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the container's + volume should be mounted. Defaults to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from which + the container's volume should be mounted. Behaves similarly + to SubPath but environment variable references $(VAR_NAME) + are expanded using the container's environment. Defaults + to "" (volume's root). SubPathExpr and SubPath are mutually + exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: Container's working directory. If not specified, + the container runtime's default will be used, which might + be configured in the container image. Cannot be updated. + type: string + required: + - name + type: object + type: array + disableReporting: + default: false + description: disableReporting disables reporting of enabled feature + flags to Grafana. + type: boolean + disableSupportBundle: + default: false + description: disableSupportBundle disables the generation of support + bundles. + type: boolean + enableConfigReadAPI: + default: false + description: enableConfigReadAPI enables the read API for viewing + the currently running config port 8080 on the agent. + type: boolean + image: + description: Image, when specified, overrides the image used to run + Agent. Specify the image along with a tag. You still need to set + the version to ensure Grafana Agent Operator knows which version + of Grafana Agent is being configured. + type: string + imagePullSecrets: + description: 'ImagePullSecrets holds an optional list of references + to Secrets within the same namespace used for pulling the Grafana + Agent image from registries. More info: https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod' + items: + description: LocalObjectReference contains enough information to + let you locate the referenced object inside the same namespace. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + x-kubernetes-map-type: atomic + type: array + initContainers: + description: 'InitContainers let you add initContainers to the pod + definition. These can be used to, for example, fetch secrets for + injection into the Grafana Agent configuration from external sources. + Errors during the execution of an initContainer cause the pod to + restart. More info: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/ + Using initContainers for any use case other than secret fetching + is entirely outside the scope of what the Grafana Agent maintainers + support and by doing so, you accept that this behavior may break + at any time without notice.' + items: + description: A single application container that you want to run + within a pod. + properties: + args: + description: 'Arguments to the entrypoint. The container image''s + CMD is used if this is not provided. Variable references $(VAR_NAME) + are expanded using the container''s environment. If a variable + cannot be resolved, the reference in the input string will + be unchanged. Double $$ are reduced to a single $, which allows + for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + produce the string literal "$(VAR_NAME)". Escaped references + will never be expanded, regardless of whether the variable + exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + command: + description: 'Entrypoint array. Not executed within a shell. + The container image''s ENTRYPOINT is used if this is not provided. + Variable references $(VAR_NAME) are expanded using the container''s + environment. If a variable cannot be resolved, the reference + in the input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) syntax: + i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". + Escaped references will never be expanded, regardless of whether + the variable exists or not. Cannot be updated. More info: + https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' + items: + type: string + type: array + env: + description: List of environment variables to set in the container. + Cannot be updated. + items: + description: EnvVar represents an environment variable present + in a Container. + properties: + name: + description: Name of the environment variable. Must be + a C_IDENTIFIER. + type: string + value: + description: 'Variable references $(VAR_NAME) are expanded + using the previously defined environment variables in + the container and any service environment variables. + If a variable cannot be resolved, the reference in the + input string will be unchanged. Double $$ are reduced + to a single $, which allows for escaping the $(VAR_NAME) + syntax: i.e. "$$(VAR_NAME)" will produce the string + literal "$(VAR_NAME)". Escaped references will never + be expanded, regardless of whether the variable exists + or not. Defaults to "".' + type: string + valueFrom: + description: Source for the environment variable's value. + Cannot be used if value is not empty. + properties: + configMapKeyRef: + description: Selects a key of a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + fieldRef: + description: 'Selects a field of the pod: supports + metadata.name, metadata.namespace, `metadata.labels['''']`, + `metadata.annotations['''']`, spec.nodeName, + spec.serviceAccountName, status.hostIP, status.podIP, + status.podIPs.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, limits.ephemeral-storage, requests.cpu, + requests.memory and requests.ephemeral-storage) + are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + secretKeyRef: + description: Selects a key of a secret in the pod's + namespace + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + required: + - name + type: object + type: array + envFrom: + description: List of sources to populate environment variables + in the container. The keys defined within a source must be + a C_IDENTIFIER. All invalid keys will be reported as an event + when the container is starting. When a key exists in multiple + sources, the value associated with the last source will take + precedence. Values defined by an Env with a duplicate key + will take precedence. Cannot be updated. + items: + description: EnvFromSource represents the source of a set + of ConfigMaps + properties: + configMapRef: + description: The ConfigMap to select from + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap must be + defined + type: boolean + type: object + x-kubernetes-map-type: atomic + prefix: + description: An optional identifier to prepend to each + key in the ConfigMap. Must be a C_IDENTIFIER. + type: string + secretRef: + description: The Secret to select from + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + type: object + type: array + image: + description: 'Container image name. More info: https://kubernetes.io/docs/concepts/containers/images + This field is optional to allow higher level config management + to default or override container images in workload controllers + like Deployments and StatefulSets.' + type: string + imagePullPolicy: + description: 'Image pull policy. One of Always, Never, IfNotPresent. + Defaults to Always if :latest tag is specified, or IfNotPresent + otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images' + type: string + lifecycle: + description: Actions that the management system should take + in response to container lifecycle events. Cannot be updated. + properties: + postStart: + description: 'PostStart is called immediately after a container + is created. If the handler fails, the container is terminated + and restarted according to its restart policy. Other management + of the container blocks until the hook completes. More + info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory for + the command is root ('/') in the container's + filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, you need + to explicitly call out to that shell. Exit status + of 0 is treated as live/healthy and non-zero is + unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to + the pod IP. You probably want to set "Host" in + httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the + host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported + as a LifecycleHandler and kept for the backward compatibility. + There are no validation of this field and lifecycle + hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + preStop: + description: 'PreStop is called immediately before a container + is terminated due to an API request or management event + such as liveness/startup probe failure, preemption, resource + contention, etc. The handler is not called if the container + crashes or exits. The Pod''s termination grace period + countdown begins before the PreStop hook is executed. + Regardless of the outcome of the handler, the container + will eventually terminate within the Pod''s termination + grace period (unless delayed by finalizers). Other management + of the container blocks until the hook completes or until + the termination grace period is reached. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory for + the command is root ('/') in the container's + filesystem. The command is simply exec'd, it is + not run inside a shell, so traditional shell instructions + ('|', etc) won't work. To use a shell, you need + to explicitly call out to that shell. Exit status + of 0 is treated as live/healthy and non-zero is + unhealthy. + items: + type: string + type: array + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to + the pod IP. You probably want to set "Host" in + httpHeaders instead. + type: string + httpHeaders: + description: Custom headers to set in the request. + HTTP allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the + host. Defaults to HTTP. + type: string + required: + - port + type: object + tcpSocket: + description: Deprecated. TCPSocket is NOT supported + as a LifecycleHandler and kept for the backward compatibility. + There are no validation of this field and lifecycle + hooks will fail in runtime when tcp handler is specified. + properties: + host: + description: 'Optional: Host name to connect to, + defaults to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access + on the container. Number must be in the range + 1 to 65535. Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + type: object + type: object + livenessProbe: + description: 'Periodic probe of container liveness. Container + will be restarted if the probe fails. Cannot be updated. More + info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory for the + command is root ('/') in the container's filesystem. + The command is simply exec'd, it is not run inside + a shell, so traditional shell instructions ('|', etc) + won't work. To use a shell, you need to explicitly + call out to that shell. Exit status of 0 is treated + as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe + to be considered failed after having succeeded. Defaults + to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to + place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior + is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the + pod IP. You probably want to set "Host" in httpHeaders + instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP + allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on + the container. Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has + started before liveness probes are initiated. More info: + https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe + to be considered successful after having failed. Defaults + to 1. Must be 1 for liveness and startup. Minimum value + is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP + port. + properties: + host: + description: 'Optional: Host name to connect to, defaults + to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on + the container. Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs + to terminate gracefully upon probe failure. The grace + period is the duration in seconds after the processes + running in the pod are sent a termination signal and the + time when the processes are forcibly halted with a kill + signal. Set this value longer than the expected cleanup + time for your process. If this value is nil, the pod's + terminationGracePeriodSeconds will be used. Otherwise, + this value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates + stop immediately via the kill signal (no opportunity to + shut down). This is a beta field and requires enabling + ProbeTerminationGracePeriod feature gate. Minimum value + is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times + out. Defaults to 1 second. Minimum value is 1. More info: + https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + name: + description: Name of the container specified as a DNS_LABEL. + Each container in a pod must have a unique name (DNS_LABEL). + Cannot be updated. + type: string + ports: + description: List of ports to expose from the container. Not + specifying a port here DOES NOT prevent that port from being + exposed. Any port which is listening on the default "0.0.0.0" + address inside a container will be accessible from the network. + Modifying this array with strategic merge patch may corrupt + the data. For more information See https://github.com/kubernetes/kubernetes/issues/108255. + Cannot be updated. + items: + description: ContainerPort represents a network port in a + single container. + properties: + containerPort: + description: Number of port to expose on the pod's IP + address. This must be a valid port number, 0 < x < 65536. + format: int32 + type: integer + hostIP: + description: What host IP to bind the external port to. + type: string + hostPort: + description: Number of port to expose on the host. If + specified, this must be a valid port number, 0 < x < + 65536. If HostNetwork is specified, this must match + ContainerPort. Most containers do not need this. + format: int32 + type: integer + name: + description: If specified, this must be an IANA_SVC_NAME + and unique within the pod. Each named port in a pod + must have a unique name. Name for the port that can + be referred to by services. + type: string + protocol: + default: TCP + description: Protocol for port. Must be UDP, TCP, or SCTP. + Defaults to "TCP". + type: string + required: + - containerPort + type: object + type: array + x-kubernetes-list-map-keys: + - containerPort + - protocol + x-kubernetes-list-type: map + readinessProbe: + description: 'Periodic probe of container service readiness. + Container will be removed from service endpoints if the probe + fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory for the + command is root ('/') in the container's filesystem. + The command is simply exec'd, it is not run inside + a shell, so traditional shell instructions ('|', etc) + won't work. To use a shell, you need to explicitly + call out to that shell. Exit status of 0 is treated + as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe + to be considered failed after having succeeded. Defaults + to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to + place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior + is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the + pod IP. You probably want to set "Host" in httpHeaders + instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP + allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on + the container. Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has + started before liveness probes are initiated. More info: + https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe + to be considered successful after having failed. Defaults + to 1. Must be 1 for liveness and startup. Minimum value + is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP + port. + properties: + host: + description: 'Optional: Host name to connect to, defaults + to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on + the container. Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs + to terminate gracefully upon probe failure. The grace + period is the duration in seconds after the processes + running in the pod are sent a termination signal and the + time when the processes are forcibly halted with a kill + signal. Set this value longer than the expected cleanup + time for your process. If this value is nil, the pod's + terminationGracePeriodSeconds will be used. Otherwise, + this value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates + stop immediately via the kill signal (no opportunity to + shut down). This is a beta field and requires enabling + ProbeTerminationGracePeriod feature gate. Minimum value + is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times + out. Defaults to 1 second. Minimum value is 1. More info: + https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + resizePolicy: + description: Resources resize policy for the container. + items: + description: ContainerResizePolicy represents resource resize + policy for the container. + properties: + resourceName: + description: 'Name of the resource to which this resource + resize policy applies. Supported values: cpu, memory.' + type: string + restartPolicy: + description: Restart policy to apply when specified resource + is resized. If not specified, it defaults to NotRequired. + type: string + required: + - resourceName + - restartPolicy + type: object + type: array + x-kubernetes-list-type: atomic + resources: + description: 'Compute Resources required by this container. + Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + properties: + claims: + description: "Claims lists the names of resources, defined + in spec.resourceClaims, that are used by this container. + \n This is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only + be set for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry + in pod.spec.resourceClaims of the Pod where this + field is used. It makes that resource available + inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute + resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, + otherwise to an implementation-defined value. Requests + cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + restartPolicy: + description: 'RestartPolicy defines the restart behavior of + individual containers in a pod. This field may only be set + for init containers, and the only allowed value is "Always". + For non-init containers or when this field is not specified, + the restart behavior is defined by the Pod''s restart policy + and the container type. Setting the RestartPolicy as "Always" + for the init container will have the following effect: this + init container will be continually restarted on exit until + all regular containers have terminated. Once all regular containers + have completed, all init containers with restartPolicy "Always" + will be shut down. This lifecycle differs from normal init + containers and is often referred to as a "sidecar" container. + Although this init container still starts in the init container + sequence, it does not wait for the container to complete before + proceeding to the next init container. Instead, the next init + container starts immediately after this init container is + started, or after any startupProbe has successfully completed.' + type: string + securityContext: + description: 'SecurityContext defines the security options the + container should be run with. If set, the fields of SecurityContext + override the equivalent fields of PodSecurityContext. More + info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/' + properties: + allowPrivilegeEscalation: + description: 'AllowPrivilegeEscalation controls whether + a process can gain more privileges than its parent process. + This bool directly controls if the no_new_privs flag will + be set on the container process. AllowPrivilegeEscalation + is true always when the container is: 1) run as Privileged + 2) has CAP_SYS_ADMIN Note that this field cannot be set + when spec.os.name is windows.' + type: boolean + capabilities: + description: The capabilities to add/drop when running containers. + Defaults to the default set of capabilities granted by + the container runtime. Note that this field cannot be + set when spec.os.name is windows. + properties: + add: + description: Added capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + drop: + description: Removed capabilities + items: + description: Capability represent POSIX capabilities + type + type: string + type: array + type: object + privileged: + description: Run container in privileged mode. Processes + in privileged containers are essentially equivalent to + root on the host. Defaults to false. Note that this field + cannot be set when spec.os.name is windows. + type: boolean + procMount: + description: procMount denotes the type of proc mount to + use for the containers. The default is DefaultProcMount + which uses the container runtime defaults for readonly + paths and masked paths. This requires the ProcMountType + feature flag to be enabled. Note that this field cannot + be set when spec.os.name is windows. + type: string + readOnlyRootFilesystem: + description: Whether this container has a read-only root + filesystem. Default is false. Note that this field cannot + be set when spec.os.name is windows. + type: boolean + runAsGroup: + description: The GID to run the entrypoint of the container + process. Uses runtime default if unset. May also be set + in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a + non-root user. If true, the Kubelet will validate the + image at runtime to ensure that it does not run as UID + 0 (root) and fail to start the container if it does. If + unset or false, no such validation will be performed. + May also be set in PodSecurityContext. If set in both + SecurityContext and PodSecurityContext, the value specified + in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container + process. Defaults to user specified in image metadata + if unspecified. May also be set in PodSecurityContext. If + set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to the container. + If unspecified, the container runtime will allocate a + random SELinux context for each container. May also be + set in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. Note that this field cannot be set when + spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies + to the container. + type: string + role: + description: Role is a SELinux role label that applies + to the container. + type: string + type: + description: Type is a SELinux type label that applies + to the container. + type: string + user: + description: User is a SELinux user label that applies + to the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by this container. + If seccomp options are provided at both the pod & container + level, the container options override the pod options. + Note that this field cannot be set when spec.os.name is + windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile + must be preconfigured on the node to work. Must be + a descending path, relative to the kubelet's configured + seccomp profile location. Must be set if type is "Localhost". + Must NOT be set for any other type. + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - + a profile defined in a file on the node should be + used. RuntimeDefault - the container runtime default + profile should be used. Unconfined - no profile should + be applied." + type: string + required: + - type + type: object + windowsOptions: + description: The Windows specific settings applied to all + containers. If unspecified, the options from the PodSecurityContext + will be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. + Note that this field cannot be set when spec.os.name is + linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named + by the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the + GMSA credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. All of a Pod's + containers must have the same effective HostProcess + value (it is not allowed to have a mix of HostProcess + containers and non-HostProcess containers). In addition, + if HostProcess is true then HostNetwork must also + be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set + in PodSecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence. + type: string + type: object + type: object + startupProbe: + description: 'StartupProbe indicates that the Pod has successfully + initialized. If specified, no other probes are executed until + this completes successfully. If this probe fails, the Pod + will be restarted, just as if the livenessProbe failed. This + can be used to provide different probe parameters at the beginning + of a Pod''s lifecycle, when it might take a long time to load + data or warm a cache, than during steady-state operation. + This cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + properties: + exec: + description: Exec specifies the action to take. + properties: + command: + description: Command is the command line to execute + inside the container, the working directory for the + command is root ('/') in the container's filesystem. + The command is simply exec'd, it is not run inside + a shell, so traditional shell instructions ('|', etc) + won't work. To use a shell, you need to explicitly + call out to that shell. Exit status of 0 is treated + as live/healthy and non-zero is unhealthy. + items: + type: string + type: array + type: object + failureThreshold: + description: Minimum consecutive failures for the probe + to be considered failed after having succeeded. Defaults + to 3. Minimum value is 1. + format: int32 + type: integer + grpc: + description: GRPC specifies an action involving a GRPC port. + properties: + port: + description: Port number of the gRPC service. Number + must be in the range 1 to 65535. + format: int32 + type: integer + service: + description: "Service is the name of the service to + place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). + \n If this is not specified, the default behavior + is defined by gRPC." + type: string + required: + - port + type: object + httpGet: + description: HTTPGet specifies the http request to perform. + properties: + host: + description: Host name to connect to, defaults to the + pod IP. You probably want to set "Host" in httpHeaders + instead. + type: string + httpHeaders: + description: Custom headers to set in the request. HTTP + allows repeated headers. + items: + description: HTTPHeader describes a custom header + to be used in HTTP probes + properties: + name: + description: The header field name. This will + be canonicalized upon output, so case-variant + names will be understood as the same header. + type: string + value: + description: The header field value + type: string + required: + - name + - value + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + anyOf: + - type: integer + - type: string + description: Name or number of the port to access on + the container. Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + scheme: + description: Scheme to use for connecting to the host. + Defaults to HTTP. + type: string + required: + - port + type: object + initialDelaySeconds: + description: 'Number of seconds after the container has + started before liveness probes are initiated. More info: + https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + Default to 10 seconds. Minimum value is 1. + format: int32 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe + to be considered successful after having failed. Defaults + to 1. Must be 1 for liveness and startup. Minimum value + is 1. + format: int32 + type: integer + tcpSocket: + description: TCPSocket specifies an action involving a TCP + port. + properties: + host: + description: 'Optional: Host name to connect to, defaults + to the pod IP.' + type: string + port: + anyOf: + - type: integer + - type: string + description: Number or name of the port to access on + the container. Number must be in the range 1 to 65535. + Name must be an IANA_SVC_NAME. + x-kubernetes-int-or-string: true + required: + - port + type: object + terminationGracePeriodSeconds: + description: Optional duration in seconds the pod needs + to terminate gracefully upon probe failure. The grace + period is the duration in seconds after the processes + running in the pod are sent a termination signal and the + time when the processes are forcibly halted with a kill + signal. Set this value longer than the expected cleanup + time for your process. If this value is nil, the pod's + terminationGracePeriodSeconds will be used. Otherwise, + this value overrides the value provided by the pod spec. + Value must be non-negative integer. The value zero indicates + stop immediately via the kill signal (no opportunity to + shut down). This is a beta field and requires enabling + ProbeTerminationGracePeriod feature gate. Minimum value + is 1. spec.terminationGracePeriodSeconds is used if unset. + format: int64 + type: integer + timeoutSeconds: + description: 'Number of seconds after which the probe times + out. Defaults to 1 second. Minimum value is 1. More info: + https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' + format: int32 + type: integer + type: object + stdin: + description: Whether this container should allocate a buffer + for stdin in the container runtime. If this is not set, reads + from stdin in the container will always result in EOF. Default + is false. + type: boolean + stdinOnce: + description: Whether the container runtime should close the + stdin channel after it has been opened by a single attach. + When stdin is true the stdin stream will remain open across + multiple attach sessions. If stdinOnce is set to true, stdin + is opened on container start, is empty until the first client + attaches to stdin, and then remains open and accepts data + until the client disconnects, at which time stdin is closed + and remains closed until the container is restarted. If this + flag is false, a container processes that reads from stdin + will never receive an EOF. Default is false + type: boolean + terminationMessagePath: + description: 'Optional: Path at which the file to which the + container''s termination message will be written is mounted + into the container''s filesystem. Message written is intended + to be brief final status, such as an assertion failure message. + Will be truncated by the node if greater than 4096 bytes. + The total message length across all containers will be limited + to 12kb. Defaults to /dev/termination-log. Cannot be updated.' + type: string + terminationMessagePolicy: + description: Indicate how the termination message should be + populated. File will use the contents of terminationMessagePath + to populate the container status message on both success and + failure. FallbackToLogsOnError will use the last chunk of + container log output if the termination message file is empty + and the container exited with an error. The log output is + limited to 2048 bytes or 80 lines, whichever is smaller. Defaults + to File. Cannot be updated. + type: string + tty: + description: Whether this container should allocate a TTY for + itself, also requires 'stdin' to be true. Default is false. + type: boolean + volumeDevices: + description: volumeDevices is the list of block devices to be + used by the container. + items: + description: volumeDevice describes a mapping of a raw block + device within a container. + properties: + devicePath: + description: devicePath is the path inside of the container + that the device will be mapped to. + type: string + name: + description: name must match the name of a persistentVolumeClaim + in the pod + type: string + required: + - devicePath + - name + type: object + type: array + volumeMounts: + description: Pod volumes to mount into the container's filesystem. + Cannot be updated. + items: + description: VolumeMount describes a mounting of a Volume + within a container. + properties: + mountPath: + description: Path within the container at which the volume + should be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts are + propagated from the host to container and the other + way around. When not set, MountPropagationNone is used. + This field is beta in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write otherwise + (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the container's + volume should be mounted. Defaults to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from which + the container's volume should be mounted. Behaves similarly + to SubPath but environment variable references $(VAR_NAME) + are expanded using the container's environment. Defaults + to "" (volume's root). SubPathExpr and SubPath are mutually + exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + workingDir: + description: Container's working directory. If not specified, + the container runtime's default will be used, which might + be configured in the container image. Cannot be updated. + type: string + required: + - name + type: object + type: array + integrations: + description: Integrations controls the integration subsystem of the + Agent and settings unique to deployed integration-specific pods. + properties: + namespaceSelector: + description: "Label selector for namespaces to search when discovering + integration resources. If nil, integration resources are only + discovered in the namespace of the GrafanaAgent resource. \n + Set to `{}` to search all namespaces." + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If + the operator is In or NotIn, the values array must + be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A + single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is "key", + the operator is "In", and the values array contains only + "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + selector: + description: Label selector to find Integration resources to run. + When nil, no integration resources will be defined. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If + the operator is In or NotIn, the values array must + be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A + single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is "key", + the operator is "In", and the values array contains only + "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + type: object + logFormat: + description: LogFormat controls the logging format of the generated + pods. Defaults to "logfmt" if not set. + type: string + logLevel: + description: LogLevel controls the log level of the generated pods. + Defaults to "info" if not set. + type: string + logs: + description: Logs controls the logging subsystem of the Agent and + settings unique to logging-specific pods that are deployed. + properties: + clients: + description: A global set of clients to use when a discovered + LogsInstance does not have any clients defined. + items: + description: LogsClientSpec defines the client integration for + logs, indicating which Loki server to send logs to. + properties: + backoffConfig: + description: Configures how to retry requests to Loki when + a request fails. Defaults to a minPeriod of 500ms, maxPeriod + of 5m, and maxRetries of 10. + properties: + maxPeriod: + description: Maximum backoff time between retries. + type: string + maxRetries: + description: Maximum number of retries to perform before + giving up a request. + type: integer + minPeriod: + description: Initial backoff time between retries. Time + between retries is increased exponentially. + type: string + type: object + basicAuth: + description: BasicAuth for the Loki server. + properties: + password: + description: The secret in the service monitor namespace + that contains the password for authentication. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: The secret in the service monitor namespace + that contains the username for authentication. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + batchSize: + description: Maximum batch size (in bytes) of logs to accumulate + before sending the batch to Loki. + type: integer + batchWait: + description: Maximum amount of time to wait before sending + a batch, even if that batch isn't full. + type: string + bearerToken: + description: BearerToken used for remote_write. + type: string + bearerTokenFile: + description: BearerTokenFile used to read bearer token. + type: string + externalLabels: + additionalProperties: + type: string + description: ExternalLabels are labels to add to any time + series when sending data to Loki. + type: object + oauth2: + description: Oauth2 for URL + properties: + clientId: + description: The secret or configmap containing the + OAuth2 client id + properties: + configMap: + description: ConfigMap containing data to use for + the targets. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the + targets. + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: The secret containing the OAuth2 client + secret + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: Parameters to append to the token URL + type: object + scopes: + description: OAuth2 scopes used for the token request + items: + type: string + type: array + tokenUrl: + description: The URL to fetch the token from + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyUrl: + description: ProxyURL to proxy requests through. Optional. + type: string + tenantId: + description: Tenant ID used by default to push logs to Loki. + If omitted assumes remote Loki is running in single-tenant + mode or an authentication layer is used to inject an X-Scope-OrgID + header. + type: string + timeout: + description: Maximum time to wait for a server to respond + to a request. + type: string + tlsConfig: + description: TLSConfig to use for the client. Only used + when the protocol of the URL is https. + properties: + ca: + description: Certificate authority used when verifying + server certificates. + properties: + configMap: + description: ConfigMap containing data to use for + the targets. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the + targets. + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + caFile: + description: Path to the CA cert in the Prometheus container + to use for the targets. + type: string + cert: + description: Client certificate to present when doing + client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for + the targets. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the + targets. + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + description: Path to the client cert file in the Prometheus + container for the targets. + type: string + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keyFile: + description: Path to the client key file in the Prometheus + container for the targets. + type: string + keySecret: + description: Secret containing the client key file for + the targets. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + url: + description: 'URL is the URL where Loki is listening. Must + be a full HTTP URL, including protocol. Required. Example: + https://logs-prod-us-central1.grafana.net/loki/api/v1/push.' + type: string + required: + - url + type: object + type: array + enforcedNamespaceLabel: + description: EnforcedNamespaceLabel enforces adding a namespace + label of origin for each metric that is user-created. The label + value will always be the namespace of the object that is being + created. + type: string + ignoreNamespaceSelectors: + description: IgnoreNamespaceSelectors, if true, will ignore NamespaceSelector + settings from the PodLogs configs, and they will only discover + endpoints within their current namespace. + type: boolean + instanceNamespaceSelector: + description: InstanceNamespaceSelector are the set of labels to + determine which namespaces to watch for LogInstances. If not + provided, only checks own namespace. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If + the operator is In or NotIn, the values array must + be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A + single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is "key", + the operator is "In", and the values array contains only + "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + instanceSelector: + description: InstanceSelector determines which LogInstances should + be selected for running. Each instance runs its own set of Prometheus + components, including service discovery, scraping, and remote_write. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If + the operator is In or NotIn, the values array must + be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A + single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is "key", + the operator is "In", and the values array contains only + "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + logsExternalLabelName: + description: LogsExternalLabelName is the name of the external + label used to denote Grafana Agent cluster. Defaults to "cluster." + External label will _not_ be added when value is set to the + empty string. + type: string + type: object + metrics: + description: Metrics controls the metrics subsystem of the Agent and + settings unique to metrics-specific pods that are deployed. + properties: + arbitraryFSAccessThroughSMs: + description: ArbitraryFSAccessThroughSMs configures whether configuration + based on a ServiceMonitor can access arbitrary files on the + file system of the Grafana Agent container, e.g., bearer token + files. + properties: + deny: + type: boolean + type: object + enforcedNamespaceLabel: + description: EnforcedNamespaceLabel enforces adding a namespace + label of origin for each metric that is user-created. The label + value is always the namespace of the object that is being created. + type: string + enforcedSampleLimit: + description: EnforcedSampleLimit defines a global limit on the + number of scraped samples that are accepted. This overrides + any SampleLimit set per ServiceMonitor and/or PodMonitor. It + is meant to be used by admins to enforce the SampleLimit to + keep the overall number of samples and series under the desired + limit. Note that if a SampleLimit from a ServiceMonitor or PodMonitor + is lower, that value is used instead. + format: int64 + type: integer + enforcedTargetLimit: + description: EnforcedTargetLimit defines a global limit on the + number of scraped targets. This overrides any TargetLimit set + per ServiceMonitor and/or PodMonitor. It is meant to be used + by admins to enforce the TargetLimit to keep the overall number + of targets under the desired limit. Note that if a TargetLimit + from a ServiceMonitor or PodMonitor is higher, that value is + used instead. + format: int64 + type: integer + externalLabels: + additionalProperties: + type: string + description: ExternalLabels are labels to add to any time series + when sending data over remote_write. + type: object + ignoreNamespaceSelectors: + description: IgnoreNamespaceSelectors, if true, ignores NamespaceSelector + settings from the PodMonitor and ServiceMonitor configs, so + that they only discover endpoints within their current namespace. + type: boolean + instanceNamespaceSelector: + description: InstanceNamespaceSelector is the set of labels that + determines which namespaces to watch for MetricsInstances. If + not provided, it only checks its own namespace. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If + the operator is In or NotIn, the values array must + be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A + single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is "key", + the operator is "In", and the values array contains only + "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + instanceSelector: + description: InstanceSelector determines which MetricsInstances + should be selected for running. Each instance runs its own set + of Metrics components, including service discovery, scraping, + and remote_write. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. If + the operator is In or NotIn, the values array must + be non-empty. If the operator is Exists or DoesNotExist, + the values array must be empty. This array is replaced + during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A + single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is "key", + the operator is "In", and the values array contains only + "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + metricsExternalLabelName: + description: MetricsExternalLabelName is the name of the external + label used to denote Grafana Agent cluster. Defaults to "cluster." + The external label is _not_ added when the value is set to the + empty string. + type: string + overrideHonorLabels: + description: OverrideHonorLabels, if true, overrides all configured + honor_labels read from ServiceMonitor or PodMonitor and sets + them to false. + type: boolean + overrideHonorTimestamps: + description: OverrideHonorTimestamps allows global enforcement + for honoring timestamps in all scrape configs. + type: boolean + remoteWrite: + description: RemoteWrite controls default remote_write settings + for all instances. If an instance does not provide its own RemoteWrite + settings, these will be used instead. + items: + description: RemoteWriteSpec defines the remote_write configuration + for Prometheus. + properties: + basicAuth: + description: BasicAuth for the URL. + properties: + password: + description: The secret in the service monitor namespace + that contains the password for authentication. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: The secret in the service monitor namespace + that contains the username for authentication. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearerToken: + description: BearerToken used for remote_write. + type: string + bearerTokenFile: + description: BearerTokenFile used to read bearer token. + type: string + headers: + additionalProperties: + type: string + description: Headers is a set of custom HTTP headers to + be sent along with each remote_write request. Be aware + that any headers set by Grafana Agent itself can't be + overwritten. + type: object + metadataConfig: + description: MetadataConfig configures the sending of series + metadata to remote storage. + properties: + send: + description: Send enables metric metadata to be sent + to remote storage. + type: boolean + sendInterval: + description: SendInterval controls how frequently metric + metadata is sent to remote storage. + type: string + type: object + name: + description: Name of the remote_write queue. Must be unique + if specified. The name is used in metrics and logging + in order to differentiate queues. + type: string + oauth2: + description: Oauth2 for URL + properties: + clientId: + description: The secret or configmap containing the + OAuth2 client id + properties: + configMap: + description: ConfigMap containing data to use for + the targets. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the + targets. + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: The secret containing the OAuth2 client + secret + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: Parameters to append to the token URL + type: object + scopes: + description: OAuth2 scopes used for the token request + items: + type: string + type: array + tokenUrl: + description: The URL to fetch the token from + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyUrl: + description: ProxyURL to proxy requests through. Optional. + type: string + queueConfig: + description: QueueConfig allows tuning of the remote_write + queue parameters. + properties: + batchSendDeadline: + description: BatchSendDeadline is the maximum time a + sample will wait in the buffer. + type: string + capacity: + description: Capacity is the number of samples to buffer + per shard before samples start being dropped. + type: integer + maxBackoff: + description: MaxBackoff is the maximum retry delay. + type: string + maxRetries: + description: MaxRetries is the maximum number of times + to retry a batch on recoverable errors. + type: integer + maxSamplesPerSend: + description: MaxSamplesPerSend is the maximum number + of samples per send. + type: integer + maxShards: + description: MaxShards is the maximum number of shards, + i.e., the amount of concurrency. + type: integer + minBackoff: + description: MinBackoff is the initial retry delay. + MinBackoff is doubled for every retry. + type: string + minShards: + description: MinShards is the minimum number of shards, + i.e., the amount of concurrency. + type: integer + retryOnRateLimit: + description: RetryOnRateLimit retries requests when + encountering rate limits. + type: boolean + type: object + remoteTimeout: + description: RemoteTimeout is the timeout for requests to + the remote_write endpoint. + type: string + sigv4: + description: SigV4 configures SigV4-based authentication + to the remote_write endpoint. SigV4-based authentication + is used if SigV4 is defined, even with an empty object. + properties: + accessKey: + description: AccessKey holds the secret of the AWS API + access key to use for signing. If not provided, the + environment variable AWS_ACCESS_KEY_ID is used. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + profile: + description: Profile is the named AWS profile to use + for authentication. + type: string + region: + description: Region of the AWS endpoint. If blank, the + region from the default credentials chain is used. + type: string + roleARN: + description: RoleARN is the AWS Role ARN to use for + authentication, as an alternative for using the AWS + API keys. + type: string + secretKey: + description: SecretKey of the AWS API to use for signing. + If blank, the environment variable AWS_SECRET_ACCESS_KEY + is used. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + tlsConfig: + description: TLSConfig to use for remote_write. + properties: + ca: + description: Certificate authority used when verifying + server certificates. + properties: + configMap: + description: ConfigMap containing data to use for + the targets. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the + targets. + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + caFile: + description: Path to the CA cert in the Prometheus container + to use for the targets. + type: string + cert: + description: Client certificate to present when doing + client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for + the targets. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or + its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the + targets. + properties: + key: + description: The key of the secret to select + from. Must be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, + kind, uid?' + type: string + optional: + description: Specify whether the Secret or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + description: Path to the client cert file in the Prometheus + container for the targets. + type: string + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keyFile: + description: Path to the client key file in the Prometheus + container for the targets. + type: string + keySecret: + description: Secret containing the client key file for + the targets. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + url: + description: URL of the endpoint to send samples to. + type: string + writeRelabelConfigs: + description: WriteRelabelConfigs holds relabel_configs to + relabel samples before they are sent to the remote_write + endpoint. + items: + description: 'RelabelConfig allows dynamic rewriting of + the label set, being applied to samples before ingestion. + It defines ``-section of Prometheus + configuration. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs' + properties: + action: + default: replace + description: Action to perform based on regex matching. + Default is 'replace'. uppercase and lowercase actions + require Prometheus >= 2.36. + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + description: Modulus to take of the hash of the source + label values. + format: int64 + type: integer + regex: + description: Regular expression against which the + extracted value is matched. Default is '(.*)' + type: string + replacement: + description: Replacement value against which a regex + replace is performed if the regular expression matches. + Regex capture groups are available. Default is '$1' + type: string + separator: + description: Separator placed between concatenated + source label values. default is ';'. + type: string + sourceLabels: + description: The source labels select values from + existing labels. Their content is concatenated using + the configured separator and matched against the + configured regular expression for the replace, keep, + and drop actions. + items: + description: LabelName is a valid Prometheus label + name which may only contain ASCII letters, numbers, + as well as underscores. + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + description: Label to which the resulting value is + written in a replace action. It is mandatory for + replace actions. Regex capture groups are available. + type: string + type: object + type: array + required: + - url + type: object + type: array + replicaExternalLabelName: + description: ReplicaExternalLabelName is the name of the metrics + external label used to denote the replica name. Defaults to + __replica__. The external label is _not_ added when the value + is set to the empty string. + type: string + replicas: + description: Replicas of each shard to deploy for metrics pods. + Number of replicas multiplied by the number of shards is the + total number of pods created. + format: int32 + type: integer + scrapeInterval: + description: ScrapeInterval is the time between consecutive scrapes. + type: string + scrapeTimeout: + description: ScrapeTimeout is the time to wait for a target to + respond before marking a scrape as failed. + type: string + shards: + description: Shards to distribute targets onto. Number of replicas + multiplied by the number of shards is the total number of pods + created. Note that scaling down shards does not reshard data + onto remaining instances; it must be manually moved. Increasing + shards does not reshard data either, but it will continue to + be available from the same instances. Sharding is performed + on the content of the __address__ target meta-label. + format: int32 + type: integer + type: object + nodeSelector: + additionalProperties: + type: string + description: NodeSelector defines which nodes pods should be scheduling + on. + type: object + paused: + description: Paused prevents actions except for deletion to be performed + on the underlying managed objects. + type: boolean + podMetadata: + description: PodMetadata configures Labels and Annotations which are + propagated to created Grafana Agent pods. + properties: + annotations: + additionalProperties: + type: string + description: 'Annotations is an unstructured key value map stored + with a resource that may be set by external tools to store and + retrieve arbitrary metadata. They are not queryable and should + be preserved when modifying objects. More info: http://kubernetes.io/docs/user-guide/annotations' + type: object + labels: + additionalProperties: + type: string + description: 'Map of string keys and values that can be used to + organize and categorize (scope and select) objects. May match + selectors of replication controllers and services. More info: + http://kubernetes.io/docs/user-guide/labels' + type: object + name: + description: 'Name must be unique within a namespace. Is required + when creating resources, although some resources may allow a + client to request the generation of an appropriate name automatically. + Name is primarily intended for creation idempotence and configuration + definition. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/identifiers#names' + type: string + type: object + portName: + description: Port name used for the pods and governing service. This + defaults to agent-metrics. + type: string + priorityClassName: + description: PriorityClassName is the priority class assigned to pods. + type: string + resources: + description: Resources holds requests and limits for individual pods. + properties: + claims: + description: "Claims lists the names of resources, defined in + spec.resourceClaims, that are used by this container. \n This + is an alpha field and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It can only be set + for containers." + items: + description: ResourceClaim references one entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one entry in pod.spec.resourceClaims + of the Pod where this field is used. It makes that resource + available inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount of compute resources + allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount of compute + resources required. If Requests is omitted for a container, + it defaults to Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests cannot exceed Limits. + More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + runtimeClassName: + description: RuntimeClassName is the runtime class assigned to pods. + type: string + secrets: + description: Secrets is a list of secrets in the same namespace as + the GrafanaAgent object which will be mounted into each running + Grafana Agent pod. The secrets are mounted into /var/lib/grafana-agent/extra-secrets/. + items: + type: string + type: array + securityContext: + description: SecurityContext holds pod-level security attributes and + common container settings. When unspecified, defaults to the default + PodSecurityContext. + properties: + fsGroup: + description: "A special supplemental group that applies to all + containers in a pod. Some volume types allow the Kubelet to + change the ownership of that volume to be owned by the pod: + \n 1. The owning GID will be the FSGroup 2. The setgid bit is + set (new files created in the volume will be owned by FSGroup) + 3. The permission bits are OR'd with rw-rw---- \n If unset, + the Kubelet will not modify the ownership and permissions of + any volume. Note that this field cannot be set when spec.os.name + is windows." + format: int64 + type: integer + fsGroupChangePolicy: + description: 'fsGroupChangePolicy defines behavior of changing + ownership and permission of the volume before being exposed + inside Pod. This field will only apply to volume types which + support fsGroup based ownership(and permissions). It will have + no effect on ephemeral volume types such as: secret, configmaps + and emptydir. Valid values are "OnRootMismatch" and "Always". + If not specified, "Always" is used. Note that this field cannot + be set when spec.os.name is windows.' + type: string + runAsGroup: + description: The GID to run the entrypoint of the container process. + Uses runtime default if unset. May also be set in SecurityContext. If + set in both SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence for that container. + Note that this field cannot be set when spec.os.name is windows. + format: int64 + type: integer + runAsNonRoot: + description: Indicates that the container must run as a non-root + user. If true, the Kubelet will validate the image at runtime + to ensure that it does not run as UID 0 (root) and fail to start + the container if it does. If unset or false, no such validation + will be performed. May also be set in SecurityContext. If set + in both SecurityContext and PodSecurityContext, the value specified + in SecurityContext takes precedence. + type: boolean + runAsUser: + description: The UID to run the entrypoint of the container process. + Defaults to user specified in image metadata if unspecified. + May also be set in SecurityContext. If set in both SecurityContext + and PodSecurityContext, the value specified in SecurityContext + takes precedence for that container. Note that this field cannot + be set when spec.os.name is windows. + format: int64 + type: integer + seLinuxOptions: + description: The SELinux context to be applied to all containers. + If unspecified, the container runtime will allocate a random + SELinux context for each container. May also be set in SecurityContext. If + set in both SecurityContext and PodSecurityContext, the value + specified in SecurityContext takes precedence for that container. + Note that this field cannot be set when spec.os.name is windows. + properties: + level: + description: Level is SELinux level label that applies to + the container. + type: string + role: + description: Role is a SELinux role label that applies to + the container. + type: string + type: + description: Type is a SELinux type label that applies to + the container. + type: string + user: + description: User is a SELinux user label that applies to + the container. + type: string + type: object + seccompProfile: + description: The seccomp options to use by the containers in this + pod. Note that this field cannot be set when spec.os.name is + windows. + properties: + localhostProfile: + description: localhostProfile indicates a profile defined + in a file on the node should be used. The profile must be + preconfigured on the node to work. Must be a descending + path, relative to the kubelet's configured seccomp profile + location. Must be set if type is "Localhost". Must NOT be + set for any other type. + type: string + type: + description: "type indicates which kind of seccomp profile + will be applied. Valid options are: \n Localhost - a profile + defined in a file on the node should be used. RuntimeDefault + - the container runtime default profile should be used. + Unconfined - no profile should be applied." + type: string + required: + - type + type: object + supplementalGroups: + description: A list of groups applied to the first process run + in each container, in addition to the container's primary GID, + the fsGroup (if specified), and group memberships defined in + the container image for the uid of the container process. If + unspecified, no additional groups are added to any container. + Note that group memberships defined in the container image for + the uid of the container process are still effective, even if + they are not included in this list. Note that this field cannot + be set when spec.os.name is windows. + items: + format: int64 + type: integer + type: array + sysctls: + description: Sysctls hold a list of namespaced sysctls used for + the pod. Pods with unsupported sysctls (by the container runtime) + might fail to launch. Note that this field cannot be set when + spec.os.name is windows. + items: + description: Sysctl defines a kernel parameter to be set + properties: + name: + description: Name of a property to set + type: string + value: + description: Value of a property to set + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + description: The Windows specific settings applied to all containers. + If unspecified, the options within a container's SecurityContext + will be used. If set in both SecurityContext and PodSecurityContext, + the value specified in SecurityContext takes precedence. Note + that this field cannot be set when spec.os.name is linux. + properties: + gmsaCredentialSpec: + description: GMSACredentialSpec is where the GMSA admission + webhook (https://github.com/kubernetes-sigs/windows-gmsa) + inlines the contents of the GMSA credential spec named by + the GMSACredentialSpecName field. + type: string + gmsaCredentialSpecName: + description: GMSACredentialSpecName is the name of the GMSA + credential spec to use. + type: string + hostProcess: + description: HostProcess determines if a container should + be run as a 'Host Process' container. All of a Pod's containers + must have the same effective HostProcess value (it is not + allowed to have a mix of HostProcess containers and non-HostProcess + containers). In addition, if HostProcess is true then HostNetwork + must also be set to true. + type: boolean + runAsUserName: + description: The UserName in Windows to run the entrypoint + of the container process. Defaults to the user specified + in image metadata if unspecified. May also be set in PodSecurityContext. + If set in both SecurityContext and PodSecurityContext, the + value specified in SecurityContext takes precedence. + type: string + type: object + type: object + serviceAccountName: + description: ServiceAccountName is the name of the ServiceAccount + to use for running Grafana Agent pods. + type: string + storage: + description: Storage spec to specify how storage will be used. + properties: + disableMountSubPath: + description: '*Deprecated: subPath usage will be removed in a + future release.*' + type: boolean + emptyDir: + description: 'EmptyDirVolumeSource to be used by the StatefulSet. + If specified, it takes precedence over `ephemeral` and `volumeClaimTemplate`. + More info: https://kubernetes.io/docs/concepts/storage/volumes/#emptydir' + properties: + medium: + description: 'medium represents what type of storage medium + should back this directory. The default is "" which means + to use the node''s default medium. Must be an empty string + (default) or Memory. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: 'sizeLimit is the total amount of local storage + required for this EmptyDir volume. The size limit is also + applicable for memory medium. The maximum usage on memory + medium EmptyDir would be the minimum value between the SizeLimit + specified here and the sum of memory limits of all containers + in a pod. The default is nil which means that the limit + is undefined. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: 'EphemeralVolumeSource to be used by the StatefulSet. + This is a beta field in k8s 1.21 and GA in 1.15. For lower versions, + starting with k8s 1.19, it requires enabling the GenericEphemeralVolume + feature gate. More info: https://kubernetes.io/docs/concepts/storage/ephemeral-volumes/#generic-ephemeral-volumes' + properties: + volumeClaimTemplate: + description: "Will be used to create a stand-alone PVC to + provision the volume. The pod in which this EphemeralVolumeSource + is embedded will be the owner of the PVC, i.e. the PVC will + be deleted together with the pod. The name of the PVC will + be `-` where `` is the + name from the `PodSpec.Volumes` array entry. Pod validation + will reject the pod if the concatenated name is not valid + for a PVC (for example, too long). \n An existing PVC with + that name that is not owned by the pod will *not* be used + for the pod to avoid using an unrelated volume by mistake. + Starting the pod is then blocked until the unrelated PVC + is removed. If such a pre-created PVC is meant to be used + by the pod, the PVC has to updated with an owner reference + to the pod once the pod exists. Normally this should not + be necessary, but it may be useful when manually reconstructing + a broken cluster. \n This field is read-only and no changes + will be made by Kubernetes to the PVC after it has been + created. \n Required, must not be nil." + properties: + metadata: + description: May contain labels and annotations that will + be copied into the PVC when creating it. No other fields + are allowed and will be rejected during validation. + type: object + spec: + description: The specification for the PersistentVolumeClaim. + The entire content is copied unchanged into the PVC + that gets created from this template. The same fields + as in a PersistentVolumeClaim are also valid here. + properties: + accessModes: + description: 'accessModes contains the desired access + modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + items: + type: string + type: array + dataSource: + description: 'dataSource field can be used to specify + either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) If the + provisioner or an external controller can support + the specified data source, it will create a new + volume based on the contents of the specified data + source. When the AnyVolumeDataSource feature gate + is enabled, dataSource contents will be copied to + dataSourceRef, and dataSourceRef contents will be + copied to dataSource when dataSourceRef.namespace + is not specified. If the namespace is specified, + then dataSourceRef will not be copied to dataSource.' + properties: + apiGroup: + description: APIGroup is the group for the resource + being referenced. If APIGroup is not specified, + the specified Kind must be in the core API group. + For any other third-party types, APIGroup is + required. + type: string + kind: + description: Kind is the type of resource being + referenced + type: string + name: + description: Name is the name of resource being + referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: 'dataSourceRef specifies the object from + which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a + non-empty API group (non core object) or a PersistentVolumeClaim + object. When this field is specified, volume binding + will only succeed if the type of the specified object + matches some installed volume populator or dynamic + provisioner. This field will replace the functionality + of the dataSource field and as such if both fields + are non-empty, they must have the same value. For + backwards compatibility, when namespace isn''t specified + in dataSourceRef, both fields (dataSource and dataSourceRef) + will be set to the same value automatically if one + of them is empty and the other is non-empty. When + namespace is specified in dataSourceRef, dataSource + isn''t set to the same value and must be empty. + There are three important differences between dataSource + and dataSourceRef: * While dataSource only allows + two specific types of objects, dataSourceRef allows + any non-core object, as well as PersistentVolumeClaim + objects. * While dataSource ignores disallowed values + (dropping them), dataSourceRef preserves all values, + and generates an error if a disallowed value is + specified. * While dataSource only allows local + objects, dataSourceRef allows objects in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource + feature gate to be enabled. (Alpha) Using the namespace + field of dataSourceRef requires the CrossNamespaceVolumeDataSource + feature gate to be enabled.' + properties: + apiGroup: + description: APIGroup is the group for the resource + being referenced. If APIGroup is not specified, + the specified Kind must be in the core API group. + For any other third-party types, APIGroup is + required. + type: string + kind: + description: Kind is the type of resource being + referenced + type: string + name: + description: Name is the name of resource being + referenced + type: string + namespace: + description: Namespace is the namespace of resource + being referenced Note that when a namespace + is specified, a gateway.networking.k8s.io/ReferenceGrant + object is required in the referent namespace + to allow that namespace's owner to accept the + reference. See the ReferenceGrant documentation + for details. (Alpha) This field requires the + CrossNamespaceVolumeDataSource feature gate + to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: 'resources represents the minimum resources + the volume should have. If RecoverVolumeExpansionFailure + feature is enabled users are allowed to specify + resource requirements that are lower than previous + value but must still be higher than capacity recorded + in the status field of the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' + properties: + claims: + description: "Claims lists the names of resources, + defined in spec.resourceClaims, that are used + by this container. \n This is an alpha field + and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. It + can only be set for containers." + items: + description: ResourceClaim references one entry + in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of + one entry in pod.spec.resourceClaims of + the Pod where this field is used. It makes + that resource available inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount + of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount + of compute resources required. If Requests is + omitted for a container, it defaults to Limits + if that is explicitly specified, otherwise to + an implementation-defined value. Requests cannot + exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + selector: + description: selector is a label query over volumes + to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement is + a selector that contains values, a key, and + an operator that relates the key and values. + properties: + key: + description: key is the label key that the + selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. If + the operator is Exists or DoesNotExist, + the values array must be empty. This array + is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is "In", + and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: 'storageClassName is the name of the + StorageClass required by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' + type: string + volumeMode: + description: volumeMode defines what type of volume + is required by the claim. Value of Filesystem is + implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference to + the PersistentVolume backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + volumeClaimTemplate: + description: Defines the PVC spec to be used by the Prometheus + StatefulSets. The easiest way to use a volume that cannot be + automatically provisioned is to use a label selector alongside + manually created PersistentVolumes. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this + representation of an object. Servers should convert recognized + schemas to the latest internal value, and may reject unrecognized + values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST + resource this object represents. Servers may infer this + from the endpoint the client submits requests to. Cannot + be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + description: EmbeddedMetadata contains metadata relevant to + an EmbeddedResource. + properties: + annotations: + additionalProperties: + type: string + description: 'Annotations is an unstructured key value + map stored with a resource that may be set by external + tools to store and retrieve arbitrary metadata. They + are not queryable and should be preserved when modifying + objects. More info: http://kubernetes.io/docs/user-guide/annotations' + type: object + labels: + additionalProperties: + type: string + description: 'Map of string keys and values that can be + used to organize and categorize (scope and select) objects. + May match selectors of replication controllers and services. + More info: http://kubernetes.io/docs/user-guide/labels' + type: object + name: + description: 'Name must be unique within a namespace. + Is required when creating resources, although some resources + may allow a client to request the generation of an appropriate + name automatically. Name is primarily intended for creation + idempotence and configuration definition. Cannot be + updated. More info: http://kubernetes.io/docs/user-guide/identifiers#names' + type: string + type: object + spec: + description: 'Defines the desired characteristics of a volume + requested by a pod author. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + properties: + accessModes: + description: 'accessModes contains the desired access + modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + items: + type: string + type: array + dataSource: + description: 'dataSource field can be used to specify + either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) If the provisioner + or an external controller can support the specified + data source, it will create a new volume based on the + contents of the specified data source. When the AnyVolumeDataSource + feature gate is enabled, dataSource contents will be + copied to dataSourceRef, and dataSourceRef contents + will be copied to dataSource when dataSourceRef.namespace + is not specified. If the namespace is specified, then + dataSourceRef will not be copied to dataSource.' + properties: + apiGroup: + description: APIGroup is the group for the resource + being referenced. If APIGroup is not specified, + the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: 'dataSourceRef specifies the object from + which to populate the volume with data, if a non-empty + volume is desired. This may be any object from a non-empty + API group (non core object) or a PersistentVolumeClaim + object. When this field is specified, volume binding + will only succeed if the type of the specified object + matches some installed volume populator or dynamic provisioner. + This field will replace the functionality of the dataSource + field and as such if both fields are non-empty, they + must have the same value. For backwards compatibility, + when namespace isn''t specified in dataSourceRef, both + fields (dataSource and dataSourceRef) will be set to + the same value automatically if one of them is empty + and the other is non-empty. When namespace is specified + in dataSourceRef, dataSource isn''t set to the same + value and must be empty. There are three important differences + between dataSource and dataSourceRef: * While dataSource + only allows two specific types of objects, dataSourceRef + allows any non-core object, as well as PersistentVolumeClaim + objects. * While dataSource ignores disallowed values + (dropping them), dataSourceRef preserves all values, + and generates an error if a disallowed value is specified. + * While dataSource only allows local objects, dataSourceRef + allows objects in any namespaces. (Beta) Using this + field requires the AnyVolumeDataSource feature gate + to be enabled. (Alpha) Using the namespace field of + dataSourceRef requires the CrossNamespaceVolumeDataSource + feature gate to be enabled.' + properties: + apiGroup: + description: APIGroup is the group for the resource + being referenced. If APIGroup is not specified, + the specified Kind must be in the core API group. + For any other third-party types, APIGroup is required. + type: string + kind: + description: Kind is the type of resource being referenced + type: string + name: + description: Name is the name of resource being referenced + type: string + namespace: + description: Namespace is the namespace of resource + being referenced Note that when a namespace is specified, + a gateway.networking.k8s.io/ReferenceGrant object + is required in the referent namespace to allow that + namespace's owner to accept the reference. See the + ReferenceGrant documentation for details. (Alpha) + This field requires the CrossNamespaceVolumeDataSource + feature gate to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: 'resources represents the minimum resources + the volume should have. If RecoverVolumeExpansionFailure + feature is enabled users are allowed to specify resource + requirements that are lower than previous value but + must still be higher than capacity recorded in the status + field of the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' + properties: + claims: + description: "Claims lists the names of resources, + defined in spec.resourceClaims, that are used by + this container. \n This is an alpha field and requires + enabling the DynamicResourceAllocation feature gate. + \n This field is immutable. It can only be set for + containers." + items: + description: ResourceClaim references one entry + in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name of one + entry in pod.spec.resourceClaims of the Pod + where this field is used. It makes that resource + available inside a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount + of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum amount + of compute resources required. If Requests is omitted + for a container, it defaults to Limits if that is + explicitly specified, otherwise to an implementation-defined + value. Requests cannot exceed Limits. More info: + https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + selector: + description: selector is a label query over volumes to + consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that + relates the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, + NotIn, Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. + If the operator is In or NotIn, the values + array must be non-empty. If the operator is + Exists or DoesNotExist, the values array must + be empty. This array is replaced during a + strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field + is "key", the operator is "In", and the values array + contains only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: 'storageClassName is the name of the StorageClass + required by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' + type: string + volumeMode: + description: volumeMode defines what type of volume is + required by the claim. Value of Filesystem is implied + when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference to the + PersistentVolume backing this claim. + type: string + type: object + status: + description: '*Deprecated: this field is never set.*' + properties: + accessModes: + description: 'accessModes contains the actual access modes + the volume backing the PVC has. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + items: + type: string + type: array + allocatedResourceStatuses: + additionalProperties: + description: When a controller receives persistentvolume + claim update with ClaimResourceStatus for a resource + that it does not recognizes, then it should ignore + that update and let other controllers handle it. + type: string + description: "allocatedResourceStatuses stores status + of resource being resized for the given PVC. Key names + follow standard Kubernetes label syntax. Valid values + are either: * Un-prefixed keys: - storage - the capacity + of the volume. * Custom resources must use implementation-defined + prefixed names such as \"example.com/my-custom-resource\" + Apart from above values - keys that are unprefixed or + have kubernetes.io prefix are considered reserved and + hence may not be used. \n ClaimResourceStatus can be + in any of following states: - ControllerResizeInProgress: + State set when resize controller starts resizing the + volume in control-plane. - ControllerResizeFailed: State + set when resize has failed in resize controller with + a terminal error. - NodeResizePending: State set when + resize controller has finished resizing the volume but + further resizing of volume is needed on the node. - + NodeResizeInProgress: State set when kubelet starts + resizing the volume. - NodeResizeFailed: State set when + resizing has failed in kubelet with a terminal error. + Transient errors don't set NodeResizeFailed. For example: + if expanding a PVC for more capacity - this field can + be one of the following states: - pvc.status.allocatedResourceStatus['storage'] + = \"ControllerResizeInProgress\" - pvc.status.allocatedResourceStatus['storage'] + = \"ControllerResizeFailed\" - pvc.status.allocatedResourceStatus['storage'] + = \"NodeResizePending\" - pvc.status.allocatedResourceStatus['storage'] + = \"NodeResizeInProgress\" - pvc.status.allocatedResourceStatus['storage'] + = \"NodeResizeFailed\" When this field is not set, it + means that no resize operation is in progress for the + given PVC. \n A controller that receives PVC update + with previously unknown resourceName or ClaimResourceStatus + should ignore the update for the purpose it was designed. + For example - a controller that only is responsible + for resizing capacity of the volume, should ignore PVC + updates that change other valid resources associated + with PVC. \n This is an alpha field and requires enabling + RecoverVolumeExpansionFailure feature." + type: object + x-kubernetes-map-type: granular + allocatedResources: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: "allocatedResources tracks the resources + allocated to a PVC including its capacity. Key names + follow standard Kubernetes label syntax. Valid values + are either: * Un-prefixed keys: - storage - the capacity + of the volume. * Custom resources must use implementation-defined + prefixed names such as \"example.com/my-custom-resource\" + Apart from above values - keys that are unprefixed or + have kubernetes.io prefix are considered reserved and + hence may not be used. \n Capacity reported here may + be larger than the actual capacity when a volume expansion + operation is requested. For storage quota, the larger + value from allocatedResources and PVC.spec.resources + is used. If allocatedResources is not set, PVC.spec.resources + alone is used for quota calculation. If a volume expansion + capacity request is lowered, allocatedResources is only + lowered if there are no expansion operations in progress + and if the actual volume capacity is equal or lower + than the requested capacity. \n A controller that receives + PVC update with previously unknown resourceName should + ignore the update for the purpose it was designed. For + example - a controller that only is responsible for + resizing capacity of the volume, should ignore PVC updates + that change other valid resources associated with PVC. + \n This is an alpha field and requires enabling RecoverVolumeExpansionFailure + feature." + type: object + capacity: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: capacity represents the actual resources + of the underlying volume. + type: object + conditions: + description: conditions is the current Condition of persistent + volume claim. If underlying persistent volume is being + resized then the Condition will be set to 'ResizeStarted'. + items: + description: PersistentVolumeClaimCondition contains + details about state of pvc + properties: + lastProbeTime: + description: lastProbeTime is the time we probed + the condition. + format: date-time + type: string + lastTransitionTime: + description: lastTransitionTime is the time the + condition transitioned from one status to another. + format: date-time + type: string + message: + description: message is the human-readable message + indicating details about last transition. + type: string + reason: + description: reason is a unique, this should be + a short, machine understandable string that gives + the reason for condition's last transition. If + it reports "ResizeStarted" that means the underlying + persistent volume is being resized. + type: string + status: + type: string + type: + description: PersistentVolumeClaimConditionType + is a valid value of PersistentVolumeClaimCondition.Type + type: string + required: + - status + - type + type: object + type: array + phase: + description: phase represents the current phase of PersistentVolumeClaim. + type: string + type: object + type: object + type: object + tolerations: + description: Tolerations, if specified, controls the pod's tolerations. + items: + description: The pod this Toleration is attached to tolerates any + taint that matches the triple using the matching + operator . + properties: + effect: + description: Effect indicates the taint effect to match. Empty + means match all taint effects. When specified, allowed values + are NoSchedule, PreferNoSchedule and NoExecute. + type: string + key: + description: Key is the taint key that the toleration applies + to. Empty means match all taint keys. If the key is empty, + operator must be Exists; this combination means to match all + values and all keys. + type: string + operator: + description: Operator represents a key's relationship to the + value. Valid operators are Exists and Equal. Defaults to Equal. + Exists is equivalent to wildcard for value, so that a pod + can tolerate all taints of a particular category. + type: string + tolerationSeconds: + description: TolerationSeconds represents the period of time + the toleration (which must be of effect NoExecute, otherwise + this field is ignored) tolerates the taint. By default, it + is not set, which means tolerate the taint forever (do not + evict). Zero and negative values will be treated as 0 (evict + immediately) by the system. + format: int64 + type: integer + value: + description: Value is the taint value the toleration matches + to. If the operator is Exists, the value should be empty, + otherwise just a regular string. + type: string + type: object + type: array + topologySpreadConstraints: + description: TopologySpreadConstraints, if specified, controls the + pod's topology spread constraints. + items: + description: TopologySpreadConstraint specifies how to spread matching + pods among the given topology. + properties: + labelSelector: + description: LabelSelector is used to find matching pods. Pods + that match this label selector are counted to determine the + number of pods in their corresponding topology domain. + properties: + matchExpressions: + description: matchExpressions is a list of label selector + requirements. The requirements are ANDed. + items: + description: A label selector requirement is a selector + that contains values, a key, and an operator that relates + the key and values. + properties: + key: + description: key is the label key that the selector + applies to. + type: string + operator: + description: operator represents a key's relationship + to a set of values. Valid operators are In, NotIn, + Exists and DoesNotExist. + type: string + values: + description: values is an array of string values. + If the operator is In or NotIn, the values array + must be non-empty. If the operator is Exists or + DoesNotExist, the values array must be empty. This + array is replaced during a strategic merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. + A single {key,value} in the matchLabels map is equivalent + to an element of matchExpressions, whose key field is + "key", the operator is "In", and the values array contains + only "value". The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + matchLabelKeys: + description: "MatchLabelKeys is a set of pod label keys to select + the pods over which spreading will be calculated. The keys + are used to lookup values from the incoming pod labels, those + key-value labels are ANDed with labelSelector to select the + group of existing pods over which spreading will be calculated + for the incoming pod. The same key is forbidden to exist in + both MatchLabelKeys and LabelSelector. MatchLabelKeys cannot + be set when LabelSelector isn't set. Keys that don't exist + in the incoming pod labels will be ignored. A null or empty + list means only match against labelSelector. \n This is a + beta field and requires the MatchLabelKeysInPodTopologySpread + feature gate to be enabled (enabled by default)." + items: + type: string + type: array + x-kubernetes-list-type: atomic + maxSkew: + description: 'MaxSkew describes the degree to which pods may + be unevenly distributed. When `whenUnsatisfiable=DoNotSchedule`, + it is the maximum permitted difference between the number + of matching pods in the target topology and the global minimum. + The global minimum is the minimum number of matching pods + in an eligible domain or zero if the number of eligible domains + is less than MinDomains. For example, in a 3-zone cluster, + MaxSkew is set to 1, and pods with the same labelSelector + spread as 2/2/1: In this case, the global minimum is 1. | + zone1 | zone2 | zone3 | | P P | P P | P | - if MaxSkew + is 1, incoming pod can only be scheduled to zone3 to become + 2/2/2; scheduling it onto zone1(zone2) would make the ActualSkew(3-1) + on zone1(zone2) violate MaxSkew(1). - if MaxSkew is 2, incoming + pod can be scheduled onto any zone. When `whenUnsatisfiable=ScheduleAnyway`, + it is used to give higher precedence to topologies that satisfy + it. It''s a required field. Default value is 1 and 0 is not + allowed.' + format: int32 + type: integer + minDomains: + description: "MinDomains indicates a minimum number of eligible + domains. When the number of eligible domains with matching + topology keys is less than minDomains, Pod Topology Spread + treats \"global minimum\" as 0, and then the calculation of + Skew is performed. And when the number of eligible domains + with matching topology keys equals or greater than minDomains, + this value has no effect on scheduling. As a result, when + the number of eligible domains is less than minDomains, scheduler + won't schedule more than maxSkew Pods to those domains. If + value is nil, the constraint behaves as if MinDomains is equal + to 1. Valid values are integers greater than 0. When value + is not nil, WhenUnsatisfiable must be DoNotSchedule. \n For + example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains + is set to 5 and pods with the same labelSelector spread as + 2/2/2: | zone1 | zone2 | zone3 | | P P | P P | P P | + The number of domains is less than 5(MinDomains), so \"global + minimum\" is treated as 0. In this situation, new pod with + the same labelSelector cannot be scheduled, because computed + skew will be 3(3 - 0) if new Pod is scheduled to any of the + three zones, it will violate MaxSkew. \n This is a beta field + and requires the MinDomainsInPodTopologySpread feature gate + to be enabled (enabled by default)." + format: int32 + type: integer + nodeAffinityPolicy: + description: "NodeAffinityPolicy indicates how we will treat + Pod's nodeAffinity/nodeSelector when calculating pod topology + spread skew. Options are: - Honor: only nodes matching nodeAffinity/nodeSelector + are included in the calculations. - Ignore: nodeAffinity/nodeSelector + are ignored. All nodes are included in the calculations. \n + If this value is nil, the behavior is equivalent to the Honor + policy. This is a beta-level feature default enabled by the + NodeInclusionPolicyInPodTopologySpread feature flag." + type: string + nodeTaintsPolicy: + description: "NodeTaintsPolicy indicates how we will treat node + taints when calculating pod topology spread skew. Options + are: - Honor: nodes without taints, along with tainted nodes + for which the incoming pod has a toleration, are included. + - Ignore: node taints are ignored. All nodes are included. + \n If this value is nil, the behavior is equivalent to the + Ignore policy. This is a beta-level feature default enabled + by the NodeInclusionPolicyInPodTopologySpread feature flag." + type: string + topologyKey: + description: TopologyKey is the key of node labels. Nodes that + have a label with this key and identical values are considered + to be in the same topology. We consider each + as a "bucket", and try to put balanced number of pods into + each bucket. We define a domain as a particular instance of + a topology. Also, we define an eligible domain as a domain + whose nodes meet the requirements of nodeAffinityPolicy and + nodeTaintsPolicy. e.g. If TopologyKey is "kubernetes.io/hostname", + each Node is a domain of that topology. And, if TopologyKey + is "topology.kubernetes.io/zone", each zone is a domain of + that topology. It's a required field. + type: string + whenUnsatisfiable: + description: 'WhenUnsatisfiable indicates how to deal with a + pod if it doesn''t satisfy the spread constraint. - DoNotSchedule + (default) tells the scheduler not to schedule it. - ScheduleAnyway + tells the scheduler to schedule the pod in any location, but + giving higher precedence to topologies that would help reduce + the skew. A constraint is considered "Unsatisfiable" for an + incoming pod if and only if every possible node assignment + for that pod would violate "MaxSkew" on some topology. For + example, in a 3-zone cluster, MaxSkew is set to 1, and pods + with the same labelSelector spread as 3/1/1: | zone1 | zone2 + | zone3 | | P P P | P | P | If WhenUnsatisfiable is + set to DoNotSchedule, incoming pod can only be scheduled to + zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on + zone2(zone3) satisfies MaxSkew(1). In other words, the cluster + can still be imbalanced, but scheduler won''t make it *more* + imbalanced. It''s a required field.' + type: string + required: + - maxSkew + - topologyKey + - whenUnsatisfiable + type: object + type: array + version: + description: Version of Grafana Agent to be deployed. + type: string + volumeMounts: + description: VolumeMounts lets you configure additional VolumeMounts + on the output StatefulSet definition. Specified VolumeMounts are + appended to other VolumeMounts generated as a result of StorageSpec + objects in the Grafana Agent container. + items: + description: VolumeMount describes a mounting of a Volume within + a container. + properties: + mountPath: + description: Path within the container at which the volume should + be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts are propagated + from the host to container and the other way around. When + not set, MountPropagationNone is used. This field is beta + in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write otherwise + (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the container's + volume should be mounted. Defaults to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from which the + container's volume should be mounted. Behaves similarly to + SubPath but environment variable references $(VAR_NAME) are + expanded using the container's environment. Defaults to "" + (volume's root). SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + volumes: + description: Volumes allows configuration of additional volumes on + the output StatefulSet definition. The volumes specified are appended + to other volumes that are generated as a result of StorageSpec objects. + items: + description: Volume represents a named volume in a pod that may + be accessed by any container in the pod. + properties: + awsElasticBlockStore: + description: 'awsElasticBlockStore represents an AWS Disk resource + that is attached to a kubelet''s host machine and then exposed + to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + properties: + fsType: + description: 'fsType is the filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. Examples: + "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + TODO: how do we prevent errors in the filesystem from + compromising the machine' + type: string + partition: + description: 'partition is the partition in the volume that + you want to mount. If omitted, the default is to mount + by volume name. Examples: For volume /dev/sda1, you specify + the partition as "1". Similarly, the volume partition + for /dev/sda is "0" (or you can leave the property empty).' + format: int32 + type: integer + readOnly: + description: 'readOnly value true will force the readOnly + setting in VolumeMounts. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: boolean + volumeID: + description: 'volumeID is unique ID of the persistent disk + resource in AWS (Amazon EBS volume). More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: string + required: + - volumeID + type: object + azureDisk: + description: azureDisk represents an Azure Data Disk mount on + the host and bind mount to the pod. + properties: + cachingMode: + description: 'cachingMode is the Host Caching mode: None, + Read Only, Read Write.' + type: string + diskName: + description: diskName is the Name of the data disk in the + blob storage + type: string + diskURI: + description: diskURI is the URI of data disk in the blob + storage + type: string + fsType: + description: fsType is Filesystem type to mount. Must be + a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. + type: string + kind: + description: 'kind expected values are Shared: multiple + blob disks per storage account Dedicated: single blob + disk per storage account Managed: azure managed data + disk (only in managed availability set). defaults to shared' + type: string + readOnly: + description: readOnly Defaults to false (read/write). ReadOnly + here will force the ReadOnly setting in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: azureFile represents an Azure File Service mount + on the host and bind mount to the pod. + properties: + readOnly: + description: readOnly defaults to false (read/write). ReadOnly + here will force the ReadOnly setting in VolumeMounts. + type: boolean + secretName: + description: secretName is the name of secret that contains + Azure Storage Account Name and Key + type: string + shareName: + description: shareName is the azure share Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: cephFS represents a Ceph FS mount on the host that + shares a pod's lifetime + properties: + monitors: + description: 'monitors is Required: Monitors is a collection + of Ceph monitors More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + items: + type: string + type: array + path: + description: 'path is Optional: Used as the mounted root, + rather than the full Ceph tree, default is /' + type: string + readOnly: + description: 'readOnly is Optional: Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: boolean + secretFile: + description: 'secretFile is Optional: SecretFile is the + path to key ring for User, default is /etc/ceph/user.secret + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + secretRef: + description: 'secretRef is Optional: SecretRef is reference + to the authentication secret for User, default is empty. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + x-kubernetes-map-type: atomic + user: + description: 'user is optional: User is the rados user name, + default is admin More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + required: + - monitors + type: object + cinder: + description: 'cinder represents a cinder volume attached and + mounted on kubelets host machine. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + properties: + fsType: + description: 'fsType is the filesystem type to mount. Must + be a filesystem type supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to + be "ext4" if unspecified. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + readOnly: + description: 'readOnly defaults to false (read/write). ReadOnly + here will force the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: boolean + secretRef: + description: 'secretRef is optional: points to a secret + object containing parameters used to connect to OpenStack.' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + description: 'volumeID used to identify the volume in cinder. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + required: + - volumeID + type: object + configMap: + description: configMap represents a configMap that should populate + this volume + properties: + defaultMode: + description: 'defaultMode is optional: mode bits used to + set permissions on created files by default. Must be an + octal value between 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal and decimal values, + JSON requires decimal values for mode bits. Defaults to + 0644. Directories within the path are not affected by + this setting. This might be in conflict with other options + that affect the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + items: + description: items if unspecified, each key-value pair in + the Data field of the referenced ConfigMap will be projected + into the volume as a file whose name is the key and content + is the value. If specified, the listed keys will be projected + into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in + the ConfigMap, the volume setup will error unless it is + marked optional. Paths must be relative and may not contain + the '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits used to + set permissions on this file. Must be an octal value + between 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal and decimal values, + JSON requires decimal values for mode bits. If not + specified, the volume defaultMode will be used. + This might be in conflict with other options that + affect the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path of the file + to map the key to. May not be an absolute path. + May not contain the path element '..'. May not start + with the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: optional specify whether the ConfigMap or its + keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + description: csi (Container Storage Interface) represents ephemeral + storage that is handled by certain external CSI drivers (Beta + feature). + properties: + driver: + description: driver is the name of the CSI driver that handles + this volume. Consult with your admin for the correct name + as registered in the cluster. + type: string + fsType: + description: fsType to mount. Ex. "ext4", "xfs", "ntfs". + If not provided, the empty value is passed to the associated + CSI driver which will determine the default filesystem + to apply. + type: string + nodePublishSecretRef: + description: nodePublishSecretRef is a reference to the + secret object containing sensitive information to pass + to the CSI driver to complete the CSI NodePublishVolume + and NodeUnpublishVolume calls. This field is optional, + and may be empty if no secret is required. If the secret + object contains more than one secret, all secret references + are passed. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + description: readOnly specifies a read-only configuration + for the volume. Defaults to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: volumeAttributes stores driver-specific properties + that are passed to the CSI driver. Consult your driver's + documentation for supported values. + type: object + required: + - driver + type: object + downwardAPI: + description: downwardAPI represents downward API about the pod + that should populate this volume + properties: + defaultMode: + description: 'Optional: mode bits to use on created files + by default. Must be a Optional: mode bits used to set + permissions on created files by default. Must be an octal + value between 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal and decimal values, + JSON requires decimal values for mode bits. Defaults to + 0644. Directories within the path are not affected by + this setting. This might be in conflict with other options + that affect the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + items: + description: Items is a list of downward API volume file + items: + description: DownwardAPIVolumeFile represents information + to create the file containing the pod field + properties: + fieldRef: + description: 'Required: Selects a field of the pod: + only annotations, labels, name and namespace are + supported.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: 'Optional: mode bits used to set permissions + on this file, must be an octal value between 0000 + and 0777 or a decimal value between 0 and 511. YAML + accepts both octal and decimal values, JSON requires + decimal values for mode bits. If not specified, + the volume defaultMode will be used. This might + be in conflict with other options that affect the + file mode, like fsGroup, and the result can be other + mode bits set.' + format: int32 + type: integer + path: + description: 'Required: Path is the relative path + name of the file to be created. Must not be absolute + or contain the ''..'' path. Must be utf-8 encoded. + The first item of the relative path must not start + with ''..''' + type: string + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, requests.cpu and requests.memory) + are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + emptyDir: + description: 'emptyDir represents a temporary directory that + shares a pod''s lifetime. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + properties: + medium: + description: 'medium represents what type of storage medium + should back this directory. The default is "" which means + to use the node''s default medium. Must be an empty string + (default) or Memory. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: 'sizeLimit is the total amount of local storage + required for this EmptyDir volume. The size limit is also + applicable for memory medium. The maximum usage on memory + medium EmptyDir would be the minimum value between the + SizeLimit specified here and the sum of memory limits + of all containers in a pod. The default is nil which means + that the limit is undefined. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: "ephemeral represents a volume that is handled + by a cluster storage driver. The volume's lifecycle is tied + to the pod that defines it - it will be created before the + pod starts, and deleted when the pod is removed. \n Use this + if: a) the volume is only needed while the pod runs, b) features + of normal volumes like restoring from snapshot or capacity + tracking are needed, c) the storage driver is specified through + a storage class, and d) the storage driver supports dynamic + volume provisioning through a PersistentVolumeClaim (see EphemeralVolumeSource + for more information on the connection between this volume + type and PersistentVolumeClaim). \n Use PersistentVolumeClaim + or one of the vendor-specific APIs for volumes that persist + for longer than the lifecycle of an individual pod. \n Use + CSI for light-weight local ephemeral volumes if the CSI driver + is meant to be used that way - see the documentation of the + driver for more information. \n A pod can use both types of + ephemeral volumes and persistent volumes at the same time." + properties: + volumeClaimTemplate: + description: "Will be used to create a stand-alone PVC to + provision the volume. The pod in which this EphemeralVolumeSource + is embedded will be the owner of the PVC, i.e. the PVC + will be deleted together with the pod. The name of the + PVC will be `-` where `` is the name from the `PodSpec.Volumes` array entry. + Pod validation will reject the pod if the concatenated + name is not valid for a PVC (for example, too long). \n + An existing PVC with that name that is not owned by the + pod will *not* be used for the pod to avoid using an unrelated + volume by mistake. Starting the pod is then blocked until + the unrelated PVC is removed. If such a pre-created PVC + is meant to be used by the pod, the PVC has to updated + with an owner reference to the pod once the pod exists. + Normally this should not be necessary, but it may be useful + when manually reconstructing a broken cluster. \n This + field is read-only and no changes will be made by Kubernetes + to the PVC after it has been created. \n Required, must + not be nil." + properties: + metadata: + description: May contain labels and annotations that + will be copied into the PVC when creating it. No other + fields are allowed and will be rejected during validation. + type: object + spec: + description: The specification for the PersistentVolumeClaim. + The entire content is copied unchanged into the PVC + that gets created from this template. The same fields + as in a PersistentVolumeClaim are also valid here. + properties: + accessModes: + description: 'accessModes contains the desired access + modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + items: + type: string + type: array + dataSource: + description: 'dataSource field can be used to specify + either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) If the + provisioner or an external controller can support + the specified data source, it will create a new + volume based on the contents of the specified + data source. When the AnyVolumeDataSource feature + gate is enabled, dataSource contents will be copied + to dataSourceRef, and dataSourceRef contents will + be copied to dataSource when dataSourceRef.namespace + is not specified. If the namespace is specified, + then dataSourceRef will not be copied to dataSource.' + properties: + apiGroup: + description: APIGroup is the group for the resource + being referenced. If APIGroup is not specified, + the specified Kind must be in the core API + group. For any other third-party types, APIGroup + is required. + type: string + kind: + description: Kind is the type of resource being + referenced + type: string + name: + description: Name is the name of resource being + referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: 'dataSourceRef specifies the object + from which to populate the volume with data, if + a non-empty volume is desired. This may be any + object from a non-empty API group (non core object) + or a PersistentVolumeClaim object. When this field + is specified, volume binding will only succeed + if the type of the specified object matches some + installed volume populator or dynamic provisioner. + This field will replace the functionality of the + dataSource field and as such if both fields are + non-empty, they must have the same value. For + backwards compatibility, when namespace isn''t + specified in dataSourceRef, both fields (dataSource + and dataSourceRef) will be set to the same value + automatically if one of them is empty and the + other is non-empty. When namespace is specified + in dataSourceRef, dataSource isn''t set to the + same value and must be empty. There are three + important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types + of objects, dataSourceRef allows any non-core + object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping + them), dataSourceRef preserves all values, and + generates an error if a disallowed value is specified. + * While dataSource only allows local objects, + dataSourceRef allows objects in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource + feature gate to be enabled. (Alpha) Using the + namespace field of dataSourceRef requires the + CrossNamespaceVolumeDataSource feature gate to + be enabled.' + properties: + apiGroup: + description: APIGroup is the group for the resource + being referenced. If APIGroup is not specified, + the specified Kind must be in the core API + group. For any other third-party types, APIGroup + is required. + type: string + kind: + description: Kind is the type of resource being + referenced + type: string + name: + description: Name is the name of resource being + referenced + type: string + namespace: + description: Namespace is the namespace of resource + being referenced Note that when a namespace + is specified, a gateway.networking.k8s.io/ReferenceGrant + object is required in the referent namespace + to allow that namespace's owner to accept + the reference. See the ReferenceGrant documentation + for details. (Alpha) This field requires the + CrossNamespaceVolumeDataSource feature gate + to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: 'resources represents the minimum resources + the volume should have. If RecoverVolumeExpansionFailure + feature is enabled users are allowed to specify + resource requirements that are lower than previous + value but must still be higher than capacity recorded + in the status field of the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' + properties: + claims: + description: "Claims lists the names of resources, + defined in spec.resourceClaims, that are used + by this container. \n This is an alpha field + and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. + It can only be set for containers." + items: + description: ResourceClaim references one + entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name + of one entry in pod.spec.resourceClaims + of the Pod where this field is used. + It makes that resource available inside + a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount + of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum + amount of compute resources required. If Requests + is omitted for a container, it defaults to + Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests + cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + selector: + description: selector is a label query over volumes + to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: 'storageClassName is the name of the + StorageClass required by the claim. More info: + https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' + type: string + volumeMode: + description: volumeMode defines what type of volume + is required by the claim. Value of Filesystem + is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference + to the PersistentVolume backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + fc: + description: fc represents a Fibre Channel resource that is + attached to a kubelet's host machine and then exposed to the + pod. + properties: + fsType: + description: 'fsType is the filesystem type to mount. Must + be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. TODO: how do we prevent errors in the + filesystem from compromising the machine' + type: string + lun: + description: 'lun is Optional: FC target lun number' + format: int32 + type: integer + readOnly: + description: 'readOnly is Optional: Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts.' + type: boolean + targetWWNs: + description: 'targetWWNs is Optional: FC target worldwide + names (WWNs)' + items: + type: string + type: array + wwids: + description: 'wwids Optional: FC volume world wide identifiers + (wwids) Either wwids or combination of targetWWNs and + lun must be set, but not both simultaneously.' + items: + type: string + type: array + type: object + flexVolume: + description: flexVolume represents a generic volume resource + that is provisioned/attached using an exec based plugin. + properties: + driver: + description: driver is the name of the driver to use for + this volume. + type: string + fsType: + description: fsType is the filesystem type to mount. Must + be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". The default filesystem depends + on FlexVolume script. + type: string + options: + additionalProperties: + type: string + description: 'options is Optional: this field holds extra + command options if any.' + type: object + readOnly: + description: 'readOnly is Optional: defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts.' + type: boolean + secretRef: + description: 'secretRef is Optional: secretRef is reference + to the secret object containing sensitive information + to pass to the plugin scripts. This may be empty if no + secret object is specified. If the secret object contains + more than one secret, all secrets are passed to the plugin + scripts.' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + description: flocker represents a Flocker volume attached to + a kubelet's host machine. This depends on the Flocker control + service being running + properties: + datasetName: + description: datasetName is Name of the dataset stored as + metadata -> name on the dataset for Flocker should be + considered as deprecated + type: string + datasetUUID: + description: datasetUUID is the UUID of the dataset. This + is unique identifier of a Flocker dataset + type: string + type: object + gcePersistentDisk: + description: 'gcePersistentDisk represents a GCE Disk resource + that is attached to a kubelet''s host machine and then exposed + to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + properties: + fsType: + description: 'fsType is filesystem type of the volume that + you want to mount. Tip: Ensure that the filesystem type + is supported by the host operating system. Examples: "ext4", + "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + TODO: how do we prevent errors in the filesystem from + compromising the machine' + type: string + partition: + description: 'partition is the partition in the volume that + you want to mount. If omitted, the default is to mount + by volume name. Examples: For volume /dev/sda1, you specify + the partition as "1". Similarly, the volume partition + for /dev/sda is "0" (or you can leave the property empty). + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + format: int32 + type: integer + pdName: + description: 'pdName is unique name of the PD resource in + GCE. Used to identify the disk in GCE. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: string + readOnly: + description: 'readOnly here will force the ReadOnly setting + in VolumeMounts. Defaults to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: boolean + required: + - pdName + type: object + gitRepo: + description: 'gitRepo represents a git repository at a particular + revision. DEPRECATED: GitRepo is deprecated. To provision + a container with a git repo, mount an EmptyDir into an InitContainer + that clones the repo using git, then mount the EmptyDir into + the Pod''s container.' + properties: + directory: + description: directory is the target directory name. Must + not contain or start with '..'. If '.' is supplied, the + volume directory will be the git repository. Otherwise, + if specified, the volume will contain the git repository + in the subdirectory with the given name. + type: string + repository: + description: repository is the URL + type: string + revision: + description: revision is the commit hash for the specified + revision. + type: string + required: + - repository + type: object + glusterfs: + description: 'glusterfs represents a Glusterfs mount on the + host that shares a pod''s lifetime. More info: https://examples.k8s.io/volumes/glusterfs/README.md' + properties: + endpoints: + description: 'endpoints is the endpoint name that details + Glusterfs topology. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + path: + description: 'path is the Glusterfs volume path. More info: + https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + readOnly: + description: 'readOnly here will force the Glusterfs volume + to be mounted with read-only permissions. Defaults to + false. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: 'hostPath represents a pre-existing file or directory + on the host machine that is directly exposed to the container. + This is generally used for system agents or other privileged + things that are allowed to see the host machine. Most containers + will NOT need this. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + --- TODO(jonesdl) We need to restrict who can use host directory + mounts and who can/can not mount host directories as read/write.' + properties: + path: + description: 'path of the directory on the host. If the + path is a symlink, it will follow the link to the real + path. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + type: + description: 'type for HostPath Volume Defaults to "" More + info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + required: + - path + type: object + iscsi: + description: 'iscsi represents an ISCSI Disk resource that is + attached to a kubelet''s host machine and then exposed to + the pod. More info: https://examples.k8s.io/volumes/iscsi/README.md' + properties: + chapAuthDiscovery: + description: chapAuthDiscovery defines whether support iSCSI + Discovery CHAP authentication + type: boolean + chapAuthSession: + description: chapAuthSession defines whether support iSCSI + Session CHAP authentication + type: boolean + fsType: + description: 'fsType is the filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. Examples: + "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi + TODO: how do we prevent errors in the filesystem from + compromising the machine' + type: string + initiatorName: + description: initiatorName is the custom iSCSI Initiator + Name. If initiatorName is specified with iscsiInterface + simultaneously, new iSCSI interface : will be created for the connection. + type: string + iqn: + description: iqn is the target iSCSI Qualified Name. + type: string + iscsiInterface: + description: iscsiInterface is the interface Name that uses + an iSCSI transport. Defaults to 'default' (tcp). + type: string + lun: + description: lun represents iSCSI Target Lun number. + format: int32 + type: integer + portals: + description: portals is the iSCSI Target Portal List. The + portal is either an IP or ip_addr:port if the port is + other than default (typically TCP ports 860 and 3260). + items: + type: string + type: array + readOnly: + description: readOnly here will force the ReadOnly setting + in VolumeMounts. Defaults to false. + type: boolean + secretRef: + description: secretRef is the CHAP Secret for iSCSI target + and initiator authentication + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + description: targetPortal is iSCSI Target Portal. The Portal + is either an IP or ip_addr:port if the port is other than + default (typically TCP ports 860 and 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: 'name of the volume. Must be a DNS_LABEL and unique + within the pod. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + nfs: + description: 'nfs represents an NFS mount on the host that shares + a pod''s lifetime More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + properties: + path: + description: 'path that is exported by the NFS server. More + info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + readOnly: + description: 'readOnly here will force the NFS export to + be mounted with read-only permissions. Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: boolean + server: + description: 'server is the hostname or IP address of the + NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: 'persistentVolumeClaimVolumeSource represents a + reference to a PersistentVolumeClaim in the same namespace. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + properties: + claimName: + description: 'claimName is the name of a PersistentVolumeClaim + in the same namespace as the pod using this volume. More + info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + type: string + readOnly: + description: readOnly Will force the ReadOnly setting in + VolumeMounts. Default false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: photonPersistentDisk represents a PhotonController + persistent disk attached and mounted on kubelets host machine + properties: + fsType: + description: fsType is the filesystem type to mount. Must + be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. + type: string + pdID: + description: pdID is the ID that identifies Photon Controller + persistent disk + type: string + required: + - pdID + type: object + portworxVolume: + description: portworxVolume represents a portworx volume attached + and mounted on kubelets host machine + properties: + fsType: + description: fSType represents the filesystem type to mount + Must be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs". Implicitly inferred to be "ext4" + if unspecified. + type: string + readOnly: + description: readOnly defaults to false (read/write). ReadOnly + here will force the ReadOnly setting in VolumeMounts. + type: boolean + volumeID: + description: volumeID uniquely identifies a Portworx volume + type: string + required: + - volumeID + type: object + projected: + description: projected items for all in one resources secrets, + configmaps, and downward API + properties: + defaultMode: + description: defaultMode are the mode bits used to set permissions + on created files by default. Must be an octal value between + 0000 and 0777 or a decimal value between 0 and 511. YAML + accepts both octal and decimal values, JSON requires decimal + values for mode bits. Directories within the path are + not affected by this setting. This might be in conflict + with other options that affect the file mode, like fsGroup, + and the result can be other mode bits set. + format: int32 + type: integer + sources: + description: sources is the list of volume projections + items: + description: Projection that may be projected along with + other supported volume types + properties: + configMap: + description: configMap information about the configMap + data to project + properties: + items: + description: items if unspecified, each key-value + pair in the Data field of the referenced ConfigMap + will be projected into the volume as a file + whose name is the key and content is the value. + If specified, the listed keys will be projected + into the specified paths, and unlisted keys + will not be present. If a key is specified which + is not present in the ConfigMap, the volume + setup will error unless it is marked optional. + Paths must be relative and may not contain the + '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits + used to set permissions on this file. + Must be an octal value between 0000 and + 0777 or a decimal value between 0 and + 511. YAML accepts both octal and decimal + values, JSON requires decimal values for + mode bits. If not specified, the volume + defaultMode will be used. This might be + in conflict with other options that affect + the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path of + the file to map the key to. May not be + an absolute path. May not contain the + path element '..'. May not start with + the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: optional specify whether the ConfigMap + or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + description: downwardAPI information about the downwardAPI + data to project + properties: + items: + description: Items is a list of DownwardAPIVolume + file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing + the pod field + properties: + fieldRef: + description: 'Required: Selects a field + of the pod: only annotations, labels, + name and namespace are supported.' + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, + defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: 'Optional: mode bits used to + set permissions on this file, must be + an octal value between 0000 and 0777 or + a decimal value between 0 and 511. YAML + accepts both octal and decimal values, + JSON requires decimal values for mode + bits. If not specified, the volume defaultMode + will be used. This might be in conflict + with other options that affect the file + mode, like fsGroup, and the result can + be other mode bits set.' + format: int32 + type: integer + path: + description: 'Required: Path is the relative + path name of the file to be created. Must + not be absolute or contain the ''..'' + path. Must be utf-8 encoded. The first + item of the relative path must not start + with ''..''' + type: string + resourceFieldRef: + description: 'Selects a resource of the + container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu + and requests.memory) are currently supported.' + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults + to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to + select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + secret: + description: secret information about the secret data + to project + properties: + items: + description: items if unspecified, each key-value + pair in the Data field of the referenced Secret + will be projected into the volume as a file + whose name is the key and content is the value. + If specified, the listed keys will be projected + into the specified paths, and unlisted keys + will not be present. If a key is specified which + is not present in the Secret, the volume setup + will error unless it is marked optional. Paths + must be relative and may not contain the '..' + path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits + used to set permissions on this file. + Must be an octal value between 0000 and + 0777 or a decimal value between 0 and + 511. YAML accepts both octal and decimal + values, JSON requires decimal values for + mode bits. If not specified, the volume + defaultMode will be used. This might be + in conflict with other options that affect + the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path of + the file to map the key to. May not be + an absolute path. May not contain the + path element '..'. May not start with + the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: optional field specify whether the + Secret or its key must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + description: serviceAccountToken is information about + the serviceAccountToken data to project + properties: + audience: + description: audience is the intended audience + of the token. A recipient of a token must identify + itself with an identifier specified in the audience + of the token, and otherwise should reject the + token. The audience defaults to the identifier + of the apiserver. + type: string + expirationSeconds: + description: expirationSeconds is the requested + duration of validity of the service account + token. As the token approaches expiration, the + kubelet volume plugin will proactively rotate + the service account token. The kubelet will + start trying to rotate the token if the token + is older than 80 percent of its time to live + or if the token is older than 24 hours.Defaults + to 1 hour and must be at least 10 minutes. + format: int64 + type: integer + path: + description: path is the path relative to the + mount point of the file to project the token + into. + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + description: quobyte represents a Quobyte mount on the host + that shares a pod's lifetime + properties: + group: + description: group to map volume access to Default is no + group + type: string + readOnly: + description: readOnly here will force the Quobyte volume + to be mounted with read-only permissions. Defaults to + false. + type: boolean + registry: + description: registry represents a single or multiple Quobyte + Registry services specified as a string as host:port pair + (multiple entries are separated with commas) which acts + as the central registry for volumes + type: string + tenant: + description: tenant owning the given Quobyte volume in the + Backend Used with dynamically provisioned Quobyte volumes, + value is set by the plugin + type: string + user: + description: user to map volume access to Defaults to serivceaccount + user + type: string + volume: + description: volume is a string that references an already + created Quobyte volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: 'rbd represents a Rados Block Device mount on the + host that shares a pod''s lifetime. More info: https://examples.k8s.io/volumes/rbd/README.md' + properties: + fsType: + description: 'fsType is the filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. Examples: + "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd + TODO: how do we prevent errors in the filesystem from + compromising the machine' + type: string + image: + description: 'image is the rados image name. More info: + https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + keyring: + description: 'keyring is the path to key ring for RBDUser. + Default is /etc/ceph/keyring. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + monitors: + description: 'monitors is a collection of Ceph monitors. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + items: + type: string + type: array + pool: + description: 'pool is the rados pool name. Default is rbd. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + readOnly: + description: 'readOnly here will force the ReadOnly setting + in VolumeMounts. Defaults to false. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: boolean + secretRef: + description: 'secretRef is name of the authentication secret + for RBDUser. If provided overrides keyring. Default is + nil. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + x-kubernetes-map-type: atomic + user: + description: 'user is the rados user name. Default is admin. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + required: + - image + - monitors + type: object + scaleIO: + description: scaleIO represents a ScaleIO persistent volume + attached and mounted on Kubernetes nodes. + properties: + fsType: + description: fsType is the filesystem type to mount. Must + be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Default is "xfs". + type: string + gateway: + description: gateway is the host address of the ScaleIO + API Gateway. + type: string + protectionDomain: + description: protectionDomain is the name of the ScaleIO + Protection Domain for the configured storage. + type: string + readOnly: + description: readOnly Defaults to false (read/write). ReadOnly + here will force the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: secretRef references to the secret for ScaleIO + user and other sensitive information. If this is not provided, + Login operation will fail. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + description: sslEnabled Flag enable/disable SSL communication + with Gateway, default false + type: boolean + storageMode: + description: storageMode indicates whether the storage for + a volume should be ThickProvisioned or ThinProvisioned. + Default is ThinProvisioned. + type: string + storagePool: + description: storagePool is the ScaleIO Storage Pool associated + with the protection domain. + type: string + system: + description: system is the name of the storage system as + configured in ScaleIO. + type: string + volumeName: + description: volumeName is the name of a volume already + created in the ScaleIO system that is associated with + this volume source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: 'secret represents a secret that should populate + this volume. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + properties: + defaultMode: + description: 'defaultMode is Optional: mode bits used to + set permissions on created files by default. Must be an + octal value between 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal and decimal values, + JSON requires decimal values for mode bits. Defaults to + 0644. Directories within the path are not affected by + this setting. This might be in conflict with other options + that affect the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + items: + description: items If unspecified, each key-value pair in + the Data field of the referenced Secret will be projected + into the volume as a file whose name is the key and content + is the value. If specified, the listed keys will be projected + into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in + the Secret, the volume setup will error unless it is marked + optional. Paths must be relative and may not contain the + '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits used to + set permissions on this file. Must be an octal value + between 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal and decimal values, + JSON requires decimal values for mode bits. If not + specified, the volume defaultMode will be used. + This might be in conflict with other options that + affect the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path of the file + to map the key to. May not be an absolute path. + May not contain the path element '..'. May not start + with the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether the Secret or + its keys must be defined + type: boolean + secretName: + description: 'secretName is the name of the secret in the + pod''s namespace to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + type: string + type: object + storageos: + description: storageOS represents a StorageOS volume attached + and mounted on Kubernetes nodes. + properties: + fsType: + description: fsType is the filesystem type to mount. Must + be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. + type: string + readOnly: + description: readOnly defaults to false (read/write). ReadOnly + here will force the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: secretRef specifies the secret to use for obtaining + the StorageOS API credentials. If not specified, default + values will be attempted. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + description: volumeName is the human-readable name of the + StorageOS volume. Volume names are only unique within + a namespace. + type: string + volumeNamespace: + description: volumeNamespace specifies the scope of the + volume within StorageOS. If no namespace is specified + then the Pod's namespace will be used. This allows the + Kubernetes name scoping to be mirrored within StorageOS + for tighter integration. Set VolumeName to any name to + override the default behaviour. Set to "default" if you + are not using namespaces within StorageOS. Namespaces + that do not pre-exist within StorageOS will be created. + type: string + type: object + vsphereVolume: + description: vsphereVolume represents a vSphere volume attached + and mounted on kubelets host machine + properties: + fsType: + description: fsType is filesystem type to mount. Must be + a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. + type: string + storagePolicyID: + description: storagePolicyID is the storage Policy Based + Management (SPBM) profile ID associated with the StoragePolicyName. + type: string + storagePolicyName: + description: storagePolicyName is the storage Policy Based + Management (SPBM) profile name. + type: string + volumePath: + description: volumePath is the path that identifies vSphere + volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + type: object + type: object + served: true + storage: true diff --git a/operations/agent-static-operator/crds/monitoring.grafana.com_integrations.yaml b/operations/agent-static-operator/crds/monitoring.grafana.com_integrations.yaml new file mode 100644 index 000000000000..e786166447fd --- /dev/null +++ b/operations/agent-static-operator/crds/monitoring.grafana.com_integrations.yaml @@ -0,0 +1,1738 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.9.2 + creationTimestamp: null + name: integrations.monitoring.grafana.com +spec: + group: monitoring.grafana.com + names: + categories: + - agent-operator + kind: Integration + listKind: IntegrationList + plural: integrations + singular: integration + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: "Integration runs a single Grafana Agent integration. Integrations + that generate telemetry must be configured to send that telemetry somewhere, + such as autoscrape for exporter-based integrations. \n Integrations have + access to the LogsInstances and MetricsInstances in the same GrafanaAgent + resource set, referenced by the / of the Instance resource. + \n For example, if there is a default/production MetricsInstance, you can + configure a supported integration's autoscrape block with: \n autoscrape: + enable: true metrics_instance: default/production \n There is currently + no way for telemetry created by an Operator-managed integration to be collected + from outside of the integration itself." + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Specifies the desired behavior of the Integration. + properties: + config: + description: "The configuration for the named integration. Note that + Integrations are deployed with the integrations-next feature flag, + which has different common settings: \n https://grafana.com/docs/agent/latest/configuration/integrations/integrations-next/" + type: object + x-kubernetes-preserve-unknown-fields: true + configMaps: + description: "An extra list of keys from ConfigMaps in the same namespace + as the Integration which will be mounted into the Grafana Agent + pod running this Integration. \n ConfigMaps are mounted at /etc/grafana-agent/integrations/configMaps///." + items: + description: Selects a key from a ConfigMap. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the ConfigMap or its key must be + defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + name: + description: Name of the integration to run (e.g., "node_exporter", + "mysqld_exporter"). + type: string + secrets: + description: "An extra list of keys from Secrets in the same namespace + as the Integration which will be mounted into the Grafana Agent + pod running this Integration. \n Secrets will be mounted at /etc/grafana-agent/integrations/secrets///." + items: + description: SecretKeySelector selects a key of a Secret. + properties: + key: + description: The key of the secret to select from. Must be + a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: array + type: + description: Type informs Grafana Agent Operator about how to manage + the integration being configured. + properties: + allNodes: + description: When true, the configured integration should be run + on every Node in the cluster. This is required for Integrations + that generate Node-specific metrics like node_exporter, otherwise + it must be false to avoid generating duplicate metrics. + type: boolean + unique: + description: Whether this integration can only be defined once + for a Grafana Agent process, such as statsd_exporter. It is + invalid for a GrafanaAgent to discover multiple unique Integrations + with the same Integration name (i.e., a single GrafanaAgent + cannot deploy two statsd_exporters). + type: boolean + type: object + volumeMounts: + description: "An extra list of VolumeMounts to be associated with + the Grafana Agent pods running this integration. VolumeMount names + are mutated to be unique across all used IntegrationSpecs. \n Mount + paths should include the namespace/name of the Integration CR to + avoid potentially colliding with other resources." + items: + description: VolumeMount describes a mounting of a Volume within + a container. + properties: + mountPath: + description: Path within the container at which the volume should + be mounted. Must not contain ':'. + type: string + mountPropagation: + description: mountPropagation determines how mounts are propagated + from the host to container and the other way around. When + not set, MountPropagationNone is used. This field is beta + in 1.10. + type: string + name: + description: This must match the Name of a Volume. + type: string + readOnly: + description: Mounted read-only if true, read-write otherwise + (false or unspecified). Defaults to false. + type: boolean + subPath: + description: Path within the volume from which the container's + volume should be mounted. Defaults to "" (volume's root). + type: string + subPathExpr: + description: Expanded path within the volume from which the + container's volume should be mounted. Behaves similarly to + SubPath but environment variable references $(VAR_NAME) are + expanded using the container's environment. Defaults to "" + (volume's root). SubPathExpr and SubPath are mutually exclusive. + type: string + required: + - mountPath + - name + type: object + type: array + volumes: + description: "An extra list of Volumes to be associated with the Grafana + Agent pods running this integration. Volume names are mutated to + be unique across all Integrations. Note that the specified volumes + should be able to tolerate existing on multiple pods at once when + type is daemonset. \n Don't use volumes for loading Secrets or ConfigMaps + from the same namespace as the Integration; use the Secrets and + ConfigMaps fields instead." + items: + description: Volume represents a named volume in a pod that may + be accessed by any container in the pod. + properties: + awsElasticBlockStore: + description: 'awsElasticBlockStore represents an AWS Disk resource + that is attached to a kubelet''s host machine and then exposed + to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + properties: + fsType: + description: 'fsType is the filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. Examples: + "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore + TODO: how do we prevent errors in the filesystem from + compromising the machine' + type: string + partition: + description: 'partition is the partition in the volume that + you want to mount. If omitted, the default is to mount + by volume name. Examples: For volume /dev/sda1, you specify + the partition as "1". Similarly, the volume partition + for /dev/sda is "0" (or you can leave the property empty).' + format: int32 + type: integer + readOnly: + description: 'readOnly value true will force the readOnly + setting in VolumeMounts. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: boolean + volumeID: + description: 'volumeID is unique ID of the persistent disk + resource in AWS (Amazon EBS volume). More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' + type: string + required: + - volumeID + type: object + azureDisk: + description: azureDisk represents an Azure Data Disk mount on + the host and bind mount to the pod. + properties: + cachingMode: + description: 'cachingMode is the Host Caching mode: None, + Read Only, Read Write.' + type: string + diskName: + description: diskName is the Name of the data disk in the + blob storage + type: string + diskURI: + description: diskURI is the URI of data disk in the blob + storage + type: string + fsType: + description: fsType is Filesystem type to mount. Must be + a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. + type: string + kind: + description: 'kind expected values are Shared: multiple + blob disks per storage account Dedicated: single blob + disk per storage account Managed: azure managed data + disk (only in managed availability set). defaults to shared' + type: string + readOnly: + description: readOnly Defaults to false (read/write). ReadOnly + here will force the ReadOnly setting in VolumeMounts. + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + description: azureFile represents an Azure File Service mount + on the host and bind mount to the pod. + properties: + readOnly: + description: readOnly defaults to false (read/write). ReadOnly + here will force the ReadOnly setting in VolumeMounts. + type: boolean + secretName: + description: secretName is the name of secret that contains + Azure Storage Account Name and Key + type: string + shareName: + description: shareName is the azure share Name + type: string + required: + - secretName + - shareName + type: object + cephfs: + description: cephFS represents a Ceph FS mount on the host that + shares a pod's lifetime + properties: + monitors: + description: 'monitors is Required: Monitors is a collection + of Ceph monitors More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + items: + type: string + type: array + path: + description: 'path is Optional: Used as the mounted root, + rather than the full Ceph tree, default is /' + type: string + readOnly: + description: 'readOnly is Optional: Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: boolean + secretFile: + description: 'secretFile is Optional: SecretFile is the + path to key ring for User, default is /etc/ceph/user.secret + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + secretRef: + description: 'secretRef is Optional: SecretRef is reference + to the authentication secret for User, default is empty. + More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + x-kubernetes-map-type: atomic + user: + description: 'user is optional: User is the rados user name, + default is admin More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' + type: string + required: + - monitors + type: object + cinder: + description: 'cinder represents a cinder volume attached and + mounted on kubelets host machine. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + properties: + fsType: + description: 'fsType is the filesystem type to mount. Must + be a filesystem type supported by the host operating system. + Examples: "ext4", "xfs", "ntfs". Implicitly inferred to + be "ext4" if unspecified. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + readOnly: + description: 'readOnly defaults to false (read/write). ReadOnly + here will force the ReadOnly setting in VolumeMounts. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: boolean + secretRef: + description: 'secretRef is optional: points to a secret + object containing parameters used to connect to OpenStack.' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + x-kubernetes-map-type: atomic + volumeID: + description: 'volumeID used to identify the volume in cinder. + More info: https://examples.k8s.io/mysql-cinder-pd/README.md' + type: string + required: + - volumeID + type: object + configMap: + description: configMap represents a configMap that should populate + this volume + properties: + defaultMode: + description: 'defaultMode is optional: mode bits used to + set permissions on created files by default. Must be an + octal value between 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal and decimal values, + JSON requires decimal values for mode bits. Defaults to + 0644. Directories within the path are not affected by + this setting. This might be in conflict with other options + that affect the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + items: + description: items if unspecified, each key-value pair in + the Data field of the referenced ConfigMap will be projected + into the volume as a file whose name is the key and content + is the value. If specified, the listed keys will be projected + into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in + the ConfigMap, the volume setup will error unless it is + marked optional. Paths must be relative and may not contain + the '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits used to + set permissions on this file. Must be an octal value + between 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal and decimal values, + JSON requires decimal values for mode bits. If not + specified, the volume defaultMode will be used. + This might be in conflict with other options that + affect the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path of the file + to map the key to. May not be an absolute path. + May not contain the path element '..'. May not start + with the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: optional specify whether the ConfigMap or its + keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + csi: + description: csi (Container Storage Interface) represents ephemeral + storage that is handled by certain external CSI drivers (Beta + feature). + properties: + driver: + description: driver is the name of the CSI driver that handles + this volume. Consult with your admin for the correct name + as registered in the cluster. + type: string + fsType: + description: fsType to mount. Ex. "ext4", "xfs", "ntfs". + If not provided, the empty value is passed to the associated + CSI driver which will determine the default filesystem + to apply. + type: string + nodePublishSecretRef: + description: nodePublishSecretRef is a reference to the + secret object containing sensitive information to pass + to the CSI driver to complete the CSI NodePublishVolume + and NodeUnpublishVolume calls. This field is optional, + and may be empty if no secret is required. If the secret + object contains more than one secret, all secret references + are passed. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + x-kubernetes-map-type: atomic + readOnly: + description: readOnly specifies a read-only configuration + for the volume. Defaults to false (read/write). + type: boolean + volumeAttributes: + additionalProperties: + type: string + description: volumeAttributes stores driver-specific properties + that are passed to the CSI driver. Consult your driver's + documentation for supported values. + type: object + required: + - driver + type: object + downwardAPI: + description: downwardAPI represents downward API about the pod + that should populate this volume + properties: + defaultMode: + description: 'Optional: mode bits to use on created files + by default. Must be a Optional: mode bits used to set + permissions on created files by default. Must be an octal + value between 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal and decimal values, + JSON requires decimal values for mode bits. Defaults to + 0644. Directories within the path are not affected by + this setting. This might be in conflict with other options + that affect the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + items: + description: Items is a list of downward API volume file + items: + description: DownwardAPIVolumeFile represents information + to create the file containing the pod field + properties: + fieldRef: + description: 'Required: Selects a field of the pod: + only annotations, labels, name and namespace are + supported.' + properties: + apiVersion: + description: Version of the schema the FieldPath + is written in terms of, defaults to "v1". + type: string + fieldPath: + description: Path of the field to select in the + specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: 'Optional: mode bits used to set permissions + on this file, must be an octal value between 0000 + and 0777 or a decimal value between 0 and 511. YAML + accepts both octal and decimal values, JSON requires + decimal values for mode bits. If not specified, + the volume defaultMode will be used. This might + be in conflict with other options that affect the + file mode, like fsGroup, and the result can be other + mode bits set.' + format: int32 + type: integer + path: + description: 'Required: Path is the relative path + name of the file to be created. Must not be absolute + or contain the ''..'' path. Must be utf-8 encoded. + The first item of the relative path must not start + with ''..''' + type: string + resourceFieldRef: + description: 'Selects a resource of the container: + only resources limits and requests (limits.cpu, + limits.memory, requests.cpu and requests.memory) + are currently supported.' + properties: + containerName: + description: 'Container name: required for volumes, + optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format of the + exposed resources, defaults to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + emptyDir: + description: 'emptyDir represents a temporary directory that + shares a pod''s lifetime. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + properties: + medium: + description: 'medium represents what type of storage medium + should back this directory. The default is "" which means + to use the node''s default medium. Must be an empty string + (default) or Memory. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + description: 'sizeLimit is the total amount of local storage + required for this EmptyDir volume. The size limit is also + applicable for memory medium. The maximum usage on memory + medium EmptyDir would be the minimum value between the + SizeLimit specified here and the sum of memory limits + of all containers in a pod. The default is nil which means + that the limit is undefined. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + description: "ephemeral represents a volume that is handled + by a cluster storage driver. The volume's lifecycle is tied + to the pod that defines it - it will be created before the + pod starts, and deleted when the pod is removed. \n Use this + if: a) the volume is only needed while the pod runs, b) features + of normal volumes like restoring from snapshot or capacity + tracking are needed, c) the storage driver is specified through + a storage class, and d) the storage driver supports dynamic + volume provisioning through a PersistentVolumeClaim (see EphemeralVolumeSource + for more information on the connection between this volume + type and PersistentVolumeClaim). \n Use PersistentVolumeClaim + or one of the vendor-specific APIs for volumes that persist + for longer than the lifecycle of an individual pod. \n Use + CSI for light-weight local ephemeral volumes if the CSI driver + is meant to be used that way - see the documentation of the + driver for more information. \n A pod can use both types of + ephemeral volumes and persistent volumes at the same time." + properties: + volumeClaimTemplate: + description: "Will be used to create a stand-alone PVC to + provision the volume. The pod in which this EphemeralVolumeSource + is embedded will be the owner of the PVC, i.e. the PVC + will be deleted together with the pod. The name of the + PVC will be `-` where `` is the name from the `PodSpec.Volumes` array entry. + Pod validation will reject the pod if the concatenated + name is not valid for a PVC (for example, too long). \n + An existing PVC with that name that is not owned by the + pod will *not* be used for the pod to avoid using an unrelated + volume by mistake. Starting the pod is then blocked until + the unrelated PVC is removed. If such a pre-created PVC + is meant to be used by the pod, the PVC has to updated + with an owner reference to the pod once the pod exists. + Normally this should not be necessary, but it may be useful + when manually reconstructing a broken cluster. \n This + field is read-only and no changes will be made by Kubernetes + to the PVC after it has been created. \n Required, must + not be nil." + properties: + metadata: + description: May contain labels and annotations that + will be copied into the PVC when creating it. No other + fields are allowed and will be rejected during validation. + type: object + spec: + description: The specification for the PersistentVolumeClaim. + The entire content is copied unchanged into the PVC + that gets created from this template. The same fields + as in a PersistentVolumeClaim are also valid here. + properties: + accessModes: + description: 'accessModes contains the desired access + modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' + items: + type: string + type: array + dataSource: + description: 'dataSource field can be used to specify + either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) + * An existing PVC (PersistentVolumeClaim) If the + provisioner or an external controller can support + the specified data source, it will create a new + volume based on the contents of the specified + data source. When the AnyVolumeDataSource feature + gate is enabled, dataSource contents will be copied + to dataSourceRef, and dataSourceRef contents will + be copied to dataSource when dataSourceRef.namespace + is not specified. If the namespace is specified, + then dataSourceRef will not be copied to dataSource.' + properties: + apiGroup: + description: APIGroup is the group for the resource + being referenced. If APIGroup is not specified, + the specified Kind must be in the core API + group. For any other third-party types, APIGroup + is required. + type: string + kind: + description: Kind is the type of resource being + referenced + type: string + name: + description: Name is the name of resource being + referenced + type: string + required: + - kind + - name + type: object + x-kubernetes-map-type: atomic + dataSourceRef: + description: 'dataSourceRef specifies the object + from which to populate the volume with data, if + a non-empty volume is desired. This may be any + object from a non-empty API group (non core object) + or a PersistentVolumeClaim object. When this field + is specified, volume binding will only succeed + if the type of the specified object matches some + installed volume populator or dynamic provisioner. + This field will replace the functionality of the + dataSource field and as such if both fields are + non-empty, they must have the same value. For + backwards compatibility, when namespace isn''t + specified in dataSourceRef, both fields (dataSource + and dataSourceRef) will be set to the same value + automatically if one of them is empty and the + other is non-empty. When namespace is specified + in dataSourceRef, dataSource isn''t set to the + same value and must be empty. There are three + important differences between dataSource and dataSourceRef: + * While dataSource only allows two specific types + of objects, dataSourceRef allows any non-core + object, as well as PersistentVolumeClaim objects. + * While dataSource ignores disallowed values (dropping + them), dataSourceRef preserves all values, and + generates an error if a disallowed value is specified. + * While dataSource only allows local objects, + dataSourceRef allows objects in any namespaces. + (Beta) Using this field requires the AnyVolumeDataSource + feature gate to be enabled. (Alpha) Using the + namespace field of dataSourceRef requires the + CrossNamespaceVolumeDataSource feature gate to + be enabled.' + properties: + apiGroup: + description: APIGroup is the group for the resource + being referenced. If APIGroup is not specified, + the specified Kind must be in the core API + group. For any other third-party types, APIGroup + is required. + type: string + kind: + description: Kind is the type of resource being + referenced + type: string + name: + description: Name is the name of resource being + referenced + type: string + namespace: + description: Namespace is the namespace of resource + being referenced Note that when a namespace + is specified, a gateway.networking.k8s.io/ReferenceGrant + object is required in the referent namespace + to allow that namespace's owner to accept + the reference. See the ReferenceGrant documentation + for details. (Alpha) This field requires the + CrossNamespaceVolumeDataSource feature gate + to be enabled. + type: string + required: + - kind + - name + type: object + resources: + description: 'resources represents the minimum resources + the volume should have. If RecoverVolumeExpansionFailure + feature is enabled users are allowed to specify + resource requirements that are lower than previous + value but must still be higher than capacity recorded + in the status field of the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' + properties: + claims: + description: "Claims lists the names of resources, + defined in spec.resourceClaims, that are used + by this container. \n This is an alpha field + and requires enabling the DynamicResourceAllocation + feature gate. \n This field is immutable. + It can only be set for containers." + items: + description: ResourceClaim references one + entry in PodSpec.ResourceClaims. + properties: + name: + description: Name must match the name + of one entry in pod.spec.resourceClaims + of the Pod where this field is used. + It makes that resource available inside + a container. + type: string + required: + - name + type: object + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Limits describes the maximum amount + of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + description: 'Requests describes the minimum + amount of compute resources required. If Requests + is omitted for a container, it defaults to + Limits if that is explicitly specified, otherwise + to an implementation-defined value. Requests + cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' + type: object + type: object + selector: + description: selector is a label query over volumes + to consider for binding. + properties: + matchExpressions: + description: matchExpressions is a list of label + selector requirements. The requirements are + ANDed. + items: + description: A label selector requirement + is a selector that contains values, a key, + and an operator that relates the key and + values. + properties: + key: + description: key is the label key that + the selector applies to. + type: string + operator: + description: operator represents a key's + relationship to a set of values. Valid + operators are In, NotIn, Exists and + DoesNotExist. + type: string + values: + description: values is an array of string + values. If the operator is In or NotIn, + the values array must be non-empty. + If the operator is Exists or DoesNotExist, + the values array must be empty. This + array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} + pairs. A single {key,value} in the matchLabels + map is equivalent to an element of matchExpressions, + whose key field is "key", the operator is + "In", and the values array contains only "value". + The requirements are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + storageClassName: + description: 'storageClassName is the name of the + StorageClass required by the claim. More info: + https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' + type: string + volumeMode: + description: volumeMode defines what type of volume + is required by the claim. Value of Filesystem + is implied when not included in claim spec. + type: string + volumeName: + description: volumeName is the binding reference + to the PersistentVolume backing this claim. + type: string + type: object + required: + - spec + type: object + type: object + fc: + description: fc represents a Fibre Channel resource that is + attached to a kubelet's host machine and then exposed to the + pod. + properties: + fsType: + description: 'fsType is the filesystem type to mount. Must + be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. TODO: how do we prevent errors in the + filesystem from compromising the machine' + type: string + lun: + description: 'lun is Optional: FC target lun number' + format: int32 + type: integer + readOnly: + description: 'readOnly is Optional: Defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts.' + type: boolean + targetWWNs: + description: 'targetWWNs is Optional: FC target worldwide + names (WWNs)' + items: + type: string + type: array + wwids: + description: 'wwids Optional: FC volume world wide identifiers + (wwids) Either wwids or combination of targetWWNs and + lun must be set, but not both simultaneously.' + items: + type: string + type: array + type: object + flexVolume: + description: flexVolume represents a generic volume resource + that is provisioned/attached using an exec based plugin. + properties: + driver: + description: driver is the name of the driver to use for + this volume. + type: string + fsType: + description: fsType is the filesystem type to mount. Must + be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". The default filesystem depends + on FlexVolume script. + type: string + options: + additionalProperties: + type: string + description: 'options is Optional: this field holds extra + command options if any.' + type: object + readOnly: + description: 'readOnly is Optional: defaults to false (read/write). + ReadOnly here will force the ReadOnly setting in VolumeMounts.' + type: boolean + secretRef: + description: 'secretRef is Optional: secretRef is reference + to the secret object containing sensitive information + to pass to the plugin scripts. This may be empty if no + secret object is specified. If the secret object contains + more than one secret, all secrets are passed to the plugin + scripts.' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + x-kubernetes-map-type: atomic + required: + - driver + type: object + flocker: + description: flocker represents a Flocker volume attached to + a kubelet's host machine. This depends on the Flocker control + service being running + properties: + datasetName: + description: datasetName is Name of the dataset stored as + metadata -> name on the dataset for Flocker should be + considered as deprecated + type: string + datasetUUID: + description: datasetUUID is the UUID of the dataset. This + is unique identifier of a Flocker dataset + type: string + type: object + gcePersistentDisk: + description: 'gcePersistentDisk represents a GCE Disk resource + that is attached to a kubelet''s host machine and then exposed + to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + properties: + fsType: + description: 'fsType is filesystem type of the volume that + you want to mount. Tip: Ensure that the filesystem type + is supported by the host operating system. Examples: "ext4", + "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk + TODO: how do we prevent errors in the filesystem from + compromising the machine' + type: string + partition: + description: 'partition is the partition in the volume that + you want to mount. If omitted, the default is to mount + by volume name. Examples: For volume /dev/sda1, you specify + the partition as "1". Similarly, the volume partition + for /dev/sda is "0" (or you can leave the property empty). + More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + format: int32 + type: integer + pdName: + description: 'pdName is unique name of the PD resource in + GCE. Used to identify the disk in GCE. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: string + readOnly: + description: 'readOnly here will force the ReadOnly setting + in VolumeMounts. Defaults to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' + type: boolean + required: + - pdName + type: object + gitRepo: + description: 'gitRepo represents a git repository at a particular + revision. DEPRECATED: GitRepo is deprecated. To provision + a container with a git repo, mount an EmptyDir into an InitContainer + that clones the repo using git, then mount the EmptyDir into + the Pod''s container.' + properties: + directory: + description: directory is the target directory name. Must + not contain or start with '..'. If '.' is supplied, the + volume directory will be the git repository. Otherwise, + if specified, the volume will contain the git repository + in the subdirectory with the given name. + type: string + repository: + description: repository is the URL + type: string + revision: + description: revision is the commit hash for the specified + revision. + type: string + required: + - repository + type: object + glusterfs: + description: 'glusterfs represents a Glusterfs mount on the + host that shares a pod''s lifetime. More info: https://examples.k8s.io/volumes/glusterfs/README.md' + properties: + endpoints: + description: 'endpoints is the endpoint name that details + Glusterfs topology. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + path: + description: 'path is the Glusterfs volume path. More info: + https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: string + readOnly: + description: 'readOnly here will force the Glusterfs volume + to be mounted with read-only permissions. Defaults to + false. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' + type: boolean + required: + - endpoints + - path + type: object + hostPath: + description: 'hostPath represents a pre-existing file or directory + on the host machine that is directly exposed to the container. + This is generally used for system agents or other privileged + things that are allowed to see the host machine. Most containers + will NOT need this. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath + --- TODO(jonesdl) We need to restrict who can use host directory + mounts and who can/can not mount host directories as read/write.' + properties: + path: + description: 'path of the directory on the host. If the + path is a symlink, it will follow the link to the real + path. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + type: + description: 'type for HostPath Volume Defaults to "" More + info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' + type: string + required: + - path + type: object + iscsi: + description: 'iscsi represents an ISCSI Disk resource that is + attached to a kubelet''s host machine and then exposed to + the pod. More info: https://examples.k8s.io/volumes/iscsi/README.md' + properties: + chapAuthDiscovery: + description: chapAuthDiscovery defines whether support iSCSI + Discovery CHAP authentication + type: boolean + chapAuthSession: + description: chapAuthSession defines whether support iSCSI + Session CHAP authentication + type: boolean + fsType: + description: 'fsType is the filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. Examples: + "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi + TODO: how do we prevent errors in the filesystem from + compromising the machine' + type: string + initiatorName: + description: initiatorName is the custom iSCSI Initiator + Name. If initiatorName is specified with iscsiInterface + simultaneously, new iSCSI interface : will be created for the connection. + type: string + iqn: + description: iqn is the target iSCSI Qualified Name. + type: string + iscsiInterface: + description: iscsiInterface is the interface Name that uses + an iSCSI transport. Defaults to 'default' (tcp). + type: string + lun: + description: lun represents iSCSI Target Lun number. + format: int32 + type: integer + portals: + description: portals is the iSCSI Target Portal List. The + portal is either an IP or ip_addr:port if the port is + other than default (typically TCP ports 860 and 3260). + items: + type: string + type: array + readOnly: + description: readOnly here will force the ReadOnly setting + in VolumeMounts. Defaults to false. + type: boolean + secretRef: + description: secretRef is the CHAP Secret for iSCSI target + and initiator authentication + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + x-kubernetes-map-type: atomic + targetPortal: + description: targetPortal is iSCSI Target Portal. The Portal + is either an IP or ip_addr:port if the port is other than + default (typically TCP ports 860 and 3260). + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + description: 'name of the volume. Must be a DNS_LABEL and unique + within the pod. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' + type: string + nfs: + description: 'nfs represents an NFS mount on the host that shares + a pod''s lifetime More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + properties: + path: + description: 'path that is exported by the NFS server. More + info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + readOnly: + description: 'readOnly here will force the NFS export to + be mounted with read-only permissions. Defaults to false. + More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: boolean + server: + description: 'server is the hostname or IP address of the + NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + description: 'persistentVolumeClaimVolumeSource represents a + reference to a PersistentVolumeClaim in the same namespace. + More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + properties: + claimName: + description: 'claimName is the name of a PersistentVolumeClaim + in the same namespace as the pod using this volume. More + info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' + type: string + readOnly: + description: readOnly Will force the ReadOnly setting in + VolumeMounts. Default false. + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + description: photonPersistentDisk represents a PhotonController + persistent disk attached and mounted on kubelets host machine + properties: + fsType: + description: fsType is the filesystem type to mount. Must + be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. + type: string + pdID: + description: pdID is the ID that identifies Photon Controller + persistent disk + type: string + required: + - pdID + type: object + portworxVolume: + description: portworxVolume represents a portworx volume attached + and mounted on kubelets host machine + properties: + fsType: + description: fSType represents the filesystem type to mount + Must be a filesystem type supported by the host operating + system. Ex. "ext4", "xfs". Implicitly inferred to be "ext4" + if unspecified. + type: string + readOnly: + description: readOnly defaults to false (read/write). ReadOnly + here will force the ReadOnly setting in VolumeMounts. + type: boolean + volumeID: + description: volumeID uniquely identifies a Portworx volume + type: string + required: + - volumeID + type: object + projected: + description: projected items for all in one resources secrets, + configmaps, and downward API + properties: + defaultMode: + description: defaultMode are the mode bits used to set permissions + on created files by default. Must be an octal value between + 0000 and 0777 or a decimal value between 0 and 511. YAML + accepts both octal and decimal values, JSON requires decimal + values for mode bits. Directories within the path are + not affected by this setting. This might be in conflict + with other options that affect the file mode, like fsGroup, + and the result can be other mode bits set. + format: int32 + type: integer + sources: + description: sources is the list of volume projections + items: + description: Projection that may be projected along with + other supported volume types + properties: + configMap: + description: configMap information about the configMap + data to project + properties: + items: + description: items if unspecified, each key-value + pair in the Data field of the referenced ConfigMap + will be projected into the volume as a file + whose name is the key and content is the value. + If specified, the listed keys will be projected + into the specified paths, and unlisted keys + will not be present. If a key is specified which + is not present in the ConfigMap, the volume + setup will error unless it is marked optional. + Paths must be relative and may not contain the + '..' path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits + used to set permissions on this file. + Must be an octal value between 0000 and + 0777 or a decimal value between 0 and + 511. YAML accepts both octal and decimal + values, JSON requires decimal values for + mode bits. If not specified, the volume + defaultMode will be used. This might be + in conflict with other options that affect + the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path of + the file to map the key to. May not be + an absolute path. May not contain the + path element '..'. May not start with + the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: optional specify whether the ConfigMap + or its keys must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + downwardAPI: + description: downwardAPI information about the downwardAPI + data to project + properties: + items: + description: Items is a list of DownwardAPIVolume + file + items: + description: DownwardAPIVolumeFile represents + information to create the file containing + the pod field + properties: + fieldRef: + description: 'Required: Selects a field + of the pod: only annotations, labels, + name and namespace are supported.' + properties: + apiVersion: + description: Version of the schema the + FieldPath is written in terms of, + defaults to "v1". + type: string + fieldPath: + description: Path of the field to select + in the specified API version. + type: string + required: + - fieldPath + type: object + x-kubernetes-map-type: atomic + mode: + description: 'Optional: mode bits used to + set permissions on this file, must be + an octal value between 0000 and 0777 or + a decimal value between 0 and 511. YAML + accepts both octal and decimal values, + JSON requires decimal values for mode + bits. If not specified, the volume defaultMode + will be used. This might be in conflict + with other options that affect the file + mode, like fsGroup, and the result can + be other mode bits set.' + format: int32 + type: integer + path: + description: 'Required: Path is the relative + path name of the file to be created. Must + not be absolute or contain the ''..'' + path. Must be utf-8 encoded. The first + item of the relative path must not start + with ''..''' + type: string + resourceFieldRef: + description: 'Selects a resource of the + container: only resources limits and requests + (limits.cpu, limits.memory, requests.cpu + and requests.memory) are currently supported.' + properties: + containerName: + description: 'Container name: required + for volumes, optional for env vars' + type: string + divisor: + anyOf: + - type: integer + - type: string + description: Specifies the output format + of the exposed resources, defaults + to "1" + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + description: 'Required: resource to + select' + type: string + required: + - resource + type: object + x-kubernetes-map-type: atomic + required: + - path + type: object + type: array + type: object + secret: + description: secret information about the secret data + to project + properties: + items: + description: items if unspecified, each key-value + pair in the Data field of the referenced Secret + will be projected into the volume as a file + whose name is the key and content is the value. + If specified, the listed keys will be projected + into the specified paths, and unlisted keys + will not be present. If a key is specified which + is not present in the Secret, the volume setup + will error unless it is marked optional. Paths + must be relative and may not contain the '..' + path or start with '..'. + items: + description: Maps a string key to a path within + a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits + used to set permissions on this file. + Must be an octal value between 0000 and + 0777 or a decimal value between 0 and + 511. YAML accepts both octal and decimal + values, JSON requires decimal values for + mode bits. If not specified, the volume + defaultMode will be used. This might be + in conflict with other options that affect + the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path of + the file to map the key to. May not be + an absolute path. May not contain the + path element '..'. May not start with + the string '..'. + type: string + required: + - key + - path + type: object + type: array + name: + description: 'Name of the referent. More info: + https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: optional field specify whether the + Secret or its key must be defined + type: boolean + type: object + x-kubernetes-map-type: atomic + serviceAccountToken: + description: serviceAccountToken is information about + the serviceAccountToken data to project + properties: + audience: + description: audience is the intended audience + of the token. A recipient of a token must identify + itself with an identifier specified in the audience + of the token, and otherwise should reject the + token. The audience defaults to the identifier + of the apiserver. + type: string + expirationSeconds: + description: expirationSeconds is the requested + duration of validity of the service account + token. As the token approaches expiration, the + kubelet volume plugin will proactively rotate + the service account token. The kubelet will + start trying to rotate the token if the token + is older than 80 percent of its time to live + or if the token is older than 24 hours.Defaults + to 1 hour and must be at least 10 minutes. + format: int64 + type: integer + path: + description: path is the path relative to the + mount point of the file to project the token + into. + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + description: quobyte represents a Quobyte mount on the host + that shares a pod's lifetime + properties: + group: + description: group to map volume access to Default is no + group + type: string + readOnly: + description: readOnly here will force the Quobyte volume + to be mounted with read-only permissions. Defaults to + false. + type: boolean + registry: + description: registry represents a single or multiple Quobyte + Registry services specified as a string as host:port pair + (multiple entries are separated with commas) which acts + as the central registry for volumes + type: string + tenant: + description: tenant owning the given Quobyte volume in the + Backend Used with dynamically provisioned Quobyte volumes, + value is set by the plugin + type: string + user: + description: user to map volume access to Defaults to serivceaccount + user + type: string + volume: + description: volume is a string that references an already + created Quobyte volume by name. + type: string + required: + - registry + - volume + type: object + rbd: + description: 'rbd represents a Rados Block Device mount on the + host that shares a pod''s lifetime. More info: https://examples.k8s.io/volumes/rbd/README.md' + properties: + fsType: + description: 'fsType is the filesystem type of the volume + that you want to mount. Tip: Ensure that the filesystem + type is supported by the host operating system. Examples: + "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd + TODO: how do we prevent errors in the filesystem from + compromising the machine' + type: string + image: + description: 'image is the rados image name. More info: + https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + keyring: + description: 'keyring is the path to key ring for RBDUser. + Default is /etc/ceph/keyring. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + monitors: + description: 'monitors is a collection of Ceph monitors. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + items: + type: string + type: array + pool: + description: 'pool is the rados pool name. Default is rbd. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + readOnly: + description: 'readOnly here will force the ReadOnly setting + in VolumeMounts. Defaults to false. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: boolean + secretRef: + description: 'secretRef is name of the authentication secret + for RBDUser. If provided overrides keyring. Default is + nil. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + x-kubernetes-map-type: atomic + user: + description: 'user is the rados user name. Default is admin. + More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' + type: string + required: + - image + - monitors + type: object + scaleIO: + description: scaleIO represents a ScaleIO persistent volume + attached and mounted on Kubernetes nodes. + properties: + fsType: + description: fsType is the filesystem type to mount. Must + be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Default is "xfs". + type: string + gateway: + description: gateway is the host address of the ScaleIO + API Gateway. + type: string + protectionDomain: + description: protectionDomain is the name of the ScaleIO + Protection Domain for the configured storage. + type: string + readOnly: + description: readOnly Defaults to false (read/write). ReadOnly + here will force the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: secretRef references to the secret for ScaleIO + user and other sensitive information. If this is not provided, + Login operation will fail. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + x-kubernetes-map-type: atomic + sslEnabled: + description: sslEnabled Flag enable/disable SSL communication + with Gateway, default false + type: boolean + storageMode: + description: storageMode indicates whether the storage for + a volume should be ThickProvisioned or ThinProvisioned. + Default is ThinProvisioned. + type: string + storagePool: + description: storagePool is the ScaleIO Storage Pool associated + with the protection domain. + type: string + system: + description: system is the name of the storage system as + configured in ScaleIO. + type: string + volumeName: + description: volumeName is the name of a volume already + created in the ScaleIO system that is associated with + this volume source. + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + description: 'secret represents a secret that should populate + this volume. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + properties: + defaultMode: + description: 'defaultMode is Optional: mode bits used to + set permissions on created files by default. Must be an + octal value between 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal and decimal values, + JSON requires decimal values for mode bits. Defaults to + 0644. Directories within the path are not affected by + this setting. This might be in conflict with other options + that affect the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + items: + description: items If unspecified, each key-value pair in + the Data field of the referenced Secret will be projected + into the volume as a file whose name is the key and content + is the value. If specified, the listed keys will be projected + into the specified paths, and unlisted keys will not be + present. If a key is specified which is not present in + the Secret, the volume setup will error unless it is marked + optional. Paths must be relative and may not contain the + '..' path or start with '..'. + items: + description: Maps a string key to a path within a volume. + properties: + key: + description: key is the key to project. + type: string + mode: + description: 'mode is Optional: mode bits used to + set permissions on this file. Must be an octal value + between 0000 and 0777 or a decimal value between + 0 and 511. YAML accepts both octal and decimal values, + JSON requires decimal values for mode bits. If not + specified, the volume defaultMode will be used. + This might be in conflict with other options that + affect the file mode, like fsGroup, and the result + can be other mode bits set.' + format: int32 + type: integer + path: + description: path is the relative path of the file + to map the key to. May not be an absolute path. + May not contain the path element '..'. May not start + with the string '..'. + type: string + required: + - key + - path + type: object + type: array + optional: + description: optional field specify whether the Secret or + its keys must be defined + type: boolean + secretName: + description: 'secretName is the name of the secret in the + pod''s namespace to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' + type: string + type: object + storageos: + description: storageOS represents a StorageOS volume attached + and mounted on Kubernetes nodes. + properties: + fsType: + description: fsType is the filesystem type to mount. Must + be a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. + type: string + readOnly: + description: readOnly defaults to false (read/write). ReadOnly + here will force the ReadOnly setting in VolumeMounts. + type: boolean + secretRef: + description: secretRef specifies the secret to use for obtaining + the StorageOS API credentials. If not specified, default + values will be attempted. + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + type: object + x-kubernetes-map-type: atomic + volumeName: + description: volumeName is the human-readable name of the + StorageOS volume. Volume names are only unique within + a namespace. + type: string + volumeNamespace: + description: volumeNamespace specifies the scope of the + volume within StorageOS. If no namespace is specified + then the Pod's namespace will be used. This allows the + Kubernetes name scoping to be mirrored within StorageOS + for tighter integration. Set VolumeName to any name to + override the default behaviour. Set to "default" if you + are not using namespaces within StorageOS. Namespaces + that do not pre-exist within StorageOS will be created. + type: string + type: object + vsphereVolume: + description: vsphereVolume represents a vSphere volume attached + and mounted on kubelets host machine + properties: + fsType: + description: fsType is filesystem type to mount. Must be + a filesystem type supported by the host operating system. + Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" + if unspecified. + type: string + storagePolicyID: + description: storagePolicyID is the storage Policy Based + Management (SPBM) profile ID associated with the StoragePolicyName. + type: string + storagePolicyName: + description: storagePolicyName is the storage Policy Based + Management (SPBM) profile name. + type: string + volumePath: + description: volumePath is the path that identifies vSphere + volume vmdk + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + required: + - config + - name + - type + type: object + type: object + served: true + storage: true diff --git a/operations/agent-static-operator/crds/monitoring.grafana.com_logsinstances.yaml b/operations/agent-static-operator/crds/monitoring.grafana.com_logsinstances.yaml new file mode 100644 index 000000000000..f36440ab0cd0 --- /dev/null +++ b/operations/agent-static-operator/crds/monitoring.grafana.com_logsinstances.yaml @@ -0,0 +1,500 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.9.2 + creationTimestamp: null + name: logsinstances.monitoring.grafana.com +spec: + group: monitoring.grafana.com + names: + categories: + - agent-operator + kind: LogsInstance + listKind: LogsInstanceList + plural: logsinstances + singular: logsinstance + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: LogsInstance controls an individual logs instance within a Grafana + Agent deployment. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Spec holds the specification of the desired behavior for + the logs instance. + properties: + additionalScrapeConfigs: + description: "AdditionalScrapeConfigs allows specifying a key of a + Secret containing additional Grafana Agent logging scrape configurations. + Scrape configurations specified are appended to the configurations + generated by the Grafana Agent Operator. \n Job configurations specified + must have the form as specified in the official Promtail documentation: + \n https://grafana.com/docs/loki/latest/clients/promtail/configuration/#scrape_configs + \n As scrape configs are appended, the user is responsible to make + sure it is valid. Note that using this feature may expose the possibility + to break upgrades of Grafana Agent. It is advised to review both + Grafana Agent and Promtail release notes to ensure that no incompatible + scrape configs are going to break Grafana Agent after the upgrade." + properties: + key: + description: The key of the secret to select from. Must be a + valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + clients: + description: Clients controls where logs are written to for this instance. + items: + description: LogsClientSpec defines the client integration for logs, + indicating which Loki server to send logs to. + properties: + backoffConfig: + description: Configures how to retry requests to Loki when a + request fails. Defaults to a minPeriod of 500ms, maxPeriod + of 5m, and maxRetries of 10. + properties: + maxPeriod: + description: Maximum backoff time between retries. + type: string + maxRetries: + description: Maximum number of retries to perform before + giving up a request. + type: integer + minPeriod: + description: Initial backoff time between retries. Time + between retries is increased exponentially. + type: string + type: object + basicAuth: + description: BasicAuth for the Loki server. + properties: + password: + description: The secret in the service monitor namespace + that contains the password for authentication. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: The secret in the service monitor namespace + that contains the username for authentication. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + batchSize: + description: Maximum batch size (in bytes) of logs to accumulate + before sending the batch to Loki. + type: integer + batchWait: + description: Maximum amount of time to wait before sending a + batch, even if that batch isn't full. + type: string + bearerToken: + description: BearerToken used for remote_write. + type: string + bearerTokenFile: + description: BearerTokenFile used to read bearer token. + type: string + externalLabels: + additionalProperties: + type: string + description: ExternalLabels are labels to add to any time series + when sending data to Loki. + type: object + oauth2: + description: Oauth2 for URL + properties: + clientId: + description: The secret or configmap containing the OAuth2 + client id + properties: + configMap: + description: ConfigMap containing data to use for the + targets. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: The secret containing the OAuth2 client secret + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: Parameters to append to the token URL + type: object + scopes: + description: OAuth2 scopes used for the token request + items: + type: string + type: array + tokenUrl: + description: The URL to fetch the token from + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyUrl: + description: ProxyURL to proxy requests through. Optional. + type: string + tenantId: + description: Tenant ID used by default to push logs to Loki. + If omitted assumes remote Loki is running in single-tenant + mode or an authentication layer is used to inject an X-Scope-OrgID + header. + type: string + timeout: + description: Maximum time to wait for a server to respond to + a request. + type: string + tlsConfig: + description: TLSConfig to use for the client. Only used when + the protocol of the URL is https. + properties: + ca: + description: Certificate authority used when verifying server + certificates. + properties: + configMap: + description: ConfigMap containing data to use for the + targets. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + caFile: + description: Path to the CA cert in the Prometheus container + to use for the targets. + type: string + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the + targets. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + description: Path to the client cert file in the Prometheus + container for the targets. + type: string + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keyFile: + description: Path to the client key file in the Prometheus + container for the targets. + type: string + keySecret: + description: Secret containing the client key file for the + targets. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + url: + description: 'URL is the URL where Loki is listening. Must be + a full HTTP URL, including protocol. Required. Example: https://logs-prod-us-central1.grafana.net/loki/api/v1/push.' + type: string + required: + - url + type: object + type: array + podLogsNamespaceSelector: + description: Set of labels to determine which namespaces should be + watched for PodLogs. If not provided, checks only namespace of the + instance. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. + The requirements are ANDed. + items: + description: A label selector requirement is a selector that + contains values, a key, and an operator that relates the key + and values. + properties: + key: + description: key is the label key that the selector applies + to. + type: string + operator: + description: operator represents a key's relationship to + a set of values. Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of string values. If the + operator is In or NotIn, the values array must be non-empty. + If the operator is Exists or DoesNotExist, the values + array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single + {key,value} in the matchLabels map is equivalent to an element + of matchExpressions, whose key field is "key", the operator + is "In", and the values array contains only "value". The requirements + are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + podLogsSelector: + description: Determines which PodLogs should be selected for including + in this instance. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. + The requirements are ANDed. + items: + description: A label selector requirement is a selector that + contains values, a key, and an operator that relates the key + and values. + properties: + key: + description: key is the label key that the selector applies + to. + type: string + operator: + description: operator represents a key's relationship to + a set of values. Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of string values. If the + operator is In or NotIn, the values array must be non-empty. + If the operator is Exists or DoesNotExist, the values + array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single + {key,value} in the matchLabels map is equivalent to an element + of matchExpressions, whose key field is "key", the operator + is "In", and the values array contains only "value". The requirements + are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + targetConfig: + description: Configures how tailed targets are watched. + properties: + syncPeriod: + description: Period to resync directories being watched and files + being tailed to discover new ones or stop watching removed ones. + type: string + type: object + type: object + type: object + served: true + storage: true diff --git a/operations/agent-static-operator/crds/monitoring.grafana.com_metricsinstances.yaml b/operations/agent-static-operator/crds/monitoring.grafana.com_metricsinstances.yaml new file mode 100644 index 000000000000..015c0339ce1a --- /dev/null +++ b/operations/agent-static-operator/crds/monitoring.grafana.com_metricsinstances.yaml @@ -0,0 +1,861 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.9.2 + creationTimestamp: null + name: metricsinstances.monitoring.grafana.com +spec: + group: monitoring.grafana.com + names: + categories: + - agent-operator + kind: MetricsInstance + listKind: MetricsInstanceList + plural: metricsinstances + singular: metricsinstance + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: MetricsInstance controls an individual Metrics instance within + a Grafana Agent deployment. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Spec holds the specification of the desired behavior for + the Metrics instance. + properties: + additionalScrapeConfigs: + description: 'AdditionalScrapeConfigs lets you specify a key of a + Secret containing additional Grafana Agent Prometheus scrape configurations. + The specified scrape configurations are appended to the configurations + generated by Grafana Agent Operator. Specified job configurations + must have the form specified in the official Prometheus documentation: + https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config. + As scrape configs are appended, you must make sure the configuration + is still valid. Note that it''s possible that this feature will + break future upgrades of Grafana Agent. Review both Grafana Agent + and Prometheus release notes to ensure that no incompatible scrape + configs will break Grafana Agent after the upgrade.' + properties: + key: + description: The key of the secret to select from. Must be a + valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + maxWALTime: + description: MaxWALTime is the maximum amount of time that series + and samples can exist in the WAL before being forcibly deleted. + type: string + minWALTime: + description: MinWALTime is the minimum amount of time that series + and samples can exist in the WAL before being considered for deletion. + type: string + podMonitorNamespaceSelector: + description: PodMonitorNamespaceSelector are the set of labels to + determine which namespaces to watch for PodMonitor discovery. If + nil, it only checks its own namespace. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. + The requirements are ANDed. + items: + description: A label selector requirement is a selector that + contains values, a key, and an operator that relates the key + and values. + properties: + key: + description: key is the label key that the selector applies + to. + type: string + operator: + description: operator represents a key's relationship to + a set of values. Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of string values. If the + operator is In or NotIn, the values array must be non-empty. + If the operator is Exists or DoesNotExist, the values + array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single + {key,value} in the matchLabels map is equivalent to an element + of matchExpressions, whose key field is "key", the operator + is "In", and the values array contains only "value". The requirements + are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + podMonitorSelector: + description: PodMonitorSelector determines which PodMonitors to selected + for target discovery. Experimental. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. + The requirements are ANDed. + items: + description: A label selector requirement is a selector that + contains values, a key, and an operator that relates the key + and values. + properties: + key: + description: key is the label key that the selector applies + to. + type: string + operator: + description: operator represents a key's relationship to + a set of values. Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of string values. If the + operator is In or NotIn, the values array must be non-empty. + If the operator is Exists or DoesNotExist, the values + array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single + {key,value} in the matchLabels map is equivalent to an element + of matchExpressions, whose key field is "key", the operator + is "In", and the values array contains only "value". The requirements + are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + probeNamespaceSelector: + description: ProbeNamespaceSelector is the set of labels that determines + which namespaces to watch for Probe discovery. If nil, it only checks + own namespace. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. + The requirements are ANDed. + items: + description: A label selector requirement is a selector that + contains values, a key, and an operator that relates the key + and values. + properties: + key: + description: key is the label key that the selector applies + to. + type: string + operator: + description: operator represents a key's relationship to + a set of values. Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of string values. If the + operator is In or NotIn, the values array must be non-empty. + If the operator is Exists or DoesNotExist, the values + array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single + {key,value} in the matchLabels map is equivalent to an element + of matchExpressions, whose key field is "key", the operator + is "In", and the values array contains only "value". The requirements + are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + probeSelector: + description: ProbeSelector determines which Probes to select for target + discovery. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. + The requirements are ANDed. + items: + description: A label selector requirement is a selector that + contains values, a key, and an operator that relates the key + and values. + properties: + key: + description: key is the label key that the selector applies + to. + type: string + operator: + description: operator represents a key's relationship to + a set of values. Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of string values. If the + operator is In or NotIn, the values array must be non-empty. + If the operator is Exists or DoesNotExist, the values + array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single + {key,value} in the matchLabels map is equivalent to an element + of matchExpressions, whose key field is "key", the operator + is "In", and the values array contains only "value". The requirements + are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + remoteFlushDeadline: + description: RemoteFlushDeadline is the deadline for flushing data + when an instance shuts down. + type: string + remoteWrite: + description: RemoteWrite controls remote_write settings for this instance. + items: + description: RemoteWriteSpec defines the remote_write configuration + for Prometheus. + properties: + basicAuth: + description: BasicAuth for the URL. + properties: + password: + description: The secret in the service monitor namespace + that contains the password for authentication. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + username: + description: The secret in the service monitor namespace + that contains the username for authentication. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + bearerToken: + description: BearerToken used for remote_write. + type: string + bearerTokenFile: + description: BearerTokenFile used to read bearer token. + type: string + headers: + additionalProperties: + type: string + description: Headers is a set of custom HTTP headers to be sent + along with each remote_write request. Be aware that any headers + set by Grafana Agent itself can't be overwritten. + type: object + metadataConfig: + description: MetadataConfig configures the sending of series + metadata to remote storage. + properties: + send: + description: Send enables metric metadata to be sent to + remote storage. + type: boolean + sendInterval: + description: SendInterval controls how frequently metric + metadata is sent to remote storage. + type: string + type: object + name: + description: Name of the remote_write queue. Must be unique + if specified. The name is used in metrics and logging in order + to differentiate queues. + type: string + oauth2: + description: Oauth2 for URL + properties: + clientId: + description: The secret or configmap containing the OAuth2 + client id + properties: + configMap: + description: ConfigMap containing data to use for the + targets. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + clientSecret: + description: The secret containing the OAuth2 client secret + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + endpointParams: + additionalProperties: + type: string + description: Parameters to append to the token URL + type: object + scopes: + description: OAuth2 scopes used for the token request + items: + type: string + type: array + tokenUrl: + description: The URL to fetch the token from + minLength: 1 + type: string + required: + - clientId + - clientSecret + - tokenUrl + type: object + proxyUrl: + description: ProxyURL to proxy requests through. Optional. + type: string + queueConfig: + description: QueueConfig allows tuning of the remote_write queue + parameters. + properties: + batchSendDeadline: + description: BatchSendDeadline is the maximum time a sample + will wait in the buffer. + type: string + capacity: + description: Capacity is the number of samples to buffer + per shard before samples start being dropped. + type: integer + maxBackoff: + description: MaxBackoff is the maximum retry delay. + type: string + maxRetries: + description: MaxRetries is the maximum number of times to + retry a batch on recoverable errors. + type: integer + maxSamplesPerSend: + description: MaxSamplesPerSend is the maximum number of + samples per send. + type: integer + maxShards: + description: MaxShards is the maximum number of shards, + i.e., the amount of concurrency. + type: integer + minBackoff: + description: MinBackoff is the initial retry delay. MinBackoff + is doubled for every retry. + type: string + minShards: + description: MinShards is the minimum number of shards, + i.e., the amount of concurrency. + type: integer + retryOnRateLimit: + description: RetryOnRateLimit retries requests when encountering + rate limits. + type: boolean + type: object + remoteTimeout: + description: RemoteTimeout is the timeout for requests to the + remote_write endpoint. + type: string + sigv4: + description: SigV4 configures SigV4-based authentication to + the remote_write endpoint. SigV4-based authentication is used + if SigV4 is defined, even with an empty object. + properties: + accessKey: + description: AccessKey holds the secret of the AWS API access + key to use for signing. If not provided, the environment + variable AWS_ACCESS_KEY_ID is used. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + profile: + description: Profile is the named AWS profile to use for + authentication. + type: string + region: + description: Region of the AWS endpoint. If blank, the region + from the default credentials chain is used. + type: string + roleARN: + description: RoleARN is the AWS Role ARN to use for authentication, + as an alternative for using the AWS API keys. + type: string + secretKey: + description: SecretKey of the AWS API to use for signing. + If blank, the environment variable AWS_SECRET_ACCESS_KEY + is used. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + tlsConfig: + description: TLSConfig to use for remote_write. + properties: + ca: + description: Certificate authority used when verifying server + certificates. + properties: + configMap: + description: ConfigMap containing data to use for the + targets. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + caFile: + description: Path to the CA cert in the Prometheus container + to use for the targets. + type: string + cert: + description: Client certificate to present when doing client-authentication. + properties: + configMap: + description: ConfigMap containing data to use for the + targets. + properties: + key: + description: The key to select. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the ConfigMap or its + key must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + secret: + description: Secret containing data to use for the targets. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, + uid?' + type: string + optional: + description: Specify whether the Secret or its key + must be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + type: object + certFile: + description: Path to the client cert file in the Prometheus + container for the targets. + type: string + insecureSkipVerify: + description: Disable target certificate validation. + type: boolean + keyFile: + description: Path to the client key file in the Prometheus + container for the targets. + type: string + keySecret: + description: Secret containing the client key file for the + targets. + properties: + key: + description: The key of the secret to select from. Must + be a valid secret key. + type: string + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + optional: + description: Specify whether the Secret or its key must + be defined + type: boolean + required: + - key + type: object + x-kubernetes-map-type: atomic + serverName: + description: Used to verify the hostname for the targets. + type: string + type: object + url: + description: URL of the endpoint to send samples to. + type: string + writeRelabelConfigs: + description: WriteRelabelConfigs holds relabel_configs to relabel + samples before they are sent to the remote_write endpoint. + items: + description: 'RelabelConfig allows dynamic rewriting of the + label set, being applied to samples before ingestion. It + defines ``-section of Prometheus + configuration. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs' + properties: + action: + default: replace + description: Action to perform based on regex matching. + Default is 'replace'. uppercase and lowercase actions + require Prometheus >= 2.36. + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + description: Modulus to take of the hash of the source + label values. + format: int64 + type: integer + regex: + description: Regular expression against which the extracted + value is matched. Default is '(.*)' + type: string + replacement: + description: Replacement value against which a regex replace + is performed if the regular expression matches. Regex + capture groups are available. Default is '$1' + type: string + separator: + description: Separator placed between concatenated source + label values. default is ';'. + type: string + sourceLabels: + description: The source labels select values from existing + labels. Their content is concatenated using the configured + separator and matched against the configured regular + expression for the replace, keep, and drop actions. + items: + description: LabelName is a valid Prometheus label name + which may only contain ASCII letters, numbers, as + well as underscores. + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + description: Label to which the resulting value is written + in a replace action. It is mandatory for replace actions. + Regex capture groups are available. + type: string + type: object + type: array + required: + - url + type: object + type: array + serviceMonitorNamespaceSelector: + description: ServiceMonitorNamespaceSelector is the set of labels + that determine which namespaces to watch for ServiceMonitor discovery. + If nil, it only checks its own namespace. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. + The requirements are ANDed. + items: + description: A label selector requirement is a selector that + contains values, a key, and an operator that relates the key + and values. + properties: + key: + description: key is the label key that the selector applies + to. + type: string + operator: + description: operator represents a key's relationship to + a set of values. Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of string values. If the + operator is In or NotIn, the values array must be non-empty. + If the operator is Exists or DoesNotExist, the values + array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single + {key,value} in the matchLabels map is equivalent to an element + of matchExpressions, whose key field is "key", the operator + is "In", and the values array contains only "value". The requirements + are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + serviceMonitorSelector: + description: ServiceMonitorSelector determines which ServiceMonitors + to select for target discovery. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. + The requirements are ANDed. + items: + description: A label selector requirement is a selector that + contains values, a key, and an operator that relates the key + and values. + properties: + key: + description: key is the label key that the selector applies + to. + type: string + operator: + description: operator represents a key's relationship to + a set of values. Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of string values. If the + operator is In or NotIn, the values array must be non-empty. + If the operator is Exists or DoesNotExist, the values + array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single + {key,value} in the matchLabels map is equivalent to an element + of matchExpressions, whose key field is "key", the operator + is "In", and the values array contains only "value". The requirements + are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + walTruncateFrequency: + description: WALTruncateFrequency specifies how frequently to run + the WAL truncation process. Higher values cause the WAL to increase + and for old series to stay in the WAL longer, but reduces the chance + of data loss when remote_write fails for longer than the given frequency. + type: string + writeStaleOnShutdown: + description: WriteStaleOnShutdown writes staleness markers on shutdown + for all series. + type: boolean + type: object + type: object + served: true + storage: true diff --git a/operations/agent-static-operator/crds/monitoring.grafana.com_podlogs.yaml b/operations/agent-static-operator/crds/monitoring.grafana.com_podlogs.yaml new file mode 100644 index 000000000000..ff6531f61e88 --- /dev/null +++ b/operations/agent-static-operator/crds/monitoring.grafana.com_podlogs.yaml @@ -0,0 +1,588 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.9.2 + creationTimestamp: null + name: podlogs.monitoring.grafana.com +spec: + group: monitoring.grafana.com + names: + categories: + - agent-operator + kind: PodLogs + listKind: PodLogsList + plural: podlogs + singular: podlogs + scope: Namespaced + versions: + - name: v1alpha1 + schema: + openAPIV3Schema: + description: PodLogs defines how to collect logs for a pod. + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: Spec holds the specification of the desired behavior for + the PodLogs. + properties: + jobLabel: + description: The label to use to retrieve the job name from. + type: string + namespaceSelector: + description: Selector to select which namespaces the Pod objects are + discovered from. + properties: + any: + description: Boolean describing whether all namespaces are selected + in contrast to a list restricting them. + type: boolean + matchNames: + description: List of namespace names to select from. + items: + type: string + type: array + type: object + pipelineStages: + description: Pipeline stages for this pod. Pipeline stages support + transforming and filtering log lines. + items: + description: "PipelineStageSpec defines an individual pipeline stage. + Each stage type is mutually exclusive and no more than one may + be set per stage. \n More information on pipelines can be found + in the Promtail documentation: https://grafana.com/docs/loki/latest/clients/promtail/pipelines/" + properties: + cri: + description: 'CRI is a parsing stage that reads log lines using + the standard CRI logging format. Supply cri: {} to enable.' + type: object + docker: + description: 'Docker is a parsing stage that reads log lines + using the standard Docker logging format. Supply docker: {} + to enable.' + type: object + drop: + description: Drop is a filtering stage that lets you drop certain + logs. + properties: + dropCounterReason: + description: Every time a log line is dropped, the metric + logentry_dropped_lines_total is incremented. A "reason" + label is added, and can be customized by providing a custom + value here. Defaults to "drop_stage". + type: string + expression: + description: "RE2 regular expression. \n If source is provided, + the regex attempts to match the source. \n If no source + is provided, then the regex attempts to attach the log + line. \n If the provided regex matches the log line or + a provided source, the line is dropped." + type: string + longerThan: + description: LongerThan will drop a log line if it its content + is longer than this value (in bytes). Can be expressed + as an integer (8192) or a number with a suffix (8kb). + type: string + olderThan: + description: OlderThan will be parsed as a Go duration. + If the log line's timestamp is older than the current + time minus the provided duration, it will be dropped. + type: string + source: + description: Name from the extract data to parse. If empty, + uses the log message. + type: string + value: + description: "Value can only be specified when source is + specified. If the value provided is an exact match for + the given source then the line will be dropped. \n Mutually + exclusive with expression." + type: string + type: object + json: + description: "JSON is a parsing stage that reads the log line + as JSON and accepts JMESPath expressions to extract data. + \n Information on JMESPath: http://jmespath.org/" + properties: + expressions: + additionalProperties: + type: string + description: "Set of the key/value pairs of JMESPath expressions. + The key will be the key in the extracted data while the + expression will be the value, evaluated as a JMESPath + from the source data. \n Literal JMESPath expressions + can be used by wrapping a key in double quotes, which + then must be wrapped again in single quotes in YAML so + they get passed to the JMESPath parser." + type: object + source: + description: Name from the extracted data to parse as JSON. + If empty, uses entire log message. + type: string + type: object + labelAllow: + description: LabelAllow is an action stage that only allows + the provided labels to be included in the label set that is + sent to Loki with the log entry. + items: + type: string + type: array + labelDrop: + description: LabelDrop is an action stage that drops labels + from the label set that is sent to Loki with the log entry. + items: + type: string + type: array + labels: + additionalProperties: + type: string + description: "Labels is an action stage that takes data from + the extracted map and modifies the label set that is sent + to Loki with the log entry. \n The key is REQUIRED and represents + the name for the label that will be created. Value is optional + and will be the name from extracted data to use for the value + of the label. If the value is not provided, it defaults to + match the key." + type: object + limit: + description: Limit is a rate-limiting stage that throttles logs + based on several options. + properties: + burst: + description: The cap in the quantity of burst lines that + Promtail will push to Loki. + type: integer + drop: + description: "When drop is true, log lines that exceed the + current rate limit are discarded. When drop is false, + log lines that exceed the current rate limit wait to enter + the back pressure mode. \n Defaults to false." + type: boolean + rate: + description: The rate limit in lines per second that Promtail + will push to Loki. + type: integer + type: object + match: + description: Match is a filtering stage that conditionally applies + a set of stages or drop entries when a log entry matches a + configurable LogQL stream selector and filter expressions. + properties: + action: + description: Determines what action is taken when the selector + matches the log line. Can be keep or drop. Defaults to + keep. When set to drop, entries are dropped and no later + metrics are recorded. Stages must be empty when dropping + metrics. + type: string + dropCounterReason: + description: Every time a log line is dropped, the metric + logentry_dropped_lines_total is incremented. A "reason" + label is added, and can be customized by providing a custom + value here. Defaults to "match_stage." + type: string + pipelineName: + description: Names the pipeline. When defined, creates an + additional label in the pipeline_duration_seconds histogram, + where the value is concatenated with job_name using an + underscore. + type: string + selector: + description: LogQL stream selector and filter expressions. + Required. + type: string + stages: + description: "Nested set of pipeline stages to execute when + action is keep and the log line matches selector. \n An + example value for stages may be: \n stages: | - json: + {} - labelAllow: [foo, bar] \n Note that stages is a string + because SIG API Machinery does not support recursive types, + and so it cannot be validated for correctness. Be careful + not to mistype anything." + type: string + required: + - selector + type: object + metrics: + additionalProperties: + description: MetricsStageSpec is an action stage that allows + for defining and updating metrics based on data from the + extracted map. Created metrics are not pushed to Loki or + Prometheus and are instead exposed via the /metrics endpoint + of the Grafana Agent pod. The Grafana Agent Operator should + be configured with a MetricsInstance that discovers the + logging DaemonSet to collect metrics created by this stage. + properties: + action: + description: "The action to take against the metric. Required. + \n Must be either \"inc\" or \"add\" for type: counter + or type: histogram. When type: gauge, must be one of + \"set\", \"inc\", \"dec\", \"add\", or \"sub\". \n \"add\", + \"set\", or \"sub\" requires the extracted value to + be convertible to a positive float." + type: string + buckets: + description: 'Buckets to create. Bucket values must be + convertible to float64s. Extremely large or small numbers + are subject to some loss of precision. Only valid for + type: histogram.' + items: + type: string + type: array + countEntryBytes: + description: "If true all log line bytes are counted. + Can only be set with matchAll: true and action: add. + \n Only valid for type: counter." + type: boolean + description: + description: Sets the description for the created metric. + type: string + matchAll: + description: "If true, all log lines are counted without + attempting to match the source to the extracted map. + Mutually exclusive with value. \n Only valid for type: + counter." + type: boolean + maxIdleDuration: + description: "Label values on metrics are dynamic which + can cause exported metrics to go stale. To prevent unbounded + cardinality, any metrics not updated within MaxIdleDuration + are removed. \n Must be greater or equal to 1s. Defaults + to 5m." + type: string + prefix: + description: Sets the custom prefix name for the metric. + Defaults to "promtail_custom_". + type: string + source: + description: Key from the extracted data map to use for + the metric. Defaults to the metrics name if not present. + type: string + type: + description: The metric type to create. Must be one of + counter, gauge, histogram. Required. + type: string + value: + description: Filters down source data and only changes + the metric if the targeted value matches the provided + string exactly. If not present, all data matches. + type: string + required: + - action + - type + type: object + description: Metrics is an action stage that supports defining + and updating metrics based on data from the extracted map. + Created metrics are not pushed to Loki or Prometheus and are + instead exposed via the /metrics endpoint of the Grafana Agent + pod. The Grafana Agent Operator should be configured with + a MetricsInstance that discovers the logging DaemonSet to + collect metrics created by this stage. + type: object + multiline: + description: Multiline stage merges multiple lines into a multiline + block before passing it on to the next stage in the pipeline. + properties: + firstLine: + description: RE2 regular expression. Creates a new multiline + block when matched. Required. + type: string + maxLines: + description: Maximum number of lines a block can have. A + new block is started if the number of lines surpasses + this value. Defaults to 128. + type: integer + maxWaitTime: + description: Maximum time to wait before passing on the + multiline block to the next stage if no new lines are + received. Defaults to 3s. + type: string + required: + - firstLine + type: object + output: + description: Output stage is an action stage that takes data + from the extracted map and changes the log line that will + be sent to Loki. + properties: + source: + description: Name from extract data to use for the log entry. + Required. + type: string + required: + - source + type: object + pack: + description: Pack is a transform stage that lets you embed extracted + values and labels into the log line by packing the log line + and labels inside of a JSON object. + properties: + ingestTimestamp: + description: If the resulting log line should use any existing + timestamp or use time.Now() when the line was created. + Set to true when combining several log streams from different + containers to avoid out of order errors. + type: boolean + labels: + description: Name from extracted data or line labels. Required. + Labels provided here are automatically removed from output + labels. + items: + type: string + type: array + required: + - labels + type: object + regex: + description: Regex is a parsing stage that parses a log line + using a regular expression. Named capture groups in the regex + allows for adding data into the extracted map. + properties: + expression: + description: RE2 regular expression. Each capture group + MUST be named. Required. + type: string + source: + description: Name from extracted data to parse. If empty, + defaults to using the log message. + type: string + required: + - expression + type: object + replace: + description: Replace is a parsing stage that parses a log line + using a regular expression and replaces the log line. Named + capture groups in the regex allows for adding data into the + extracted map. + properties: + expression: + description: RE2 regular expression. Each capture group + MUST be named. Required. + type: string + replace: + description: Value to replace the captured group with. + type: string + source: + description: Name from extracted data to parse. If empty, + defaults to using the log message. + type: string + required: + - expression + type: object + template: + description: Template is a transform stage that manipulates + the values in the extracted map using Go's template syntax. + properties: + source: + description: Name from extracted data to parse. Required. + If empty, defaults to using the log message. + type: string + template: + description: Go template string to use. Required. In addition + to normal template functions, ToLower, ToUpper, Replace, + Trim, TrimLeft, TrimRight, TrimPrefix, and TrimSpace are + also available. + type: string + required: + - source + - template + type: object + tenant: + description: Tenant is an action stage that sets the tenant + ID for the log entry picking it from a field in the extracted + data map. If the field is missing, the default LogsClientSpec.tenantId + will be used. + properties: + label: + description: Name from labels whose value should be set + as tenant ID. Mutually exclusive with source and value. + type: string + source: + description: Name from extracted data to use as the tenant + ID. Mutually exclusive with label and value. + type: string + value: + description: Value to use for the template ID. Useful when + this stage is used within a conditional pipeline such + as match. Mutually exclusive with label and source. + type: string + type: object + timestamp: + description: Timestamp is an action stage that can change the + timestamp of a log line before it is sent to Loki. If not + present, the timestamp of a log line defaults to the time + when the log line was read. + properties: + actionOnFailure: + description: Action to take when the timestamp can't be + extracted or parsed. Can be skip or fudge. Defaults to + fudge. + type: string + fallbackFormats: + description: Fallback formats to try if format fails. + items: + type: string + type: array + format: + description: 'Determines format of the time string. Required. + Can be one of: ANSIC, UnixDate, RubyDate, RFC822, RFC822Z, + RFC850, RFC1123, RFC1123Z, RFC3339, RFC3339Nano, Unix, + UnixMs, UnixUs, UnixNs.' + type: string + location: + description: IANA Timezone Database string. + type: string + source: + description: Name from extracted data to use as the timestamp. + Required. + type: string + required: + - format + - source + type: object + type: object + type: array + podTargetLabels: + description: PodTargetLabels transfers labels on the Kubernetes Pod + onto the target. + items: + type: string + type: array + relabelings: + description: "RelabelConfigs to apply to logs before delivering. Grafana + Agent Operator automatically adds relabelings for a few standard + Kubernetes fields and replaces original scrape job name with __tmp_logs_job_name. + \n More info: https://grafana.com/docs/loki/latest/clients/promtail/configuration/#relabel_configs" + items: + description: 'RelabelConfig allows dynamic rewriting of the label + set, being applied to samples before ingestion. It defines ``-section + of Prometheus configuration. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs' + properties: + action: + default: replace + description: Action to perform based on regex matching. Default + is 'replace'. uppercase and lowercase actions require Prometheus + >= 2.36. + enum: + - replace + - Replace + - keep + - Keep + - drop + - Drop + - hashmod + - HashMod + - labelmap + - LabelMap + - labeldrop + - LabelDrop + - labelkeep + - LabelKeep + - lowercase + - Lowercase + - uppercase + - Uppercase + - keepequal + - KeepEqual + - dropequal + - DropEqual + type: string + modulus: + description: Modulus to take of the hash of the source label + values. + format: int64 + type: integer + regex: + description: Regular expression against which the extracted + value is matched. Default is '(.*)' + type: string + replacement: + description: Replacement value against which a regex replace + is performed if the regular expression matches. Regex capture + groups are available. Default is '$1' + type: string + separator: + description: Separator placed between concatenated source label + values. default is ';'. + type: string + sourceLabels: + description: The source labels select values from existing labels. + Their content is concatenated using the configured separator + and matched against the configured regular expression for + the replace, keep, and drop actions. + items: + description: LabelName is a valid Prometheus label name which + may only contain ASCII letters, numbers, as well as underscores. + pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ + type: string + type: array + targetLabel: + description: Label to which the resulting value is written in + a replace action. It is mandatory for replace actions. Regex + capture groups are available. + type: string + type: object + type: array + selector: + description: Selector to select Pod objects. Required. + properties: + matchExpressions: + description: matchExpressions is a list of label selector requirements. + The requirements are ANDed. + items: + description: A label selector requirement is a selector that + contains values, a key, and an operator that relates the key + and values. + properties: + key: + description: key is the label key that the selector applies + to. + type: string + operator: + description: operator represents a key's relationship to + a set of values. Valid operators are In, NotIn, Exists + and DoesNotExist. + type: string + values: + description: values is an array of string values. If the + operator is In or NotIn, the values array must be non-empty. + If the operator is Exists or DoesNotExist, the values + array must be empty. This array is replaced during a strategic + merge patch. + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + description: matchLabels is a map of {key,value} pairs. A single + {key,value} in the matchLabels map is equivalent to an element + of matchExpressions, whose key field is "key", the operator + is "In", and the values array contains only "value". The requirements + are ANDed. + type: object + type: object + x-kubernetes-map-type: atomic + required: + - selector + type: object + type: object + served: true + storage: true diff --git a/operations/agent-static-operator/templates/agent-operator.yaml b/operations/agent-static-operator/templates/agent-operator.yaml new file mode 100644 index 000000000000..ba8c08e75e6f --- /dev/null +++ b/operations/agent-static-operator/templates/agent-operator.yaml @@ -0,0 +1,645 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: grafana-agent + namespace: ${NAMESPACE} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: grafana-agent-operator + namespace: ${NAMESPACE} +--- +apiVersion: v1 +automountServiceAccountToken: false +kind: ServiceAccount +metadata: + labels: + app.kubernetes.io/component: exporter + app.kubernetes.io/name: kube-state-metrics + app.kubernetes.io/version: 2.5.0 + name: kube-state-metrics + namespace: ${NAMESPACE} +--- +apiVersion: v1 +data: {} +kind: Secret +metadata: + name: logs-secret + namespace: ${NAMESPACE} +stringData: + password: ${LOGS_KEY} + username: ${LOGS_USER} +type: Opaque +--- +apiVersion: v1 +data: {} +kind: Secret +metadata: + name: metrics-secret + namespace: ${NAMESPACE} +stringData: + password: ${METRICS_KEY} + username: ${METRICS_USER} +type: Opaque +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: agent-eventhandler + namespace: ${NAMESPACE} +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: grafana-agent +rules: +- apiGroups: + - "" + resources: + - nodes + - nodes/proxy + - nodes/metrics + - services + - endpoints + - pods + - events + verbs: + - get + - list + - watch +- apiGroups: + - networking.k8s.io + resources: + - ingresses + verbs: + - get + - list + - watch +- nonResourceURLs: + - /metrics + - /metrics/cadvisor + verbs: + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: grafana-agent-operator +rules: +- apiGroups: + - monitoring.grafana.com + resources: + - grafanaagents + - metricsinstances + - logsinstances + - podlogs + - integrations + verbs: + - get + - list + - watch +- apiGroups: + - monitoring.grafana.com + resources: + - grafanaagents/finalizers + - metricsinstances/finalizers + - logsinstances/finalizers + - podlogs/finalizers + - integrations/finalizers + verbs: + - get + - list + - watch + - update +- apiGroups: + - monitoring.coreos.com + resources: + - podmonitors + - probes + - servicemonitors + verbs: + - get + - list + - watch +- apiGroups: + - monitoring.coreos.com + resources: + - podmonitors/finalizers + - probes/finalizers + - servicemonitors/finalizers + verbs: + - get + - list + - watch + - update +- apiGroups: + - "" + resources: + - namespaces + - nodes + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - secrets + - services + - configmaps + - endpoints + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +- apiGroups: + - apps + resources: + - statefulsets + - daemonsets + - deployments + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app.kubernetes.io/component: exporter + app.kubernetes.io/name: kube-state-metrics + app.kubernetes.io/version: 2.5.0 + name: kube-state-metrics +rules: +- apiGroups: + - "" + resources: + - configmaps + - secrets + - nodes + - pods + - services + - resourcequotas + - replicationcontrollers + - limitranges + - persistentvolumeclaims + - persistentvolumes + - namespaces + - endpoints + verbs: + - list + - watch +- apiGroups: + - apps + resources: + - statefulsets + - daemonsets + - deployments + - replicasets + verbs: + - list + - watch +- apiGroups: + - batch + resources: + - cronjobs + - jobs + verbs: + - list + - watch +- apiGroups: + - autoscaling + resources: + - horizontalpodautoscalers + verbs: + - list + - watch +- apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create +- apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create +- apiGroups: + - policy + resources: + - poddisruptionbudgets + verbs: + - list + - watch +- apiGroups: + - certificates.k8s.io + resources: + - certificatesigningrequests + verbs: + - list + - watch +- apiGroups: + - storage.k8s.io + resources: + - storageclasses + - volumeattachments + verbs: + - list + - watch +- apiGroups: + - admissionregistration.k8s.io + resources: + - mutatingwebhookconfigurations + - validatingwebhookconfigurations + verbs: + - list + - watch +- apiGroups: + - networking.k8s.io + resources: + - networkpolicies + - ingresses + verbs: + - list + - watch +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - list + - watch +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: grafana-agent +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: grafana-agent +subjects: +- kind: ServiceAccount + name: grafana-agent + namespace: ${NAMESPACE} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: grafana-agent-operator +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: grafana-agent-operator +subjects: +- kind: ServiceAccount + name: grafana-agent-operator + namespace: ${NAMESPACE} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app.kubernetes.io/component: exporter + app.kubernetes.io/name: kube-state-metrics + app.kubernetes.io/version: 2.5.0 + name: kube-state-metrics +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: kube-state-metrics +subjects: +- kind: ServiceAccount + name: kube-state-metrics + namespace: ${NAMESPACE} +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app.kubernetes.io/component: exporter + app.kubernetes.io/name: kube-state-metrics + app.kubernetes.io/version: 2.5.0 + name: kube-state-metrics + namespace: ${NAMESPACE} +spec: + clusterIP: None + ports: + - name: http-metrics + port: 8080 + targetPort: http-metrics + - name: telemetry + port: 8081 + targetPort: telemetry + selector: + app.kubernetes.io/name: kube-state-metrics +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: grafana-agent-operator + namespace: ${NAMESPACE} +spec: + minReadySeconds: 10 + replicas: 1 + revisionHistoryLimit: 10 + selector: + matchLabels: + name: grafana-agent-operator + template: + metadata: + labels: + name: grafana-agent-operator + spec: + containers: + - args: + - --kubelet-service=default/kubelet + image: grafana/agent-operator:v0.37.4 + imagePullPolicy: IfNotPresent + name: grafana-agent-operator + serviceAccount: grafana-agent-operator +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app.kubernetes.io/component: exporter + app.kubernetes.io/name: kube-state-metrics + app.kubernetes.io/version: 2.5.0 + name: kube-state-metrics + namespace: ${NAMESPACE} +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: kube-state-metrics + template: + metadata: + labels: + app.kubernetes.io/component: exporter + app.kubernetes.io/name: kube-state-metrics + app.kubernetes.io/version: 2.5.0 + spec: + automountServiceAccountToken: true + containers: + - image: registry.k8s.io/kube-state-metrics/kube-state-metrics:v2.5.0 + livenessProbe: + httpGet: + path: /healthz + port: 8080 + initialDelaySeconds: 5 + timeoutSeconds: 5 + name: kube-state-metrics + ports: + - containerPort: 8080 + name: http-metrics + - containerPort: 8081 + name: telemetry + readinessProbe: + httpGet: + path: / + port: 8081 + initialDelaySeconds: 5 + timeoutSeconds: 5 + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsUser: 65534 + nodeSelector: + kubernetes.io/os: linux + serviceAccountName: kube-state-metrics +--- +apiVersion: monitoring.grafana.com/v1alpha1 +kind: GrafanaAgent +metadata: + name: grafana-agent + namespace: ${NAMESPACE} +spec: + image: grafana/agent:v0.37.4 + integrations: + selector: + matchLabels: + agent: grafana-agent + logs: + instanceSelector: + matchLabels: + agent: grafana-agent + metrics: + externalLabels: + cluster: ${CLUSTER} + instanceSelector: + matchLabels: + agent: grafana-agent + serviceAccountName: grafana-agent +--- +apiVersion: monitoring.grafana.com/v1alpha1 +kind: Integration +metadata: + labels: + agent: grafana-agent + name: agent-eventhandler + namespace: ${NAMESPACE} +spec: + config: + cache_path: /etc/eventhandler/eventhandler.cache + logs_instance: ${NAMESPACE}/grafana-agent-logs + name: eventhandler + type: + unique: true + volumeMounts: + - mountPath: /etc/eventhandler + name: agent-eventhandler + volumes: + - name: agent-eventhandler + persistentVolumeClaim: + claimName: agent-eventhandler +--- +apiVersion: monitoring.grafana.com/v1alpha1 +kind: LogsInstance +metadata: + labels: + agent: grafana-agent + name: grafana-agent-logs + namespace: ${NAMESPACE} +spec: + clients: + - basicAuth: + password: + key: password + name: logs-secret + username: + key: username + name: logs-secret + externalLabels: + cluster: ${CLUSTER} + url: ${LOGS_URL} + podLogsNamespaceSelector: {} + podLogsSelector: + matchLabels: + instance: primary +--- +apiVersion: monitoring.grafana.com/v1alpha1 +kind: MetricsInstance +metadata: + labels: + agent: grafana-agent + name: grafana-agent-metrics + namespace: ${NAMESPACE} +spec: + remoteWrite: + - basicAuth: + password: + key: password + name: metrics-secret + username: + key: username + name: metrics-secret + url: ${METRICS_URL} + serviceMonitorNamespaceSelector: {} + serviceMonitorSelector: + matchLabels: + instance: primary +--- +apiVersion: monitoring.grafana.com/v1alpha1 +kind: PodLogs +metadata: + labels: + instance: primary + name: kubernetes-logs + namespace: ${NAMESPACE} +spec: + namespaceSelector: + any: true + pipelineStages: + - cri: {} + relabelings: + - sourceLabels: + - __meta_kubernetes_pod_node_name + targetLabel: __host__ + - action: replace + sourceLabels: + - __meta_kubernetes_namespace + targetLabel: namespace + - action: replace + sourceLabels: + - __meta_kubernetes_pod_name + targetLabel: pod + - action: replace + sourceLabels: + - __meta_kubernetes_pod_container_name + targetLabel: container + - replacement: /var/log/pods/*$1/*.log + separator: / + sourceLabels: + - __meta_kubernetes_pod_uid + - __meta_kubernetes_pod_container_name + targetLabel: __path__ + selector: + matchLabels: {} +--- +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + labels: + instance: primary + name: cadvisor-monitor + namespace: ${NAMESPACE} +spec: + endpoints: + - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + honorLabels: true + interval: 60s + path: /metrics/cadvisor + port: https-metrics + relabelings: + - sourceLabels: + - __metrics_path__ + targetLabel: metrics_path + - action: replace + replacement: cadvisor + targetLabel: job + scheme: https + tlsConfig: + insecureSkipVerify: true + namespaceSelector: + matchNames: + - default + selector: + matchLabels: + app.kubernetes.io/name: kubelet +--- +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + labels: + instance: primary + name: ksm-monitor + namespace: ${NAMESPACE} +spec: + endpoints: + - honorLabels: true + interval: 60s + path: /metrics + port: http-metrics + relabelings: + - action: replace + replacement: kube-state-metrics + targetLabel: job + namespaceSelector: + matchNames: + - ${NAMESPACE} + selector: + matchLabels: + app.kubernetes.io/name: kube-state-metrics +--- +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + labels: + instance: primary + name: kubelet-monitor + namespace: ${NAMESPACE} +spec: + endpoints: + - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token + honorLabels: true + interval: 60s + path: /metrics + port: https-metrics + relabelings: + - sourceLabels: + - __metrics_path__ + targetLabel: metrics_path + - action: replace + replacement: kubelet + targetLabel: job + scheme: https + tlsConfig: + insecureSkipVerify: true + namespaceSelector: + matchNames: + - default + selector: + matchLabels: + app.kubernetes.io/name: kubelet diff --git a/production/README.md b/production/README.md new file mode 100644 index 000000000000..93a7f2594349 --- /dev/null +++ b/production/README.md @@ -0,0 +1 @@ +**NOTE**: This folder has been deprecated in favor of [operations/](../operations/) and will be removed. From 858c71a85c2a9e5f6f355f2995fbe8375eb8d9f5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 9 Jan 2024 10:45:29 -0500 Subject: [PATCH 33/68] build(deps): bump follow-redirects from 1.15.2 to 1.15.4 in /web/ui (#6072) Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.15.2 to 1.15.4. - [Release notes](https://github.com/follow-redirects/follow-redirects/releases) - [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.15.2...v1.15.4) --- updated-dependencies: - dependency-name: follow-redirects dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- web/ui/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/web/ui/yarn.lock b/web/ui/yarn.lock index 85e807484347..e490feb4ec05 100644 --- a/web/ui/yarn.lock +++ b/web/ui/yarn.lock @@ -5011,9 +5011,9 @@ flatted@^3.1.0: integrity sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ== follow-redirects@^1.0.0: - version "1.15.2" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.2.tgz#b460864144ba63f2681096f274c4e57026da2c13" - integrity sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA== + version "1.15.4" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.4.tgz#cdc7d308bf6493126b17ea2191ea0ccf3e535adf" + integrity sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw== for-each@^0.3.3: version "0.3.3" From f93e31f4db661ac0716d5cf33537bfd263eeb361 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Tudur=C3=AD?= Date: Tue, 9 Jan 2024 16:51:11 +0100 Subject: [PATCH 34/68] Change refs v0.39 (#6081) * V0.39 update refs (#6054) * Update version to v0.39.0-rc.0 (#6053) (cherry picked from commit c246cf896ce497d2821b4e18116e5b1493d3b199) * Remove main from changelog * Cherry picks release v0.39 (#6078) * add call to set perf query (#6065) * add changelog (#6058) * Fix changelog --------- Co-authored-by: mattdurham * Update refs to v0.39 --------- Co-authored-by: mattdurham --- CHANGELOG.md | 12 ++++-------- docs/sources/_index.md | 2 +- pkg/operator/defaults.go | 2 +- production/kubernetes/agent-bare.yaml | 2 +- production/kubernetes/agent-loki.yaml | 2 +- production/kubernetes/agent-traces.yaml | 2 +- production/kubernetes/build/lib/version.libsonnet | 2 +- .../kubernetes/build/templates/operator/main.jsonnet | 4 ++-- production/kubernetes/install-bare.sh | 2 +- production/operator/templates/agent-operator.yaml | 4 ++-- production/tanka/grafana-agent/v1/main.libsonnet | 4 ++-- .../tanka/grafana-agent/v2/internal/base.libsonnet | 4 ++-- .../tanka/grafana-agent/v2/internal/syncer.libsonnet | 2 +- tools/gen-versioned-files/agent-version.txt | 2 +- 14 files changed, 21 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b9d7e66231e1..05a4fd7e6862 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,12 +16,9 @@ Main (unreleased) - [GO-2023-2412](https://github.com/advisories/GHSA-7ww5-4wqc-m92c) - [CVE-2023-49568](https://github.com/advisories/GHSA-mw99-9chc-xw7r) -### Bugfixes - -- Fix performance issue where perf lib where clause was not being set, leading to timeouts in collecting metrics for windows_exporter. (@mattdurham) -v0.39.0-rc.0 (2024-01-05) -------------------------- +v0.39.0 (2024-01-09) +-------------------- ### Breaking changes @@ -42,9 +39,6 @@ v0.39.0-rc.0 (2024-01-05) ### Features - A new `discovery.ovhcloud` component for discovering scrape targets on OVHcloud. (@ptodev) - -### Features - - Allow specifying additional containers to run. (@juangom) ### Enhancements @@ -121,6 +115,8 @@ v0.39.0-rc.0 (2024-01-05) - Fix issue where `prometheus.exporter.kafka` would crash when configuring `sasl_password`. (@rfratto) +- Fix performance issue where perf lib where clause was not being set, leading to timeouts in collecting metrics for windows_exporter. (@mattdurham) + - Fix nil panic when using the process collector with the windows exporter. (@mattdurham) ### Other changes diff --git a/docs/sources/_index.md b/docs/sources/_index.md index 4b19726241b6..890ac82d71a7 100644 --- a/docs/sources/_index.md +++ b/docs/sources/_index.md @@ -9,7 +9,7 @@ title: Grafana Agent description: Grafana Agent is a flexible, performant, vendor-neutral, telemetry collector weight: 350 cascade: - AGENT_RELEASE: v0.39.0-rc.0 + AGENT_RELEASE: v0.39.0 OTEL_VERSION: v0.87.0 --- diff --git a/pkg/operator/defaults.go b/pkg/operator/defaults.go index a518d884b0b1..bc9cff6ab04e 100644 --- a/pkg/operator/defaults.go +++ b/pkg/operator/defaults.go @@ -2,7 +2,7 @@ package operator // Supported versions of the Grafana Agent. var ( - DefaultAgentVersion = "v0.39.0-rc.0" + DefaultAgentVersion = "v0.39.0" DefaultAgentBaseImage = "grafana/agent" DefaultAgentImage = DefaultAgentBaseImage + ":" + DefaultAgentVersion ) diff --git a/production/kubernetes/agent-bare.yaml b/production/kubernetes/agent-bare.yaml index 0ca2da3bc58f..ccf5d13439ce 100644 --- a/production/kubernetes/agent-bare.yaml +++ b/production/kubernetes/agent-bare.yaml @@ -83,7 +83,7 @@ spec: valueFrom: fieldRef: fieldPath: spec.nodeName - image: grafana/agent:v0.37.4 + image: grafana/agent:v0.39.0 imagePullPolicy: IfNotPresent name: grafana-agent ports: diff --git a/production/kubernetes/agent-loki.yaml b/production/kubernetes/agent-loki.yaml index 4eeb798a00d8..497462d3efcb 100644 --- a/production/kubernetes/agent-loki.yaml +++ b/production/kubernetes/agent-loki.yaml @@ -65,7 +65,7 @@ spec: valueFrom: fieldRef: fieldPath: spec.nodeName - image: grafana/agent:v0.37.4 + image: grafana/agent:v0.39.0 imagePullPolicy: IfNotPresent name: grafana-agent-logs ports: diff --git a/production/kubernetes/agent-traces.yaml b/production/kubernetes/agent-traces.yaml index 7c2835846b0a..c42cec6125e3 100644 --- a/production/kubernetes/agent-traces.yaml +++ b/production/kubernetes/agent-traces.yaml @@ -114,7 +114,7 @@ spec: valueFrom: fieldRef: fieldPath: spec.nodeName - image: grafana/agent:v0.37.4 + image: grafana/agent:v0.39.0 imagePullPolicy: IfNotPresent name: grafana-agent-traces ports: diff --git a/production/kubernetes/build/lib/version.libsonnet b/production/kubernetes/build/lib/version.libsonnet index be3865408074..70fb0ff0cffe 100644 --- a/production/kubernetes/build/lib/version.libsonnet +++ b/production/kubernetes/build/lib/version.libsonnet @@ -1 +1 @@ -'grafana/agent:v0.37.4' +'grafana/agent:v0.39.0' diff --git a/production/kubernetes/build/templates/operator/main.jsonnet b/production/kubernetes/build/templates/operator/main.jsonnet index fe49426c4fa4..efc5b6e9df9f 100644 --- a/production/kubernetes/build/templates/operator/main.jsonnet +++ b/production/kubernetes/build/templates/operator/main.jsonnet @@ -23,8 +23,8 @@ local ksm = import 'kube-state-metrics/kube-state-metrics.libsonnet'; local this = self, _images:: { - agent: 'grafana/agent:v0.37.4', - agent_operator: 'grafana/agent-operator:v0.37.4', + agent: 'grafana/agent:v0.39.0', + agent_operator: 'grafana/agent-operator:v0.39.0', ksm: 'registry.k8s.io/kube-state-metrics/kube-state-metrics:v2.5.0', }, diff --git a/production/kubernetes/install-bare.sh b/production/kubernetes/install-bare.sh index 93cc7120af23..32127903a224 100644 --- a/production/kubernetes/install-bare.sh +++ b/production/kubernetes/install-bare.sh @@ -25,7 +25,7 @@ check_installed() { check_installed curl check_installed envsubst -MANIFEST_BRANCH=v0.37.4 +MANIFEST_BRANCH=v0.39.0 MANIFEST_URL=${MANIFEST_URL:-https://raw.githubusercontent.com/grafana/agent/${MANIFEST_BRANCH}/production/kubernetes/agent-bare.yaml} NAMESPACE=${NAMESPACE:-default} diff --git a/production/operator/templates/agent-operator.yaml b/production/operator/templates/agent-operator.yaml index ba8c08e75e6f..442bab4fa353 100644 --- a/production/operator/templates/agent-operator.yaml +++ b/production/operator/templates/agent-operator.yaml @@ -372,7 +372,7 @@ spec: containers: - args: - --kubelet-service=default/kubelet - image: grafana/agent-operator:v0.37.4 + image: grafana/agent-operator:v0.39.0 imagePullPolicy: IfNotPresent name: grafana-agent-operator serviceAccount: grafana-agent-operator @@ -436,7 +436,7 @@ metadata: name: grafana-agent namespace: ${NAMESPACE} spec: - image: grafana/agent:v0.37.4 + image: grafana/agent:v0.39.0 integrations: selector: matchLabels: diff --git a/production/tanka/grafana-agent/v1/main.libsonnet b/production/tanka/grafana-agent/v1/main.libsonnet index 8ff06ab1bf5b..d4096bc015e9 100644 --- a/production/tanka/grafana-agent/v1/main.libsonnet +++ b/production/tanka/grafana-agent/v1/main.libsonnet @@ -15,8 +15,8 @@ local service = k.core.v1.service; (import './lib/traces.libsonnet') + { _images:: { - agent: 'grafana/agent:v0.37.4', - agentctl: 'grafana/agentctl:v0.37.4', + agent: 'grafana/agent:v0.39.0', + agentctl: 'grafana/agentctl:v0.39.0', }, // new creates a new DaemonSet deployment of the grafana-agent. By default, diff --git a/production/tanka/grafana-agent/v2/internal/base.libsonnet b/production/tanka/grafana-agent/v2/internal/base.libsonnet index 53921bf64aaf..6d697c93a3aa 100644 --- a/production/tanka/grafana-agent/v2/internal/base.libsonnet +++ b/production/tanka/grafana-agent/v2/internal/base.libsonnet @@ -11,8 +11,8 @@ function(name='grafana-agent', namespace='') { local this = self, _images:: { - agent: 'grafana/agent:v0.37.4', - agentctl: 'grafana/agentctl:v0.37.4', + agent: 'grafana/agent:v0.39.0', + agentctl: 'grafana/agentctl:v0.39.0', }, _config:: { name: name, diff --git a/production/tanka/grafana-agent/v2/internal/syncer.libsonnet b/production/tanka/grafana-agent/v2/internal/syncer.libsonnet index 689b14fd87b3..79409f65f310 100644 --- a/production/tanka/grafana-agent/v2/internal/syncer.libsonnet +++ b/production/tanka/grafana-agent/v2/internal/syncer.libsonnet @@ -14,7 +14,7 @@ function( ) { local _config = { api: error 'api must be set', - image: 'grafana/agentctl:v0.37.4', + image: 'grafana/agentctl:v0.39.0', schedule: '*/5 * * * *', configs: [], } + config, diff --git a/tools/gen-versioned-files/agent-version.txt b/tools/gen-versioned-files/agent-version.txt index f02ec0731bfa..999889149ec2 100644 --- a/tools/gen-versioned-files/agent-version.txt +++ b/tools/gen-versioned-files/agent-version.txt @@ -1 +1 @@ -v0.39.0-rc.0 +v0.39.0 \ No newline at end of file From e54d60a9081b600775644aec0236aea82faeac1c Mon Sep 17 00:00:00 2001 From: Piotr <17101802+thampiotr@users.noreply.github.com> Date: Tue, 9 Jan 2024 15:56:16 +0000 Subject: [PATCH 35/68] Move 'Set up / Configure' to 'Tasks / Configure' (#6083) --- docs/sources/flow/setup/configure/_index.md | 24 ------------- docs/sources/flow/setup/install/binary.md | 4 +-- docs/sources/flow/setup/install/kubernetes.md | 4 +-- docs/sources/flow/setup/install/linux.md | 4 +-- docs/sources/flow/setup/install/macos.md | 4 +-- docs/sources/flow/setup/install/windows.md | 4 +-- docs/sources/flow/setup/start-agent.md | 4 +-- docs/sources/flow/tasks/configure/_index.md | 36 +++++++++++++++++++ .../configure/configure-kubernetes.md | 8 ++++- .../configure/configure-linux.md | 8 ++++- .../configure/configure-macos.md | 8 ++++- .../configure/configure-windows.md | 8 ++++- .../distribute-prometheus-scrape-load.md | 4 +-- 13 files changed, 78 insertions(+), 42 deletions(-) delete mode 100644 docs/sources/flow/setup/configure/_index.md create mode 100644 docs/sources/flow/tasks/configure/_index.md rename docs/sources/flow/{setup => tasks}/configure/configure-kubernetes.md (80%) rename docs/sources/flow/{setup => tasks}/configure/configure-linux.md (86%) rename docs/sources/flow/{setup => tasks}/configure/configure-macos.md (85%) rename docs/sources/flow/{setup => tasks}/configure/configure-windows.md (85%) diff --git a/docs/sources/flow/setup/configure/_index.md b/docs/sources/flow/setup/configure/_index.md deleted file mode 100644 index b185bdac69a0..000000000000 --- a/docs/sources/flow/setup/configure/_index.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -aliases: -- /docs/grafana-cloud/agent/flow/setup/configure/ -- /docs/grafana-cloud/monitor-infrastructure/agent/flow/setup/configure/ -- /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/setup/configure/ -- /docs/grafana-cloud/send-data/agent/flow/setup/configure/ -canonical: https://grafana.com/docs/agent/latest/flow/setup/configure/ -description: Configure Grafana Agent Flow after it is installed -menuTitle: Configure Grafana Agent Flow -title: Configure Grafana Agent Flow -weight: 150 ---- - -# Configure {{% param "PRODUCT_NAME" %}} - -You can configure {{< param "PRODUCT_NAME" >}} after it is installed. The default River configuration file for {{< param "PRODUCT_NAME" >}} is located at: - -* Linux: `/etc/grafana-agent-flow.river` -* macOS: `$(brew --prefix)/etc/grafana-agent-flow/config.river` -* Windows: `C:\Program Files\Grafana Agent Flow\config.river` - -This section includes information that helps you configure {{< param "PRODUCT_NAME" >}}. - -{{< section >}} diff --git a/docs/sources/flow/setup/install/binary.md b/docs/sources/flow/setup/install/binary.md index d491ad86cfe5..88560dbf63e0 100644 --- a/docs/sources/flow/setup/install/binary.md +++ b/docs/sources/flow/setup/install/binary.md @@ -51,6 +51,6 @@ To download {{< param "PRODUCT_NAME" >}} as a standalone binary, perform the fol {{% docs/reference %}} [Start]: "/docs/agent/ -> /docs/agent//flow/setup/start-agent.md#standalone-binary" [Start]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/setup/start-agent.md#standalone-binary" -[Configure]: "/docs/agent/ -> /docs/agent//flow/setup/configure" -[Configure]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/setup/configure/" +[Configure]: "/docs/agent/ -> /docs/agent//flow/tasks/configure" +[Configure]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/tasks/configure/" {{% /docs/reference %}} diff --git a/docs/sources/flow/setup/install/kubernetes.md b/docs/sources/flow/setup/install/kubernetes.md index 51ab96260ca3..3bd0a3240fbc 100644 --- a/docs/sources/flow/setup/install/kubernetes.md +++ b/docs/sources/flow/setup/install/kubernetes.md @@ -64,6 +64,6 @@ For more information on the {{< param "PRODUCT_ROOT_NAME" >}} Helm chart, refer [Helm]: https://helm.sh {{% docs/reference %}} -[Configure]: "/docs/agent/ -> /docs/agent//flow/setup/configure/configure-kubernetes.md" -[Configure]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/setup/configure/configure-kubernetes.md" +[Configure]: "/docs/agent/ -> /docs/agent//flow/tasks/configure/configure-kubernetes.md" +[Configure]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/tasks/configure/configure-kubernetes.md" {{% /docs/reference %}} diff --git a/docs/sources/flow/setup/install/linux.md b/docs/sources/flow/setup/install/linux.md index 56aae580299a..12e4f3323e7e 100644 --- a/docs/sources/flow/setup/install/linux.md +++ b/docs/sources/flow/setup/install/linux.md @@ -125,6 +125,6 @@ To uninstall {{< param "PRODUCT_NAME" >}} on Linux, run the following commands i {{% docs/reference %}} [Start]: "/docs/agent/ -> /docs/agent//flow/setup/start-agent.md#linux" [Start]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/setup/start-agent.md#linux" -[Configure]: "/docs/agent/ -> /docs/agent//flow/setup/configure/configure-linux.md" -[Configure]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/setup/configure/configure-linux.md" +[Configure]: "/docs/agent/ -> /docs/agent//flow/tasks/configure/configure-linux.md" +[Configure]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/tasks/configure/configure-linux.md" {{% /docs/reference %}} diff --git a/docs/sources/flow/setup/install/macos.md b/docs/sources/flow/setup/install/macos.md index ad5174577aa3..9aa7e86ee265 100644 --- a/docs/sources/flow/setup/install/macos.md +++ b/docs/sources/flow/setup/install/macos.md @@ -74,6 +74,6 @@ brew uninstall grafana-agent-flow {{% docs/reference %}} [Start]: "/docs/agent/ -> /docs/agent//flow/setup/start-agent.md#macos" [Start]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/setup/start-agent.md#macos" -[Configure]: "/docs/agent/ -> /docs/agent//flow/setup/configure/configure-macos.md" -[Configure]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/setup/configure/configure-macos.md" +[Configure]: "/docs/agent/ -> /docs/agent//flow/tasks/configure/configure-macos.md" +[Configure]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/tasks/configure/configure-macos.md" {{% /docs/reference %}} diff --git a/docs/sources/flow/setup/install/windows.md b/docs/sources/flow/setup/install/windows.md index 765e9fdd3ac4..031b0caeab06 100644 --- a/docs/sources/flow/setup/install/windows.md +++ b/docs/sources/flow/setup/install/windows.md @@ -86,8 +86,8 @@ This includes any configuration files in the installation directory. {{% docs/reference %}} [Start]: "/docs/agent/ -> /docs/agent//flow/setup/start-agent.md#windows" [Start]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/setup/start-agent.md#windows" -[Configure]: "/docs/agent/ -> /docs/agent//flow/setup/configure/configure-windows.md" -[Configure]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/setup/configure/configure-windows.md" +[Configure]: "/docs/agent/ -> /docs/agent//flow/tasks/configure/configure-windows.md" +[Configure]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/tasks/configure/configure-windows.md" [data collection]: "/docs/agent/ -> /docs/agent//data-collection.md" [data collection]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/data-collection.md" {{% /docs/reference %}} diff --git a/docs/sources/flow/setup/start-agent.md b/docs/sources/flow/setup/start-agent.md index b63386cf1436..b8bd97a75e05 100644 --- a/docs/sources/flow/setup/start-agent.md +++ b/docs/sources/flow/setup/start-agent.md @@ -252,6 +252,6 @@ These steps assume you have a default systemd and {{< param "PRODUCT_NAME" >}} c [release]: https://github.com/grafana/agent/releases/latest {{% docs/reference %}} -[Configure]: "/docs/agent/ -> /docs/agent//flow/setup/configure/configure-macos.md#configure-the-grafana-agent-service" -[Configure]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/setup/configure/configure-macos.md#configure-the-grafana-agent-service" +[Configure]: "/docs/agent/ -> /docs/agent//flow/tasks/configure/configure-macos.md#configure-the-grafana-agent-service" +[Configure]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/tasks/configure/configure-macos.md#configure-the-grafana-agent-service" {{% /docs/reference %}} diff --git a/docs/sources/flow/tasks/configure/_index.md b/docs/sources/flow/tasks/configure/_index.md new file mode 100644 index 000000000000..fc576f8f51a3 --- /dev/null +++ b/docs/sources/flow/tasks/configure/_index.md @@ -0,0 +1,36 @@ +--- +aliases: +- /docs/grafana-cloud/agent/flow/tasks/configure/ +- /docs/grafana-cloud/monitor-infrastructure/agent/flow/tasks/configure/ +- /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/tasks/configure/ +- /docs/grafana-cloud/send-data/agent/flow/tasks/configure/ +# Previous page aliases for backwards compatibility: +- /docs/grafana-cloud/agent/flow/setup/configure/ +- /docs/grafana-cloud/monitor-infrastructure/agent/flow/setup/configure/ +- /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/setup/configure/ +- /docs/grafana-cloud/send-data/agent/flow/setup/configure/ +- ../setup/configure/ # /docs/agent/latest/flow/setup/configure/ +canonical: https://grafana.com/docs/agent/latest/flow/tasks/configure/ +description: Configure Grafana Agent Flow after it is installed +menuTitle: Configure +title: Configure Grafana Agent Flow +weight: 90 +--- + +# Configure {{% param "PRODUCT_NAME" %}} + +You can configure {{< param "PRODUCT_NAME" >}} after it is [installed][Install]. +The default River configuration file for {{< param "PRODUCT_NAME" >}} is located at: + +* Linux: `/etc/grafana-agent-flow.river` +* macOS: `$(brew --prefix)/etc/grafana-agent-flow/config.river` +* Windows: `C:\Program Files\Grafana Agent Flow\config.river` + +This section includes information that helps you configure {{< param "PRODUCT_NAME" >}}. + +{{< section >}} + +{{% docs/reference %}} +[Install]: "/docs/agent/ -> /docs/agent//flow/setup/install/" +[Install]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/setup/install/" +{{% /docs/reference %}} diff --git a/docs/sources/flow/setup/configure/configure-kubernetes.md b/docs/sources/flow/tasks/configure/configure-kubernetes.md similarity index 80% rename from docs/sources/flow/setup/configure/configure-kubernetes.md rename to docs/sources/flow/tasks/configure/configure-kubernetes.md index 0eceedd5f89d..2941f68a4281 100644 --- a/docs/sources/flow/setup/configure/configure-kubernetes.md +++ b/docs/sources/flow/tasks/configure/configure-kubernetes.md @@ -1,10 +1,16 @@ --- aliases: +- /docs/grafana-cloud/agent/flow/tasks/configure/configure-kubernetes/ +- /docs/grafana-cloud/monitor-infrastructure/agent/flow/tasks/configure/configure-kubernetes/ +- /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/tasks/configure/configure-kubernetes/ +- /docs/grafana-cloud/send-data/agent/flow/tasks/configure/configure-kubernetes/ +# Previous page aliases for backwards compatibility: - /docs/grafana-cloud/agent/flow/setup/configure/configure-kubernetes/ - /docs/grafana-cloud/monitor-infrastructure/agent/flow/setup/configure/configure-kubernetes/ - /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/setup/configure/configure-kubernetes/ - /docs/grafana-cloud/send-data/agent/flow/setup/configure/configure-kubernetes/ -canonical: https://grafana.com/docs/agent/latest/flow/setup/configure/configure-kubernetes/ +- ../../setup/configure/configure-kubernetes/ # /docs/agent/latest/flow/setup/configure/configure-kubernetes/ +canonical: https://grafana.com/docs/agent/latest/flow/tasks/configure/configure-kubernetes/ description: Learn how to configure Grafana Agent Flow on Kubernetes menuTitle: Kubernetes title: Configure Grafana Agent Flow on Kubernetes diff --git a/docs/sources/flow/setup/configure/configure-linux.md b/docs/sources/flow/tasks/configure/configure-linux.md similarity index 86% rename from docs/sources/flow/setup/configure/configure-linux.md rename to docs/sources/flow/tasks/configure/configure-linux.md index a2cb7389774f..4b0bd3344ec6 100644 --- a/docs/sources/flow/setup/configure/configure-linux.md +++ b/docs/sources/flow/tasks/configure/configure-linux.md @@ -1,10 +1,16 @@ --- aliases: +- /docs/grafana-cloud/agent/flow/tasks/configure/configure-linux/ +- /docs/grafana-cloud/monitor-infrastructure/agent/flow/tasks/configure/configure-linux/ +- /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/tasks/configure/configure-linux/ +- /docs/grafana-cloud/send-data/agent/flow/tasks/configure/configure-linux/ +# Previous page aliases for backwards compatibility: - /docs/grafana-cloud/agent/flow/setup/configure/configure-linux/ - /docs/grafana-cloud/monitor-infrastructure/agent/flow/setup/configure/configure-linux/ - /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/setup/configure/configure-linux/ - /docs/grafana-cloud/send-data/agent/flow/setup/configure/configure-linux/ -canonical: https://grafana.com/docs/agent/latest/flow/setup/configure/configure-linux/ +- ../../setup/configure/configure-linux/ # /docs/agent/latest/flow/setup/configure/configure-linux/ +canonical: https://grafana.com/docs/agent/latest/flow/tasks/configure/configure-linux/ description: Learn how to configure Grafana Agent Flow on Linux menuTitle: Linux title: Configure Grafana Agent Flow on Linux diff --git a/docs/sources/flow/setup/configure/configure-macos.md b/docs/sources/flow/tasks/configure/configure-macos.md similarity index 85% rename from docs/sources/flow/setup/configure/configure-macos.md rename to docs/sources/flow/tasks/configure/configure-macos.md index e0943be422cb..fc1c6677f579 100644 --- a/docs/sources/flow/setup/configure/configure-macos.md +++ b/docs/sources/flow/tasks/configure/configure-macos.md @@ -1,10 +1,16 @@ --- aliases: +- /docs/grafana-cloud/agent/flow/tasks/configure/configure-macos/ +- /docs/grafana-cloud/monitor-infrastructure/agent/flow/tasks/configure/configure-macos/ +- /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/tasks/configure/configure-macos/ +- /docs/grafana-cloud/send-data/agent/flow/tasks/configure/configure-macos/ +# Previous page aliases for backwards compatibility: - /docs/grafana-cloud/agent/flow/setup/configure/configure-macos/ - /docs/grafana-cloud/monitor-infrastructure/agent/flow/setup/configure/configure-macos/ - /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/setup/configure/configure-macos/ - /docs/grafana-cloud/send-data/agent/flow/setup/configure/configure-macos/ -canonical: https://grafana.com/docs/agent/latest/flow/setup/configure/configure-macos/ +- ../../setup/configure/configure-macos/ # /docs/agent/latest/flow/setup/configure/configure-macos/ +canonical: https://grafana.com/docs/agent/latest/flow/tasks/configure/configure-macos/ description: Learn how to configure Grafana Agent Flow on macOS menuTitle: macOS title: Configure Grafana Agent Flow on macOS diff --git a/docs/sources/flow/setup/configure/configure-windows.md b/docs/sources/flow/tasks/configure/configure-windows.md similarity index 85% rename from docs/sources/flow/setup/configure/configure-windows.md rename to docs/sources/flow/tasks/configure/configure-windows.md index 520ba2b64539..806579ea1359 100644 --- a/docs/sources/flow/setup/configure/configure-windows.md +++ b/docs/sources/flow/tasks/configure/configure-windows.md @@ -1,10 +1,16 @@ --- aliases: +- /docs/grafana-cloud/agent/flow/tasks/configure/configure-windows/ +- /docs/grafana-cloud/monitor-infrastructure/agent/flow/tasks/configure/configure-windows/ +- /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/tasks/configure/configure-windows/ +- /docs/grafana-cloud/send-data/agent/flow/tasks/configure/configure-windows/ +# Previous page aliases for backwards compatibility: - /docs/grafana-cloud/agent/flow/setup/configure/configure-windows/ - /docs/grafana-cloud/monitor-infrastructure/agent/flow/setup/configure/configure-windows/ - /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/setup/configure/configure-windows/ - /docs/grafana-cloud/send-data/agent/flow/setup/configure/configure-windows/ -canonical: https://grafana.com/docs/agent/latest/flow/setup/configure/configure-windows/ +- ../../setup/configure/configure-windows/ # /docs/agent/latest/flow/setup/configure/configure-windows/ +canonical: https://grafana.com/docs/agent/latest/flow/tasks/configure/configure-windows/ description: Learn how to configure Grafana Agent Flow on Windows menuTitle: Windows title: Configure Grafana Agent Flow on Windows diff --git a/docs/sources/flow/tasks/distribute-prometheus-scrape-load.md b/docs/sources/flow/tasks/distribute-prometheus-scrape-load.md index 329f6eed9ade..ee3a3fd9827a 100644 --- a/docs/sources/flow/tasks/distribute-prometheus-scrape-load.md +++ b/docs/sources/flow/tasks/distribute-prometheus-scrape-load.md @@ -57,8 +57,8 @@ To distribute Prometheus metrics scrape load with clustering: [Clustering]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/concepts/clustering.md" [beta]: "/docs/agent/ -> /docs/agent//stability.md#beta" [beta]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/stability.md#beta" -[configure-grafana-agent]: "/docs/agent/ -> /docs/agent//flow/setup/configure" -[configure-grafana-agent]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/setup/configure" +[configure-grafana-agent]: "/docs/agent/ -> /docs/agent//flow/tasks/configure" +[configure-grafana-agent]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/tasks/configure" [Configure Prometheus metrics collection]: "/docs/agent/ -> /docs/agent//flow/tasks/collect-prometheus-metrics.md" [Configure Prometheus metrics collection]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/tasks/collect-prometheus-metrics.md" [Configure clustering]: "/docs/agent/ -> /docs/agent//flow/tasks/configure-agent-clustering.md" From cce3c302dae8b4bb703bc36ff38d26979dd70a1a Mon Sep 17 00:00:00 2001 From: mattdurham Date: Tue, 9 Jan 2024 12:28:07 -0500 Subject: [PATCH 36/68] remove windows 2012 support (#6086) --- CHANGELOG.md | 6 ++++++ docs/sources/_index.md | 2 +- docs/sources/_index.md.t | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 05a4fd7e6862..7bf22afacc7c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,11 +11,15 @@ Main (unreleased) ----------------- ### Security fixes + - Fixes following vulnerabilities (@hainenber) - [GO-2023-2409](https://github.com/advisories/GHSA-mhpq-9638-x6pw) - [GO-2023-2412](https://github.com/advisories/GHSA-7ww5-4wqc-m92c) - [CVE-2023-49568](https://github.com/advisories/GHSA-mw99-9chc-xw7r) +### Other changes + +- Removed support for Windows 2012 in line with Microsoft end of life. (@mattdurham) v0.39.0 (2024-01-09) -------------------- @@ -39,6 +43,7 @@ v0.39.0 (2024-01-09) ### Features - A new `discovery.ovhcloud` component for discovering scrape targets on OVHcloud. (@ptodev) + - Allow specifying additional containers to run. (@juangom) ### Enhancements @@ -68,6 +73,7 @@ v0.39.0 (2024-01-09) - `otelcol.receiver.prometheus` does not drop histograms without buckets anymore. (@wildum) - Added exemplars support to `otelcol.receiver.prometheus`. (@wildum) + - `mimir.rules.kubernetes` may now retry its startup on failure. (@hainenber) - Added links between compatible components in the documentation to make it diff --git a/docs/sources/_index.md b/docs/sources/_index.md index 890ac82d71a7..780a3800da31 100644 --- a/docs/sources/_index.md +++ b/docs/sources/_index.md @@ -77,7 +77,7 @@ Grafana Agent can collect, transform, and send data to: * Windows - * Minimum version: Windows Server 2012 or later, or Windows 10 or later. + * Minimum version: Windows Server 2016 or later, or Windows 10 or later. * Architectures: AMD64 * macOS diff --git a/docs/sources/_index.md.t b/docs/sources/_index.md.t index c8dccbfb6748..549ba33ef8db 100644 --- a/docs/sources/_index.md.t +++ b/docs/sources/_index.md.t @@ -77,7 +77,7 @@ Grafana Agent can collect, transform, and send data to: * Windows - * Minimum version: Windows Server 2012 or later, or Windows 10 or later. + * Minimum version: Windows Server 2016 or later, or Windows 10 or later. * Architectures: AMD64 * macOS From eed6601333f488ff9e87c5ae8339fd283a2659c5 Mon Sep 17 00:00:00 2001 From: Piotr <17101802+thampiotr@users.noreply.github.com> Date: Tue, 9 Jan 2024 18:09:07 +0000 Subject: [PATCH 37/68] Fix incorrect aliases for config migration docs (#6088) --- docs/sources/flow/tasks/migrate/from-operator.md | 2 +- docs/sources/flow/tasks/migrate/from-prometheus.md | 2 +- docs/sources/flow/tasks/migrate/from-promtail.md | 2 +- docs/sources/flow/tasks/migrate/from-static.md | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/sources/flow/tasks/migrate/from-operator.md b/docs/sources/flow/tasks/migrate/from-operator.md index 1e942a2da941..306e613bc45a 100644 --- a/docs/sources/flow/tasks/migrate/from-operator.md +++ b/docs/sources/flow/tasks/migrate/from-operator.md @@ -5,7 +5,7 @@ aliases: # Previous page aliases for backwards compatibility: - /docs/grafana-cloud/monitor-infrastructure/agent/flow/getting-started/migrating-from-operator/ - /docs/grafana-cloud/send-data/agent/flow/getting-started/migrating-from-operator/ -- ../getting-started/migrating-from-operator/ # /docs/agent/latest/flow/getting-started/migrating-from-operator/ +- ../../getting-started/migrating-from-operator/ # /docs/agent/latest/flow/getting-started/migrating-from-operator/ canonical: https://grafana.com/docs/agent/latest/flow/tasks/migrate/from-operator/ description: Migrate from Grafana Agent Operator to Grafana Agent Flow menuTitle: Migrate from Operator diff --git a/docs/sources/flow/tasks/migrate/from-prometheus.md b/docs/sources/flow/tasks/migrate/from-prometheus.md index 6224d82901e7..aa106d940b3b 100644 --- a/docs/sources/flow/tasks/migrate/from-prometheus.md +++ b/docs/sources/flow/tasks/migrate/from-prometheus.md @@ -9,7 +9,7 @@ aliases: - /docs/grafana-cloud/monitor-infrastructure/agent/flow/getting-started/migrating-from-prometheus/ - /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/getting-started/migrating-from-prometheus/ - /docs/grafana-cloud/send-data/agent/flow/getting-started/migrating-from-prometheus/ -- ../getting-started/migrating-from-prometheus/ # /docs/agent/latest/flow/getting-started/migrating-from-prometheus/ +- ../../getting-started/migrating-from-prometheus/ # /docs/agent/latest/flow/getting-started/migrating-from-prometheus/ canonical: https://grafana.com/docs/agent/latest/flow/tasks/migrate/from-prometheus/ description: Learn how to migrate from Prometheus to Grafana Agent Flow menuTitle: Migrate from Prometheus diff --git a/docs/sources/flow/tasks/migrate/from-promtail.md b/docs/sources/flow/tasks/migrate/from-promtail.md index 29dc2ca5c0e6..1416efea88c1 100644 --- a/docs/sources/flow/tasks/migrate/from-promtail.md +++ b/docs/sources/flow/tasks/migrate/from-promtail.md @@ -9,7 +9,7 @@ aliases: - /docs/grafana-cloud/monitor-infrastructure/agent/flow/getting-started/migrating-from-promtail/ - /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/getting-started/migrating-from-promtail/ - /docs/grafana-cloud/send-data/agent/flow/getting-started/migrating-from-promtail/ -- ../getting-started/migrating-from-promtail/ # /docs/agent/latest/flow/getting-started/migrating-from-promtail/ +- ../../getting-started/migrating-from-promtail/ # /docs/agent/latest/flow/getting-started/migrating-from-promtail/ canonical: https://grafana.com/docs/agent/latest/flow/tasks/migrate/from-promtail/ description: Learn how to migrate from Promtail to Grafana Agent Flow menuTitle: Migrate from Promtail diff --git a/docs/sources/flow/tasks/migrate/from-static.md b/docs/sources/flow/tasks/migrate/from-static.md index 0a6fb982853b..a08935fff859 100644 --- a/docs/sources/flow/tasks/migrate/from-static.md +++ b/docs/sources/flow/tasks/migrate/from-static.md @@ -9,7 +9,7 @@ aliases: - /docs/grafana-cloud/monitor-infrastructure/agent/flow/getting-started/migrating-from-static/ - /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/getting-started/migrating-from-static/ - /docs/grafana-cloud/send-data/agent/flow/getting-started/migrating-from-static/ -- ../getting-started/migrating-from-static/ # /docs/agent/latest/flow/getting-started/migrating-from-static/ +- ../../getting-started/migrating-from-static/ # /docs/agent/latest/flow/getting-started/migrating-from-static/ canonical: https://grafana.com/docs/agent/latest/flow/tasks/migrate/from-static/ description: Learn how to migrate your configuration from Grafana Agent Static to Grafana Agent Flow menuTitle: Migrate from Static to Flow From 3e8f39cace00130556c72e6f9533b8a4428baed1 Mon Sep 17 00:00:00 2001 From: Mischa Thompson Date: Tue, 9 Jan 2024 17:24:58 -0800 Subject: [PATCH 38/68] Fix handling of partial reads in remote.s3 (#6090) --- CHANGELOG.md | 5 +++++ component/remote/s3/watcher.go | 10 +++++++--- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7bf22afacc7c..bfc3e447ddcb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,11 @@ Main (unreleased) - [GO-2023-2412](https://github.com/advisories/GHSA-7ww5-4wqc-m92c) - [CVE-2023-49568](https://github.com/advisories/GHSA-mw99-9chc-xw7r) +### Bugfixes + +- Fix an issue in `remote.s3` where the exported content of an object would be an empty string if `remote.s3` failed to fully retrieve + the file in a single read call. (@grafana/agent-squad) + ### Other changes - Removed support for Windows 2012 in line with Microsoft end of life. (@mattdurham) diff --git a/component/remote/s3/watcher.go b/component/remote/s3/watcher.go index 45c4df2ba417..f591b2bb2cfe 100644 --- a/component/remote/s3/watcher.go +++ b/component/remote/s3/watcher.go @@ -1,7 +1,6 @@ package s3 import ( - "errors" "io" "sync" "time" @@ -100,10 +99,15 @@ func (w *watcher) getObject(ctx context.Context) ([]byte, error) { if err != nil { return []byte{}, err } + defer output.Body.Close() + buf := make([]byte, output.ContentLength) - _, err = output.Body.Read(buf) - if !errors.Is(err, io.EOF) { + + _, err = io.ReadFull(output.Body, buf) + + if err != nil { return []byte{}, err } + return buf, nil } From f696b3aaea3c373c871d47c4d7ae6505d6f28003 Mon Sep 17 00:00:00 2001 From: Paulin Todev Date: Wed, 10 Jan 2024 07:21:57 +0000 Subject: [PATCH 39/68] Explain tracing load balancing in more detail (#5904) * Explain tracing load balancing in more detail --------- Co-authored-by: Piotr <17101802+thampiotr@users.noreply.github.com> Co-authored-by: Clayton Cornell <131809008+clayton-cornell@users.noreply.github.com> --- .../otelcol.exporter.loadbalancing.md | 660 +++++++++++++++++- docs/sources/flow/setup/deploy-agent.md | 57 ++ .../static/configuration/traces-config.md | 30 +- docs/sources/static/set-up/deploy-agent.md | 380 ++++++++++ 4 files changed, 1119 insertions(+), 8 deletions(-) diff --git a/docs/sources/flow/reference/components/otelcol.exporter.loadbalancing.md b/docs/sources/flow/reference/components/otelcol.exporter.loadbalancing.md index 60480de6677e..c22c169665b7 100644 --- a/docs/sources/flow/reference/components/otelcol.exporter.loadbalancing.md +++ b/docs/sources/flow/reference/components/otelcol.exporter.loadbalancing.md @@ -15,6 +15,8 @@ title: otelcol.exporter.loadbalancing {{< docs/shared lookup="flow/stability/beta.md" source="agent" version="" >}} + + `otelcol.exporter.loadbalancing` accepts logs and traces from other `otelcol` components and writes them over the network using the OpenTelemetry Protocol (OTLP) protocol. @@ -141,8 +143,9 @@ Name | Type | Description | Default | Required ### kubernetes block -You can use the `kubernetes` block to load balance across the pods of a Kubernetes service. The Agent will be notified -by the Kubernetes API whenever a new pod is added or removed from the service. +You can use the `kubernetes` block to load balance across the pods of a Kubernetes service. +The Kubernetes API notifies {{< param "PRODUCT_NAME" >}} whenever a new pod is added or removed from the service. +The `kubernetes` resolver has a much faster response time than the `dns` resolver because it doesn't require polling. The following arguments are supported: @@ -264,6 +267,86 @@ Name | Type | Description * logs * traces +## Choose a load balancing strategy + + + + +Different {{< param "PRODUCT_NAME" >}} components require different load-balancing strategies. +The use of `otelcol.exporter.loadbalancing` is only necessary for [stateful Flow components][stateful-and-stateless-components]. + +[stateful-and-stateless-components]: {{< relref "../../setup/deploy-agent.md#stateful-and-stateless-components" >}} + +### otelcol.processor.tail_sampling + +All spans for a given trace ID must go to the same tail sampling {{< param "PRODUCT_ROOT_NAME" >}} instance. +* This can be done by configuring `otelcol.exporter.loadbalancing` with `routing_key = "traceID"`. +* If you do not configure `routing_key = "traceID"`, the sampling decision may be incorrect. + The tail sampler must have a full view of the trace when making a sampling decision. + For example, a `rate_limiting` tail sampling strategy may incorrectly pass through + more spans than expected if the spans for the same trace are spread out to more than + one {{< param "PRODUCT_NAME" >}} instance. + + + +### otelcol.connector.spanmetrics +All spans for a given `service.name` must go to the same spanmetrics {{< param "PRODUCT_ROOT_NAME" >}}. +* This can be done by configuring `otelcol.exporter.loadbalancing` with `routing_key = "service"`. +* If you do not configure `routing_key = "service"`, metrics generated from spans might be incorrect. +For example, if similar spans for the same `service.name` end up on different {{< param "PRODUCT_ROOT_NAME" >}} instances, the two {{< param "PRODUCT_ROOT_NAME" >}}s will have identical metric series for calculating span latency, errors, and number of requests. +When both {{< param "PRODUCT_ROOT_NAME" >}} instances attempt to write the metrics to a database such as Mimir, the series may clash with each other. +At best, this will lead to an error in {{< param "PRODUCT_ROOT_NAME" >}} and a rejected write to the metrics database. +At worst, it could lead to inaccurate data due to overlapping samples for the metric series. + +However, there are ways to scale `otelcol.connector.spanmetrics` without the need for a load balancer: +1. Each {{< param "PRODUCT_ROOT_NAME" >}} could add an attribute such as `collector.id` in order to make its series unique. + Then, for example, you could use a `sum by` PromQL query to aggregate the metrics from different {{< param "PRODUCT_ROOT_NAME" >}}s. + Unfortunately, an extra `collector.id` attribute has a downside that the metrics stored in the database will have higher {{< term "cardinality" >}}cardinality{{< /term >}}. +2. Spanmetrics could be generated in the backend database instead of in {{< param "PRODUCT_ROOT_NAME" >}}. + For example, span metrics can be [generated][tempo-spanmetrics] in Grafana Cloud by the Tempo traces database. + +[tempo-spanmetrics]: https://grafana.com/docs/tempo/latest/metrics-generator/span_metrics/ + +### otelcol.connector.servicegraph +It is challenging to scale `otelcol.connector.servicegraph` over multiple {{< param "PRODUCT_ROOT_NAME" >}} instances. +For `otelcol.connector.servicegraph` to work correctly, each "client" span must be paired with a "server" span to calculate metrics such as span duration. +If a "client" span goes to one {{< param "PRODUCT_ROOT_NAME" >}}, but a "server" span goes to another {{< param "PRODUCT_ROOT_NAME" >}}, then no single {{< param "PRODUCT_ROOT_NAME" >}} will be able to pair the spans and a metric won't be generated. + +`otelcol.exporter.loadbalancing` can solve this problem partially if it is configured with `routing_key = "traceID"`. +Each {{< param "PRODUCT_ROOT_NAME" >}} will then be able to calculate a service graph for each "client"/"server" pair in a trace. +It is possible to have a span with similar "server"/"client" values in a different trace, processed by another {{< param "PRODUCT_ROOT_NAME" >}}. +If two different {{< param "PRODUCT_ROOT_NAME" >}} instances process similar "server"/"client" spans, they will generate the same service graph metric series. +If the series from two {{< param "PRODUCT_ROOT_NAME" >}} are the same, this will lead to issues when writing them to the backend database. +You could differentiate the series by adding an attribute such as `"collector.id"`. +The series from different {{< param "PRODUCT_ROOT_NAME" >}}s can be aggregated using PromQL queries on the backed metrics database. +If the metrics are stored in Grafana Mimir, cardinality issues due to `"collector.id"` labels can be solved using [Adaptive Metrics][adaptive-metrics]. + +A simpler, more scalable alternative to generating service graph metrics in {{< param "PRODUCT_ROOT_NAME" >}} is to generate them entirely in the backend database. +For example, service graphs can be [generated][tempo-servicegraphs] in Grafana Cloud by the Tempo traces database. + +[tempo-servicegraphs]: https://grafana.com/docs/tempo/latest/metrics-generator/service_graphs/ +[adaptive-metrics]: https://grafana.com/docs/grafana-cloud/cost-management-and-billing/reduce-costs/metrics-costs/control-metrics-usage-via-adaptive-metrics/ + +### Mixing stateful components + +Different {{< param "PRODUCT_NAME" >}} components may require a different `routing_key` for `otelcol.exporter.loadbalancing`. +For example, `otelcol.processor.tail_sampling` requires `routing_key = "traceID"` whereas `otelcol.connector.spanmetrics` requires `routing_key = "service"`. +To load balance both types of components, two different sets of load balancers have to be set up: + +* One set of `otelcol.exporter.loadbalancing` with `routing_key = "traceID"`, sending spans to {{< param "PRODUCT_ROOT_NAME" >}}s doing tail sampling and no span metrics. +* Another set of `otelcol.exporter.loadbalancing` with `routing_key = "service"`, sending spans to {{< param "PRODUCT_ROOT_NAME" >}}s doing span metrics and no service graphs. + +Unfortunately, this can also lead to side effects. +For example, if `otelcol.connector.spanmetrics` is configured to generate exemplars, the tail sampling {{< param "PRODUCT_ROOT_NAME" >}}s might drop the trace that the exemplar points to. +There is no coordination between the tail sampling {{< param "PRODUCT_ROOT_NAME" >}}s and the span metrics {{< param "PRODUCT_ROOT_NAME" >}}s to make sure trace IDs for exemplars are kept. + + + ## Component health `otelcol.exporter.loadbalancing` is only reported as unhealthy if given an invalid @@ -274,7 +357,9 @@ configuration. `otelcol.exporter.loadbalancing` does not expose any component-specific debug information. -## Example +## Examples + +### Static resolver This example accepts OTLP logs and traces over gRPC. It then sends them in a load-balanced way to "localhost:55690" or "localhost:55700". @@ -301,6 +386,573 @@ otelcol.exporter.loadbalancing "default" { } } ``` + +### DNS resolver + +When configured with a `dns` resolver, `otelcol.exporter.loadbalancing` will do a DNS lookup +on regular intervals. Spans are exported to the addresses the DNS lookup returned. + +```river +otelcol.exporter.loadbalancing "default" { + resolver { + dns { + hostname = "grafana-agent-traces-sampling.grafana-cloud-monitoring.svc.cluster.local" + port = "34621" + interval = "5s" + timeout = "1s" + } + } + protocol { + otlp { + client {} + } + } +} +``` + +The following example shows a Kubernetes configuration that configures two sets of {{< param "PRODUCT_ROOT_NAME" >}}s: +* A pool of load-balancer {{< param "PRODUCT_ROOT_NAME" >}}s: + * Spans are received from instrumented applications via `otelcol.receiver.otlp` + * Spans are exported via `otelcol.exporter.loadbalancing`. +* A pool of sampling {{< param "PRODUCT_ROOT_NAME" >}}s: + * The sampling {{< param "PRODUCT_ROOT_NAME" >}}s run behind a headless service to enable the load-balancer {{< param "PRODUCT_ROOT_NAME" >}}s to discover them. + * Spans are received from the load-balancer {{< param "PRODUCT_ROOT_NAME" >}}s via `otelcol.receiver.otlp` + * Traces are sampled via `otelcol.processor.tail_sampling`. + * The traces are exported via `otelcol.exporter.otlp` to an OTLP-compatible database such as Tempo. + +{{< collapse title="Example Kubernetes configuration" >}} + +```yaml +apiVersion: v1 +kind: Namespace +metadata: + name: grafana-cloud-monitoring +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: k6-trace-generator + namespace: grafana-cloud-monitoring +spec: + minReadySeconds: 10 + replicas: 1 + revisionHistoryLimit: 1 + selector: + matchLabels: + name: k6-trace-generator + template: + metadata: + labels: + name: k6-trace-generator + spec: + containers: + - env: + - name: ENDPOINT + value: agent-traces-lb.grafana-cloud-monitoring.svc.cluster.local:9411 + image: ghcr.io/grafana/xk6-client-tracing:v0.0.2 + imagePullPolicy: IfNotPresent + name: k6-trace-generator +--- +apiVersion: v1 +kind: Service +metadata: + name: agent-traces-lb + namespace: grafana-cloud-monitoring +spec: + clusterIP: None + ports: + - name: agent-traces-otlp-grpc + port: 9411 + protocol: TCP + targetPort: 9411 + selector: + name: agent-traces-lb + type: ClusterIP +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: agent-traces-lb + namespace: grafana-cloud-monitoring +spec: + minReadySeconds: 10 + replicas: 1 + revisionHistoryLimit: 1 + selector: + matchLabels: + name: agent-traces-lb + template: + metadata: + labels: + name: agent-traces-lb + spec: + containers: + - args: + - run + - /etc/agent/agent_lb.river + command: + - /bin/grafana-agent + env: + - name: AGENT_MODE + value: flow + image: grafana/agent:v0.38.0 + imagePullPolicy: IfNotPresent + name: agent-traces + ports: + - containerPort: 9411 + name: otlp-grpc + protocol: TCP + - containerPort: 34621 + name: agent-lb + protocol: TCP + volumeMounts: + - mountPath: /etc/agent + name: agent-traces + volumes: + - configMap: + name: agent-traces + name: agent-traces +--- +apiVersion: v1 +kind: Service +metadata: + name: agent-traces-sampling + namespace: grafana-cloud-monitoring +spec: + clusterIP: None + ports: + - name: agent-lb + port: 34621 + protocol: TCP + targetPort: agent-lb + selector: + name: agent-traces-sampling + type: ClusterIP +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: agent-traces-sampling + namespace: grafana-cloud-monitoring +spec: + minReadySeconds: 10 + replicas: 3 + revisionHistoryLimit: 1 + selector: + matchLabels: + name: agent-traces-sampling + template: + metadata: + labels: + name: agent-traces-sampling + spec: + containers: + - args: + - run + - /etc/agent/agent_sampling.river + command: + - /bin/grafana-agent + env: + - name: AGENT_MODE + value: flow + image: grafana/agent:v0.38.0 + imagePullPolicy: IfNotPresent + name: agent-traces + ports: + - containerPort: 9411 + name: otlp-grpc + protocol: TCP + - containerPort: 34621 + name: agent-lb + protocol: TCP + volumeMounts: + - mountPath: /etc/agent + name: agent-traces + volumes: + - configMap: + name: agent-traces + name: agent-traces +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: agent-traces + namespace: grafana-cloud-monitoring +data: + agent_lb.river: | + otelcol.receiver.otlp "default" { + grpc { + endpoint = "0.0.0.0:9411" + } + output { + traces = [otelcol.exporter.loadbalancing.default.input,otelcol.exporter.logging.default.input] + } + } + + otelcol.exporter.logging "default" { + verbosity = "detailed" + } + + otelcol.exporter.loadbalancing "default" { + resolver { + dns { + hostname = "agent-traces-sampling.grafana-cloud-monitoring.svc.cluster.local" + port = "34621" + } + } + protocol { + otlp { + client { + tls { + insecure = true + } + } + } + } + } + + agent_sampling.river: | + otelcol.receiver.otlp "default" { + grpc { + endpoint = "0.0.0.0:34621" + } + output { + traces = [otelcol.exporter.otlp.default.input,otelcol.exporter.logging.default.input] + } + } + + otelcol.exporter.logging "default" { + verbosity = "detailed" + } + + otelcol.exporter.otlp "default" { + client { + endpoint = "tempo-prod-06-prod-gb-south-0.grafana.net:443" + auth = otelcol.auth.basic.creds.handler + } + } + + otelcol.auth.basic "creds" { + username = "111111" + password = "pass" + } +``` +{{< /collapse >}} + +You must fill in the correct OTLP credentials prior to running the example. +You can use [k3d][] to start the example: + + +```bash +k3d cluster create grafana-agent-lb-test +kubectl apply -f kubernetes_config.yaml +``` + +To delete the cluster, run: + +```bash +k3d cluster delete grafana-agent-lb-test +``` + +[k3d]: https://k3d.io/v5.6.0/ + +### Kubernetes resolver + +When you configure `otelcol.exporter.loadbalancing` with a `kubernetes` resolver, the Kubernetes API notifies {{< param "PRODUCT_NAME" >}} whenever a new pod is added or removed from the service. +Spans are exported to the addresses from the Kubernetes API, combined with all the possible `ports`. + +```river +otelcol.exporter.loadbalancing "default" { + resolver { + kubernetes { + service = "grafana-agent-traces-headless" + ports = [ 34621 ] + } + } + protocol { + otlp { + client {} + } + } +} +``` + +The following example shows a Kubernetes configuration that sets up two sets of {{< param "PRODUCT_ROOT_NAME" >}}s: +* A pool of load-balancer {{< param "PRODUCT_ROOT_NAME" >}}s: + * Spans are received from instrumented applications via `otelcol.receiver.otlp` + * Spans are exported via `otelcol.exporter.loadbalancing`. + * The load-balancer {{< param "PRODUCT_ROOT_NAME" >}}s will get notified by the Kubernetes API any time a pod + is added or removed from the pool of sampling {{< param "PRODUCT_ROOT_NAME" >}}s. +* A pool of sampling {{< param "PRODUCT_ROOT_NAME" >}}s: + * The sampling {{< param "PRODUCT_ROOT_NAME" >}}s do not need to run behind a headless service. + * Spans are received from the load-balancer {{< param "PRODUCT_ROOT_NAME" >}}s via `otelcol.receiver.otlp` + * Traces are sampled via `otelcol.processor.tail_sampling`. + * The traces are exported via `otelcol.exporter.otlp` to a an OTLP-compatible database such as Tempo. + + +{{< collapse title="Example Kubernetes configuration" >}} + +```yaml +apiVersion: v1 +kind: Namespace +metadata: + name: grafana-cloud-monitoring +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: agent-traces + namespace: grafana-cloud-monitoring +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: agent-traces-role + namespace: grafana-cloud-monitoring +rules: +- apiGroups: + - "" + resources: + - endpoints + verbs: + - list + - watch + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: agent-traces-rolebinding + namespace: grafana-cloud-monitoring +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: agent-traces-role +subjects: +- kind: ServiceAccount + name: agent-traces + namespace: grafana-cloud-monitoring +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: k6-trace-generator + namespace: grafana-cloud-monitoring +spec: + minReadySeconds: 10 + replicas: 1 + revisionHistoryLimit: 1 + selector: + matchLabels: + name: k6-trace-generator + template: + metadata: + labels: + name: k6-trace-generator + spec: + containers: + - env: + - name: ENDPOINT + value: agent-traces-lb.grafana-cloud-monitoring.svc.cluster.local:9411 + image: ghcr.io/grafana/xk6-client-tracing:v0.0.2 + imagePullPolicy: IfNotPresent + name: k6-trace-generator +--- +apiVersion: v1 +kind: Service +metadata: + name: agent-traces-lb + namespace: grafana-cloud-monitoring +spec: + clusterIP: None + ports: + - name: agent-traces-otlp-grpc + port: 9411 + protocol: TCP + targetPort: 9411 + selector: + name: agent-traces-lb + type: ClusterIP +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: agent-traces-lb + namespace: grafana-cloud-monitoring +spec: + minReadySeconds: 10 + replicas: 1 + revisionHistoryLimit: 1 + selector: + matchLabels: + name: agent-traces-lb + template: + metadata: + labels: + name: agent-traces-lb + spec: + containers: + - args: + - run + - /etc/agent/agent_lb.river + command: + - /bin/grafana-agent + env: + - name: AGENT_MODE + value: flow + image: grafana/agent:v0.38.0 + imagePullPolicy: IfNotPresent + name: agent-traces + ports: + - containerPort: 9411 + name: otlp-grpc + protocol: TCP + volumeMounts: + - mountPath: /etc/agent + name: agent-traces + serviceAccount: agent-traces + volumes: + - configMap: + name: agent-traces + name: agent-traces +--- +apiVersion: v1 +kind: Service +metadata: + name: agent-traces-sampling + namespace: grafana-cloud-monitoring +spec: + ports: + - name: agent-lb + port: 34621 + protocol: TCP + targetPort: agent-lb + selector: + name: agent-traces-sampling + type: ClusterIP +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: agent-traces-sampling + namespace: grafana-cloud-monitoring +spec: + minReadySeconds: 10 + replicas: 3 + revisionHistoryLimit: 1 + selector: + matchLabels: + name: agent-traces-sampling + template: + metadata: + labels: + name: agent-traces-sampling + spec: + containers: + - args: + - run + - /etc/agent/agent_sampling.river + command: + - /bin/grafana-agent + env: + - name: AGENT_MODE + value: flow + image: grafana/agent:v0.38.0 + imagePullPolicy: IfNotPresent + name: agent-traces + ports: + - containerPort: 34621 + name: agent-lb + protocol: TCP + volumeMounts: + - mountPath: /etc/agent + name: agent-traces + volumes: + - configMap: + name: agent-traces + name: agent-traces +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: agent-traces + namespace: grafana-cloud-monitoring +data: + agent_lb.river: | + otelcol.receiver.otlp "default" { + grpc { + endpoint = "0.0.0.0:9411" + } + output { + traces = [otelcol.exporter.loadbalancing.default.input,otelcol.exporter.logging.default.input] + } + } + + otelcol.exporter.logging "default" { + verbosity = "detailed" + } + + otelcol.exporter.loadbalancing "default" { + resolver { + kubernetes { + service = "agent-traces-sampling" + ports = ["34621"] + } + } + protocol { + otlp { + client { + tls { + insecure = true + } + } + } + } + } + + agent_sampling.river: | + otelcol.receiver.otlp "default" { + grpc { + endpoint = "0.0.0.0:34621" + } + output { + traces = [otelcol.exporter.otlp.default.input,otelcol.exporter.logging.default.input] + } + } + + otelcol.exporter.logging "default" { + verbosity = "detailed" + } + + otelcol.exporter.otlp "default" { + client { + endpoint = "tempo-prod-06-prod-gb-south-0.grafana.net:443" + auth = otelcol.auth.basic.creds.handler + } + } + + otelcol.auth.basic "creds" { + username = "111111" + password = "pass" + } +``` + +{{< /collapse >}} + +You must fill in the correct OTLP credentials prior to running the example. +You can use [k3d][] to start the example: + +```bash +k3d cluster create grafana-agent-lb-test +kubectl apply -f kubernetes_config.yaml +``` + +To delete the cluster, run: + +```bash +k3d cluster delete grafana-agent-lb-test +``` + ## Compatible components @@ -316,4 +968,4 @@ connection work correctly. Refer to the linked documentation for more details. {{% /admonition %}} - \ No newline at end of file + diff --git a/docs/sources/flow/setup/deploy-agent.md b/docs/sources/flow/setup/deploy-agent.md index 8328e03b65b6..60afd38aeb17 100644 --- a/docs/sources/flow/setup/deploy-agent.md +++ b/docs/sources/flow/setup/deploy-agent.md @@ -13,3 +13,60 @@ weight: 900 {{< docs/shared source="agent" lookup="/deploy-agent.md" version="" >}} +## Processing different types of telemetry in different {{< param "PRODUCT_ROOT_NAME" >}} instances + +If the load on {{< param "PRODUCT_ROOT_NAME" >}} is small, it is recommended to process all necessary telemetry signals in the same {{< param "PRODUCT_ROOT_NAME" >}} process. +For example, a single {{< param "PRODUCT_ROOT_NAME" >}} can process all of the incoming metrics, logs, traces, and profiles. + +However, if the load on the {{< param "PRODUCT_ROOT_NAME" >}}s is big, it may be beneficial to process different telemetry signals in different deployments of {{< param "PRODUCT_ROOT_NAME" >}}s. + +This provides better stability due to the isolation between processes. +For example, an overloaded {{< param "PRODUCT_ROOT_NAME" >}} processing traces won't impact an {{< param "PRODUCT_ROOT_NAME" >}} processing metrics. +Different types of signal collection require different methods for scaling: + +* "Pull" components such as `prometheus.scrape` and `pyroscope.scrape` are scaled using hashmod sharing or clustering. +* "Push" components such as `otelcol.receiver.otlp` are scaled by placing a load balancer in front of them. + +### Traces + +Scaling {{< param "PRODUCT_ROOT_NAME" >}} instances for tracing is very similar to [scaling OpenTelemetry Collector][scaling-collector] instances. +This similarity is because most {{< param "PRODUCT_NAME" >}} components used for tracing are based on components from the OTel Collector. + +[scaling-collector]: https://opentelemetry.io/docs/collector/scaling/ + +#### When to scale + +To decide whether scaling is necessary, check metrics such as: +* `receiver_refused_spans_ratio_total` from receivers such as `otelcol.receiver.otlp`. +* `processor_refused_spans_ratio_total` from processors such as `otelcol.processor.batch`. +* `exporter_send_failed_spans_ratio_total` from exporters such as `otelcol.exporter.otlp` and `otelcol.exporter.loadbalancing`. + +#### Stateful and stateless components + +In the context of tracing, a "stateful component" is a component +that needs to aggregate certain spans to work correctly. +A "stateless {{< param "PRODUCT_ROOT_NAME" >}}" is a {{< param "PRODUCT_ROOT_NAME" >}} which does not contain stateful components. + +Scaling stateful {{< param "PRODUCT_ROOT_NAME" >}}s is more difficult, because spans must be forwarded to a +specific {{< param "PRODUCT_ROOT_NAME" >}} according to a span property such as trace ID or a `service.name` attribute. +You can forward spans with `otelcol.exporter.loadbalancing`. + +Examples of stateful components: + +* `otelcol.processor.tail_sampling` +* `otelcol.connector.spanmetrics` +* `otelcol.connector.servicegraph` + + + +A "stateless component" does not need to aggregate specific spans to work correctly - +it can work correctly even if it only has some of the spans of a trace. + +A stateless {{< param "PRODUCT_ROOT_NAME" >}} can be scaled without using `otelcol.exporter.loadbalancing`. +For example, you could use an off-the-shelf load balancer to do a round-robin load balancing. + +Examples of stateless components: +* `otelcol.processor.probabilistic_sampler` +* `otelcol.processor.transform` +* `otelcol.processor.attributes` +* `otelcol.processor.span` diff --git a/docs/sources/static/configuration/traces-config.md b/docs/sources/static/configuration/traces-config.md index 57a2a724ea58..8ede4e9eb94e 100644 --- a/docs/sources/static/configuration/traces-config.md +++ b/docs/sources/static/configuration/traces-config.md @@ -308,30 +308,52 @@ tail_sampling: # It ensures that all spans of a trace are sampled in the same instance. # It works by exporting spans based on their traceID via consistent hashing. # -# Enabling this feature is required for tail_sampling to correctly work when -# different agent instances can receive spans for the same trace. +# Enabling this feature is required for "tail_sampling", "spanmetrics", and "service_graphs" +# to correctly work when spans are ingested by multiple agent instances. # # Load balancing works by layering two pipelines and consistently exporting # spans belonging to a trace to the same agent instance. # Agent instances need to be able to communicate with each other via gRPC. # +# When load_balancing is enabled: +# 1. When an Agent receives spans from the configured "receivers". +# 2. If the "attributes" processor is configured, it will run through all the spans. +# 3. The spans will be exported using the "load_balancing" configuration to any of the Agent instances. +# This may or may not be the same Agent which has already received the span. +# 4. The Agent which received the span from the loadbalancer will run these processors, +# in this order, if they are configured: +# 1. "spanmetrics" +# 2. "service_graphs" +# 3. "tail_sampling" +# 4. "automatic_logging" +# 5. "batch" +# 5. The spans are then remote written using the "remote_write" configuration. +# # Load balancing significantly increases CPU usage. This is because spans are # exported an additional time between agents. load_balancing: # resolver configures the resolution strategy for the involved backends - # It can be static, with a fixed list of hostnames, or DNS, with a hostname - # (and port) that will resolve to all IP addresses. + # It can be either "static", "dns" or "kubernetes". resolver: static: + # A fixed list of hostnames. hostnames: [ - ... ] dns: + # DNS hostname from which to resolve IP addresses. hostname: + # Port number to use with the resolved IP address when exporting spans. [ port: | default = 4317 ] # Resolver interval [ interval: | default = 5s ] # Resolver timeout [ timeout: | default = 1s ] + # The kubernetes resolver receives IP addresses of a Kubernetes service + # from the Kubernetes API. It does not require polling. The Kubernetes API + # notifies the Agent when a new pod is available and when an old pod has exited. + # + # For the kubernetes resolver to work, Agent must be running under + # a system account with "list", "watch" and "get" permissions. kubernetes: service: [ ports: | default = 4317 ] diff --git a/docs/sources/static/set-up/deploy-agent.md b/docs/sources/static/set-up/deploy-agent.md index 7af7714adaf5..5325d3b71c01 100644 --- a/docs/sources/static/set-up/deploy-agent.md +++ b/docs/sources/static/set-up/deploy-agent.md @@ -11,3 +11,383 @@ weight: 300 {{< docs/shared source="agent" lookup="/deploy-agent.md" version="" >}} +## For scalable ingestion of traces + +For small workloads, it is normal to have just one Agent handle all incoming spans with no need of load balancing. +However, for large workloads it is desirable to spread out the load of processing spans over multiple Agent instances. + +To scale the Agent for trace ingestion, do the following: +1. Set up the `load_balancing` section of the Agent's `traces` config. +2. Start multiple Agent instances, all with the same configuration, so that: + * Each Agent load balances using the same strategy. + * Each Agent processes spans in the same way. +3. The cluster of Agents is now setup for load balancing. It works as follows: + 1. Any of the Agents can receive spans from instrumented applications via the configured `receivers`. + 2. When an Agent firstly receives spans, it will forward them to any of the Agents in the cluster according to the `load_balancing` configuration. + + + +### tail_sampling + +If some of the spans for a trace end up in a different Agent, `tail_sampling` will not sample correctly. +Enabling `load_balancing` is necessary if `tail_sampling` is enabled and when there could be more than one Agent instance processing spans for the same trace. +`load_balancing` will make sure that all spans of a given trace will be processed by the same Agent instance. + +### spanmetrics + +All spans for a given `service.name` must be processed by the same `spanmetrics` Agent. +To make sure that this is the case, set up `load_balancing` with `routing_key: service`. + +### service_graphs + +It is challenging to scale `service_graphs` over multiple Agent instances. +* For `service_graphs` to work correctly, each "client" span must be paired + with a "server" span in order to calculate metrics such as span duration. +* If a "client" span goes to one Agent, but a "server" span goes to another Agent, + then no single Agent will be able to pair the spans and a metric won't be generated. + +`load_balancing` can solve this problem partially if it is configured with `routing_key: traceID`. + * Each Agent will then be able to calculate service graph for each "client"/"server" pair in a trace. + * However, it is possible to have a span with similar "server"/"client" values + in a different trace, processed by another Agent. + * If two different Agents process similar "server"/"client" spans, + they will generate the same service graph metric series. + * If the series from two Agents are the same, this will lead to issues + when writing them to the backend database. + * Users could differentiate the series by adding a label such as `"agent_id"`. + * Unfortunately, there is currently no method in the Agent to aggregate those series from different Agents and merge them into one series. + * A PromQL query could be used to aggregate the metrics from different Agents. + * If the metrics are stored in Grafana Mimir, cardinality issues due to `"agent_id"` labels can be solved using [Adaptive Metrics][adaptive-metrics]. + +A simpler, more scalable alternative to generating service graph metrics in the Agent is to generate them entirely in the backend database. +For example, service graphs can be [generated][tempo-servicegraphs] in Grafana Cloud by the Tempo traces database. + +[tempo-servicegraphs]: https://grafana.com/docs/tempo/latest/metrics-generator/service_graphs/ +[adaptive-metrics]: https://grafana.com/docs/grafana-cloud/cost-management-and-billing/reduce-costs/metrics-costs/control-metrics-usage-via-adaptive-metrics/ + +### Example Kubernetes configuration +{{< collapse title="Example Kubernetes configuration with DNS load balancing" >}} +```yaml +apiVersion: v1 +kind: Namespace +metadata: + name: grafana-cloud-monitoring +--- +apiVersion: v1 +kind: Service +metadata: + name: agent-traces + namespace: grafana-cloud-monitoring +spec: + ports: + - name: agent-traces-otlp-grpc + port: 9411 + protocol: TCP + targetPort: 9411 + selector: + name: agent-traces +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: k6-trace-generator + namespace: grafana-cloud-monitoring +spec: + minReadySeconds: 10 + replicas: 1 + revisionHistoryLimit: 1 + selector: + matchLabels: + name: k6-trace-generator + template: + metadata: + labels: + name: k6-trace-generator + spec: + containers: + - env: + - name: ENDPOINT + value: agent-traces-headless.grafana-cloud-monitoring.svc.cluster.local:9411 + image: ghcr.io/grafana/xk6-client-tracing:v0.0.2 + imagePullPolicy: IfNotPresent + name: k6-trace-generator +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: agent-traces + namespace: grafana-cloud-monitoring +spec: + minReadySeconds: 10 + replicas: 3 + revisionHistoryLimit: 1 + selector: + matchLabels: + name: agent-traces + template: + metadata: + labels: + name: agent-traces + spec: + containers: + - args: + - -config.file=/etc/agent/agent.yaml + command: + - /bin/grafana-agent + image: grafana/agent:v0.38.0 + imagePullPolicy: IfNotPresent + name: agent-traces + ports: + - containerPort: 9411 + name: otlp-grpc + protocol: TCP + - containerPort: 34621 + name: agent-lb + protocol: TCP + volumeMounts: + - mountPath: /etc/agent + name: agent-traces + volumes: + - configMap: + name: agent-traces + name: agent-traces +--- +apiVersion: v1 +kind: Service +metadata: + name: agent-traces-headless + namespace: grafana-cloud-monitoring +spec: + clusterIP: None + ports: + - name: agent-lb + port: 34621 + protocol: TCP + targetPort: agent-lb + selector: + name: agent-traces + type: ClusterIP +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: agent-traces + namespace: grafana-cloud-monitoring +data: + agent.yaml: | + traces: + configs: + - name: default + load_balancing: + exporter: + insecure: true + resolver: + dns: + hostname: agent-traces-headless.grafana-cloud-monitoring.svc.cluster.local + port: 34621 + timeout: 5s + interval: 60s + receiver_port: 34621 + receivers: + otlp: + protocols: + grpc: + endpoint: 0.0.0.0:9411 + remote_write: + - basic_auth: + username: 111111 + password: pass + endpoint: tempo-prod-06-prod-gb-south-0.grafana.net:443 + retry_on_failure: + enabled: false +``` +{{< /collapse >}} + +{{< collapse title="Example Kubernetes configuration with Kubernetes load balancing" >}} + +```yaml +apiVersion: v1 +kind: Namespace +metadata: + name: grafana-cloud-monitoring +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: grafana-agent-traces + namespace: grafana-cloud-monitoring +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: grafana-agent-traces-role + namespace: grafana-cloud-monitoring +rules: +- apiGroups: + - "" + resources: + - endpoints + verbs: + - list + - watch + - get +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: grafana-agent-traces-rolebinding + namespace: grafana-cloud-monitoring +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: grafana-agent-traces-role +subjects: +- kind: ServiceAccount + name: grafana-agent-traces + namespace: grafana-cloud-monitoring +--- +apiVersion: v1 +kind: Service +metadata: + name: agent-traces + namespace: grafana-cloud-monitoring +spec: + ports: + - name: agent-traces-otlp-grpc + port: 9411 + protocol: TCP + targetPort: 9411 + selector: + name: agent-traces +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: k6-trace-generator + namespace: grafana-cloud-monitoring +spec: + minReadySeconds: 10 + replicas: 1 + revisionHistoryLimit: 1 + selector: + matchLabels: + name: k6-trace-generator + template: + metadata: + labels: + name: k6-trace-generator + spec: + containers: + - env: + - name: ENDPOINT + value: agent-traces-headless.grafana-cloud-monitoring.svc.cluster.local:9411 + image: ghcr.io/grafana/xk6-client-tracing:v0.0.2 + imagePullPolicy: IfNotPresent + name: k6-trace-generator +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: agent-traces + namespace: grafana-cloud-monitoring +spec: + minReadySeconds: 10 + replicas: 3 + revisionHistoryLimit: 1 + selector: + matchLabels: + name: agent-traces + template: + metadata: + labels: + name: agent-traces + spec: + containers: + - args: + - -config.file=/etc/agent/agent.yaml + command: + - /bin/grafana-agent + image: grafana/agent:v0.38.0 + imagePullPolicy: IfNotPresent + name: agent-traces + ports: + - containerPort: 9411 + name: otlp-grpc + protocol: TCP + - containerPort: 34621 + name: agent-lb + protocol: TCP + volumeMounts: + - mountPath: /etc/agent + name: agent-traces + serviceAccount: grafana-agent-traces + volumes: + - configMap: + name: agent-traces + name: agent-traces +--- +apiVersion: v1 +kind: Service +metadata: + name: agent-traces-headless + namespace: grafana-cloud-monitoring +spec: + clusterIP: None + ports: + - name: agent-lb + port: 34621 + protocol: TCP + targetPort: agent-lb + selector: + name: agent-traces + type: ClusterIP +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: agent-traces + namespace: grafana-cloud-monitoring +data: + agent.yaml: | + traces: + configs: + - name: default + load_balancing: + exporter: + insecure: true + resolver: + kubernetes: + service: agent-traces-headless + ports: + - 34621 + receiver_port: 34621 + receivers: + otlp: + protocols: + grpc: + endpoint: 0.0.0.0:9411 + remote_write: + - basic_auth: + username: 111111 + password: pass + endpoint: tempo-prod-06-prod-gb-south-0.grafana.net:443 + retry_on_failure: + enabled: false``` +``` + +{{< /collapse >}} + +You need to fill in correct OTLP credentials prior to running the above examples. +The example above can be started by using [k3d][]: + +```bash +k3d cluster create grafana-agent-lb-test +kubectl apply -f kubernetes_config.yaml +``` + +To delete the cluster, run: +```bash +k3d cluster delete grafana-agent-lb-test +``` + +[k3d]: https://k3d.io/v5.6.0/ From 6b939ce77dc34a7c55854ba89b1fdae5bc2c07fb Mon Sep 17 00:00:00 2001 From: Paulin Todev Date: Wed, 10 Jan 2024 08:28:43 +0000 Subject: [PATCH 40/68] Clarify usage of spanmetrics connector with a prometheus remote write (#5980) * Clarify spanmetric generation with prometheus --------- Signed-off-by: Jack Baldry Co-authored-by: Jack Baldry Co-authored-by: Piotr <17101802+thampiotr@users.noreply.github.com> Co-authored-by: Clayton Cornell <131809008+clayton-cornell@users.noreply.github.com> --- .../connector/spanmetrics/spanmetrics_test.go | 418 +++++++++++++ .../processor/processortest/processortest.go | 99 ++++ .../otelcol.connector.spanmetrics.md | 549 ++++++++++++++++-- 3 files changed, 1025 insertions(+), 41 deletions(-) diff --git a/component/otelcol/connector/spanmetrics/spanmetrics_test.go b/component/otelcol/connector/spanmetrics/spanmetrics_test.go index 62f65966a36c..7a3a3f891504 100644 --- a/component/otelcol/connector/spanmetrics/spanmetrics_test.go +++ b/component/otelcol/connector/spanmetrics/spanmetrics_test.go @@ -1,10 +1,14 @@ package spanmetrics_test import ( + "context" "testing" "time" "github.com/grafana/agent/component/otelcol/connector/spanmetrics" + "github.com/grafana/agent/component/otelcol/processor/processortest" + "github.com/grafana/agent/pkg/flow/componenttest" + "github.com/grafana/agent/pkg/util" "github.com/grafana/river" "github.com/open-telemetry/opentelemetry-collector-contrib/connector/spanmetricsconnector" "github.com/stretchr/testify/require" @@ -331,3 +335,417 @@ func TestArguments_UnmarshalRiver(t *testing.T) { }) } } + +func testRunProcessor(t *testing.T, processorConfig string, testSignal processortest.Signal) { + ctx := componenttest.TestContext(t) + testRunProcessorWithContext(ctx, t, processorConfig, testSignal) +} + +func testRunProcessorWithContext(ctx context.Context, t *testing.T, processorConfig string, testSignal processortest.Signal) { + l := util.TestLogger(t) + + ctrl, err := componenttest.NewControllerFromID(l, "otelcol.connector.spanmetrics") + require.NoError(t, err) + + var args spanmetrics.Arguments + require.NoError(t, river.Unmarshal([]byte(processorConfig), &args)) + + // Override the arguments so signals get forwarded to the test channel. + args.Output = testSignal.MakeOutput() + + prc := processortest.ProcessorRunConfig{ + Ctx: ctx, + T: t, + Args: args, + TestSignal: testSignal, + Ctrl: ctrl, + L: l, + } + processortest.TestRunProcessor(prc) +} + +func Test_ComponentIO(t *testing.T) { + const defaultInputTrace = `{ + "resourceSpans": [{ + "resource": { + "attributes": [{ + "key": "service.name", + "value": { "stringValue": "TestSvcName" } + }, + { + "key": "res_attribute1", + "value": { "intValue": "11" } + }] + }, + "scopeSpans": [{ + "spans": [{ + "trace_id": "7bba9f33312b3dbb8b2c2c62bb7abe2d", + "span_id": "086e83747d0e381e", + "name": "TestSpan", + "attributes": [{ + "key": "attribute1", + "value": { "intValue": "78" } + }] + }] + }] + },{ + "resource": { + "attributes": [{ + "key": "service.name", + "value": { "stringValue": "TestSvcName" } + }, + { + "key": "res_attribute1", + "value": { "intValue": "11" } + }] + }, + "scopeSpans": [{ + "spans": [{ + "trace_id": "7bba9f33312b3dbb8b2c2c62bb7abe2d", + "span_id": "086e83747d0e381b", + "name": "TestSpan", + "attributes": [{ + "key": "attribute1", + "value": { "intValue": "78" } + }] + }] + }] + }] + }` + + tests := []struct { + testName string + cfg string + inputTraceJson string + expectedOutputLogJson string + }{ + { + testName: "Sum metric only", + cfg: ` + metrics_flush_interval = "1s" + histogram { + disable = true + explicit {} + } + + output { + // no-op: will be overridden by test code. + } + `, + inputTraceJson: defaultInputTrace, + expectedOutputLogJson: `{ + "resourceMetrics": [{ + "resource": { + "attributes": [{ + "key": "service.name", + "value": { "stringValue": "TestSvcName" } + }, + { + "key": "res_attribute1", + "value": { "intValue": "11" } + }] + }, + "scopeMetrics": [{ + "scope": { + "name": "spanmetricsconnector" + }, + "metrics": [{ + "name": "calls", + "sum": { + "dataPoints": [{ + "attributes": [{ + "key": "service.name", + "value": { "stringValue": "TestSvcName" } + }, + { + "key": "span.name", + "value": { "stringValue": "TestSpan" } + }, + { + "key": "span.kind", + "value": { "stringValue": "SPAN_KIND_UNSPECIFIED" } + }, + { + "key": "status.code", + "value": { "stringValue": "STATUS_CODE_UNSET" } + }], + "startTimeUnixNano": "0", + "timeUnixNano": "0", + "asInt": "2" + }], + "aggregationTemporality": 2, + "isMonotonic": true + } + }] + }] + }] + }`, + }, + { + testName: "Sum metric only for two spans", + cfg: ` + metrics_flush_interval = "1s" + histogram { + disable = true + explicit {} + } + + output { + // no-op: will be overridden by test code. + } + `, + inputTraceJson: `{ + "resourceSpans": [{ + "resource": { + "attributes": [{ + "key": "service.name", + "value": { "stringValue": "TestSvcName" } + }, + { + "key": "k8s.pod.name", + "value": { "stringValue": "first" } + }] + }, + "scopeSpans": [{ + "spans": [{ + "trace_id": "7bba9f33312b3dbb8b2c2c62bb7abe2d", + "span_id": "086e83747d0e381e", + "name": "TestSpan", + "attributes": [{ + "key": "attribute1", + "value": { "intValue": "78" } + }] + }] + }] + },{ + "resource": { + "attributes": [{ + "key": "service.name", + "value": { "stringValue": "TestSvcName" } + }, + { + "key": "k8s.pod.name", + "value": { "stringValue": "second" } + }] + }, + "scopeSpans": [{ + "spans": [{ + "trace_id": "7bba9f33312b3dbb8b2c2c62bb7abe2d", + "span_id": "086e83747d0e381b", + "name": "TestSpan", + "attributes": [{ + "key": "attribute1", + "value": { "intValue": "78" } + }] + }] + }] + }] + }`, + expectedOutputLogJson: `{ + "resourceMetrics": [{ + "resource": { + "attributes": [{ + "key": "service.name", + "value": { "stringValue": "TestSvcName" } + }, + { + "key": "k8s.pod.name", + "value": { "stringValue": "first" } + }] + }, + "scopeMetrics": [{ + "scope": { + "name": "spanmetricsconnector" + }, + "metrics": [{ + "name": "calls", + "sum": { + "dataPoints": [{ + "attributes": [{ + "key": "service.name", + "value": { "stringValue": "TestSvcName" } + }, + { + "key": "span.name", + "value": { "stringValue": "TestSpan" } + }, + { + "key": "span.kind", + "value": { "stringValue": "SPAN_KIND_UNSPECIFIED" } + }, + { + "key": "status.code", + "value": { "stringValue": "STATUS_CODE_UNSET" } + }], + "startTimeUnixNano": "0", + "timeUnixNano": "0", + "asInt": "1" + }], + "aggregationTemporality": 2, + "isMonotonic": true + } + }] + }] + }, + { + "resource": { + "attributes": [{ + "key": "service.name", + "value": { "stringValue": "TestSvcName" } + }, + { + "key": "k8s.pod.name", + "value": { "stringValue": "second" } + }] + }, + "scopeMetrics": [{ + "scope": { + "name": "spanmetricsconnector" + }, + "metrics": [{ + "name": "calls", + "sum": { + "dataPoints": [{ + "attributes": [{ + "key": "service.name", + "value": { "stringValue": "TestSvcName" } + }, + { + "key": "span.name", + "value": { "stringValue": "TestSpan" } + }, + { + "key": "span.kind", + "value": { "stringValue": "SPAN_KIND_UNSPECIFIED" } + }, + { + "key": "status.code", + "value": { "stringValue": "STATUS_CODE_UNSET" } + }], + "startTimeUnixNano": "0", + "timeUnixNano": "0", + "asInt": "1" + }], + "aggregationTemporality": 2, + "isMonotonic": true + } + }] + }] + }] + }`, + }, + { + testName: "Sum and histogram", + cfg: ` + metrics_flush_interval = "1s" + histogram { + explicit { + buckets = ["5m", "10m", "30m"] + } + } + + output { + // no-op: will be overridden by test code. + } + `, + inputTraceJson: defaultInputTrace, + expectedOutputLogJson: `{ + "resourceMetrics": [{ + "resource": { + "attributes": [{ + "key": "service.name", + "value": { "stringValue": "TestSvcName" } + }, + { + "key": "res_attribute1", + "value": { "intValue": "11" } + }] + }, + "scopeMetrics": [{ + "scope": { + "name": "spanmetricsconnector" + }, + "metrics": [{ + "name": "calls", + "sum": { + "dataPoints": [{ + "attributes": [{ + "key": "service.name", + "value": { "stringValue": "TestSvcName" } + }, + { + "key": "span.name", + "value": { "stringValue": "TestSpan" } + }, + { + "key": "span.kind", + "value": { "stringValue": "SPAN_KIND_UNSPECIFIED" } + }, + { + "key": "status.code", + "value": { "stringValue": "STATUS_CODE_UNSET" } + }], + "startTimeUnixNano": "0", + "timeUnixNano": "0", + "asInt": "2" + }], + "aggregationTemporality": 2, + "isMonotonic": true + } + }, + { + "name": "duration", + "unit": "ms", + "histogram": { + "dataPoints": [ + { + "attributes": [ + { + "key": "service.name", + "value": { + "stringValue": "TestSvcName" + } + }, + { + "key": "span.name", + "value": { + "stringValue": "TestSpan" + } + }, + { + "key": "span.kind", + "value": { + "stringValue": "SPAN_KIND_UNSPECIFIED" + } + }, + { + "key": "status.code", + "value": { + "stringValue": "STATUS_CODE_UNSET" + } + } + ], + "count": "2", + "sum": 0, + "bucketCounts": [ "2", "0", "0", "0" ], + "explicitBounds": [ 300000, 600000, 1800000 ] + } + ], + "aggregationTemporality": 2 + } + }] + }] + }] + }`, + }, + } + + for _, tt := range tests { + t.Run(tt.testName, func(t *testing.T) { + var args spanmetrics.Arguments + require.NoError(t, river.Unmarshal([]byte(tt.cfg), &args)) + + testRunProcessor(t, tt.cfg, processortest.NewTraceToMetricSignal(tt.inputTraceJson, tt.expectedOutputLogJson)) + }) + } +} diff --git a/component/otelcol/processor/processortest/processortest.go b/component/otelcol/processor/processortest/processortest.go index 3153e662c656..0298f8e9250b 100644 --- a/component/otelcol/processor/processortest/processortest.go +++ b/component/otelcol/processor/processortest/processortest.go @@ -108,6 +108,105 @@ func (s traceToLogSignal) CheckOutput(t *testing.T) { } } +// +// Trace to Metrics +// + +type traceToMetricSignal struct { + metricCh chan pmetric.Metrics + inputTrace ptrace.Traces + expectedOuutputMetric pmetric.Metrics +} + +// Any timestamps inside expectedOutputJson should be set to 0. +func NewTraceToMetricSignal(inputJson string, expectedOutputJson string) Signal { + return &traceToMetricSignal{ + metricCh: make(chan pmetric.Metrics), + inputTrace: CreateTestTraces(inputJson), + expectedOuutputMetric: CreateTestMetrics(expectedOutputJson), + } +} + +func (s traceToMetricSignal) MakeOutput() *otelcol.ConsumerArguments { + return makeMetricsOutput(s.metricCh) +} + +func (s traceToMetricSignal) ConsumeInput(ctx context.Context, consumer otelcol.Consumer) error { + return consumer.ConsumeTraces(ctx, s.inputTrace) +} + +// Set the timestamp of all data points to 0. +// This helps avoid flaky tests due to timestamps. +func setMetricTimestampToZero(metrics pmetric.Metrics) { + // Loop over all resource metrics + for i := 0; i < metrics.ResourceMetrics().Len(); i++ { + rm := metrics.ResourceMetrics().At(i) + // Loop over all metric scopes. + for j := 0; j < rm.ScopeMetrics().Len(); j++ { + sm := rm.ScopeMetrics().At(j) + // Loop over all metrics. + for k := 0; k < sm.Metrics().Len(); k++ { + m := sm.Metrics().At(k) + switch m.Type() { + case pmetric.MetricTypeSum: + // Loop over all data points. + for l := 0; l < m.Sum().DataPoints().Len(); l++ { + // Set the timestamp to 0 to avoid flaky tests. + dp := m.Sum().DataPoints().At(l) + dp.SetTimestamp(0) + dp.SetStartTimestamp(0) + } + case pmetric.MetricTypeGauge: + // Loop over all data points. + for l := 0; l < m.Gauge().DataPoints().Len(); l++ { + // Set the timestamp to 0 to avoid flaky tests. + dp := m.Gauge().DataPoints().At(l) + dp.SetTimestamp(0) + dp.SetStartTimestamp(0) + } + case pmetric.MetricTypeHistogram: + // Loop over all data points. + for l := 0; l < m.Histogram().DataPoints().Len(); l++ { + // Set the timestamp to 0 to avoid flaky tests. + dp := m.Histogram().DataPoints().At(l) + dp.SetTimestamp(0) + dp.SetStartTimestamp(0) + } + case pmetric.MetricTypeSummary: + // Loop over all data points. + for l := 0; l < m.Summary().DataPoints().Len(); l++ { + // Set the timestamp to 0 to avoid flaky tests. + dp := m.Summary().DataPoints().At(l) + dp.SetTimestamp(0) + dp.SetStartTimestamp(0) + } + } + } + } + } +} + +// Wait for the component to finish and check its output. +func (s traceToMetricSignal) CheckOutput(t *testing.T) { + // Set the timeout to a few seconds so that all components have finished. + // Components such as otelcol.connector.spanmetrics may need a few + // seconds before they output metrics. + timeout := time.Second * 5 + + select { + case <-time.After(timeout): + require.FailNow(t, "failed waiting for metrics") + case tr := <-s.metricCh: + setMetricTimestampToZero(tr) + trStr := marshalMetrics(tr) + + expStr := marshalMetrics(s.expectedOuutputMetric) + // Set a field from the json to an empty string to avoid flaky tests containing timestamps. + + require.JSONEq(t, expStr, trStr) + } +} + // // Traces // diff --git a/docs/sources/flow/reference/components/otelcol.connector.spanmetrics.md b/docs/sources/flow/reference/components/otelcol.connector.spanmetrics.md index c1e887b78c9f..23c2eaa0a24d 100644 --- a/docs/sources/flow/reference/components/otelcol.connector.spanmetrics.md +++ b/docs/sources/flow/reference/components/otelcol.connector.spanmetrics.md @@ -22,10 +22,25 @@ aggregates Request, Error and Duration (R.E.D) OpenTelemetry metrics from the sp including Errors. Multiple metrics can be aggregated if, for instance, a user wishes to view call counts just on `service.name` and `span.name`. -- **Error** counts are computed from the Request counts which have an `Error` status code metric dimension. + Requests are tracked using a `calls` metric with a `status.code` datapoint attribute set to `Ok`: + ``` + calls { service.name="shipping", span.name="get_shipping/{shippingId}", span.kind="SERVER", status.code="Ok" } + ``` + +- **Error** counts are computed from the number of spans with an `Error` status code. + + Errors are tracked using a `calls` metric with a `status.code` datapoint attribute set to `Error`: + ``` + calls { service.name="shipping", span.name="get_shipping/{shippingId}, span.kind="SERVER", status.code="Error" } + ``` - **Duration** is computed from the difference between the span start and end times and inserted - into the relevant duration histogram time bucket for each unique set dimensions. + into the relevant duration histogram time bucket for each unique set dimensions. + + Span durations are tracked using a `duration` histogram metric: + ``` + duration { service.name="shipping", span.name="get_shipping/{shippingId}", span.kind="SERVER", status.code="Ok" } + ``` > **NOTE**: `otelcol.connector.spanmetrics` is a wrapper over the upstream > OpenTelemetry Collector `spanmetrics` connector. Bug reports or feature requests @@ -52,13 +67,13 @@ otelcol.connector.spanmetrics "LABEL" { `otelcol.connector.spanmetrics` supports the following arguments: -| Name | Type | Description | Default | Required | -| ------------------------- | ---------- | ------------------------------------------------------- | -------------- | -------- | -| `dimensions_cache_size` | `number` | How many dimensions to cache. | `1000` | no | -| `aggregation_temporality` | `string` | Configures whether to reset the metrics after flushing. | `"CUMULATIVE"` | no | -| `metrics_flush_interval` | `duration` | How often to flush generated metrics. | `"15s"` | no | -| `namespace` | `string` | Metric namespace. | `""` | no | -| `exclude_dimensions` | `list(string)` | List of dimensions to be excluded from the default set of dimensions. | `false` | no | +| Name | Type | Description | Default | Required | +| ------------------------- | -------------- | --------------------------------------------------------------------- | -------------- | -------- | +| `dimensions_cache_size` | `number` | How many dimensions to cache. | `1000` | no | +| `aggregation_temporality` | `string` | Configures whether to reset the metrics after flushing. | `"CUMULATIVE"` | no | +| `metrics_flush_interval` | `duration` | How often to flush generated metrics. | `"15s"` | no | +| `namespace` | `string` | Metric namespace. | `""` | no | +| `exclude_dimensions` | `list(string)` | List of dimensions to be excluded from the default set of dimensions. | `false` | no | Adjusting `dimensions_cache_size` can improve the Agent process' memory usage. @@ -130,10 +145,10 @@ The `histogram` block configures the histogram derived from spans' durations. The following attributes are supported: -| Name | Type | Description | Default | Required | -| ------ | -------- | ------------------------------- | ------- | -------- | -| `unit` | `string` | Configures the histogram units. | `"ms"` | no | -| `disable`| `bool` | Disable all histogram metrics. | `false` | no | +| Name | Type | Description | Default | Required | +| --------- | -------- | ------------------------------- | ------- | -------- | +| `unit` | `string` | Configures the histogram units. | `"ms"` | no | +| `disable` | `bool` | Disable all histogram metrics. | `false` | no | The supported values for `unit` are: @@ -166,9 +181,9 @@ The `exemplars` block configures how to attach exemplars to histograms. The following attributes are supported: -| Name | Type | Description | Default | Required | -| ---------- | -------- | ---------------------------------------------------------------- | ------- | -------- | -| `enabled` | `bool` | Configures whether to add exemplars to histograms. | `false` | no | +| Name | Type | Description | Default | Required | +| --------- | ------ | -------------------------------------------------- | ------- | -------- | +| `enabled` | `bool` | Configures whether to add exemplars to histograms. | `false` | no | ### output block @@ -184,6 +199,348 @@ The following fields are exported and can be referenced by other components: `input` accepts `otelcol.Consumer` traces telemetry data. It does not accept metrics and logs. +## Handling of resource attributes + +[Handling of resource attributes]: #handling-of-resource-attributes + +`otelcol.connector.spanmetrics` is an OTLP-native component. As such, it aims to preserve the resource attributes of spans. + +1. For example, let's assume that there are two incoming resources spans with the same `service.name` and `k8s.pod.name` resource attributes. + {{< collapse title="Example JSON of two incoming spans." >}} + + ```json + { + "resourceSpans": [ + { + "resource": { + "attributes": [ + { + "key": "service.name", + "value": { "stringValue": "TestSvcName" } + }, + { + "key": "k8s.pod.name", + "value": { "stringValue": "first" } + } + ] + }, + "scopeSpans": [ + { + "spans": [ + { + "trace_id": "7bba9f33312b3dbb8b2c2c62bb7abe2d", + "span_id": "086e83747d0e381e", + "name": "TestSpan", + "attributes": [ + { + "key": "attribute1", + "value": { "intValue": "78" } + } + ] + } + ] + } + ] + }, + { + "resource": { + "attributes": [ + { + "key": "service.name", + "value": { "stringValue": "TestSvcName" } + }, + { + "key": "k8s.pod.name", + "value": { "stringValue": "first" } + } + ] + }, + "scopeSpans": [ + { + "spans": [ + { + "trace_id": "7bba9f33312b3dbb8b2c2c62bb7abe2d", + "span_id": "086e83747d0e381b", + "name": "TestSpan", + "attributes": [ + { + "key": "attribute1", + "value": { "intValue": "78" } + } + ] + } + ] + } + ] + } + ] + } + ``` + + {{< /collapse >}} + +1. `otelcol.connector.spanmetrics` will preserve the incoming `service.name` and `k8s.pod.name` resource attributes by attaching them to the output metrics resource. + Only one metric resource will be created, because both span resources have identical resource attributes. + {{< collapse title="Example JSON of one outgoing metric resource." >}} + + ```json + { + "resourceMetrics": [ + { + "resource": { + "attributes": [ + { + "key": "service.name", + "value": { "stringValue": "TestSvcName" } + }, + { + "key": "k8s.pod.name", + "value": { "stringValue": "first" } + } + ] + }, + "scopeMetrics": [ + { + "scope": { "name": "spanmetricsconnector" }, + "metrics": [ + { + "name": "calls", + "sum": { + "dataPoints": [ + { + "attributes": [ + { + "key": "service.name", + "value": { "stringValue": "TestSvcName" } + }, + { + "key": "span.name", + "value": { "stringValue": "TestSpan" } + }, + { + "key": "span.kind", + "value": { "stringValue": "SPAN_KIND_UNSPECIFIED" } + }, + { + "key": "status.code", + "value": { "stringValue": "STATUS_CODE_UNSET" } + } + ], + "startTimeUnixNano": "1702582936761872000", + "timeUnixNano": "1702582936761872012", + "asInt": "2" + } + ], + "aggregationTemporality": 2, + "isMonotonic": true + } + } + ] + } + ] + } + ] + } + ``` + + {{< /collapse >}} + +1. Now assume that `otelcol.connector.spanmetrics` receives two incoming resource spans, each with a different value for the `k8s.pod.name` recourse attribute. + {{< collapse title="Example JSON of two incoming spans." >}} + + ```json + { + "resourceSpans": [ + { + "resource": { + "attributes": [ + { + "key": "service.name", + "value": { "stringValue": "TestSvcName" } + }, + { + "key": "k8s.pod.name", + "value": { "stringValue": "first" } + } + ] + }, + "scopeSpans": [ + { + "spans": [ + { + "trace_id": "7bba9f33312b3dbb8b2c2c62bb7abe2d", + "span_id": "086e83747d0e381e", + "name": "TestSpan", + "attributes": [ + { + "key": "attribute1", + "value": { "intValue": "78" } + } + ] + } + ] + } + ] + }, + { + "resource": { + "attributes": [ + { + "key": "service.name", + "value": { "stringValue": "TestSvcName" } + }, + { + "key": "k8s.pod.name", + "value": { "stringValue": "second" } + } + ] + }, + "scopeSpans": [ + { + "spans": [ + { + "trace_id": "7bba9f33312b3dbb8b2c2c62bb7abe2d", + "span_id": "086e83747d0e381b", + "name": "TestSpan", + "attributes": [ + { + "key": "attribute1", + "value": { "intValue": "78" } + } + ] + } + ] + } + ] + } + ] + } + ``` + + {{< /collapse >}} + +1. To preserve the values of all resource attributes, `otelcol.connector.spanmetrics` will produce two resource metrics. + Each resource metric will have a different value for the `k8s.pod.name` recourse attribute. + This way none of the resource attributes will be lost during the generation of metrics. + {{< collapse title="Example JSON of two outgoing metric resources." >}} + ```json + { + "resourceMetrics": [ + { + "resource": { + "attributes": [ + { + "key": "service.name", + "value": { "stringValue": "TestSvcName" } + }, + { + "key": "k8s.pod.name", + "value": { "stringValue": "first" } + } + ] + }, + "scopeMetrics": [ + { + "scope": { + "name": "spanmetricsconnector" + }, + "metrics": [ + { + "name": "calls", + "sum": { + "dataPoints": [ + { + "attributes": [ + { + "key": "service.name", + "value": { "stringValue": "TestSvcName" } + }, + { + "key": "span.name", + "value": { "stringValue": "TestSpan" } + }, + { + "key": "span.kind", + "value": { "stringValue": "SPAN_KIND_UNSPECIFIED" } + }, + { + "key": "status.code", + "value": { "stringValue": "STATUS_CODE_UNSET" } + } + ], + "startTimeUnixNano": "1702582936761872000", + "timeUnixNano": "1702582936761872012", + "asInt": "1" + } + ], + "aggregationTemporality": 2, + "isMonotonic": true + } + } + ] + } + ] + }, + { + "resource": { + "attributes": [ + { + "key": "service.name", + "value": { "stringValue": "TestSvcName" } + }, + { + "key": "k8s.pod.name", + "value": { "stringValue": "second" } + } + ] + }, + "scopeMetrics": [ + { + "scope": { + "name": "spanmetricsconnector" + }, + "metrics": [ + { + "name": "calls", + "sum": { + "dataPoints": [ + { + "attributes": [ + { + "key": "service.name", + "value": { "stringValue": "TestSvcName" } + }, + { + "key": "span.name", + "value": { "stringValue": "TestSpan" } + }, + { + "key": "span.kind", + "value": { "stringValue": "SPAN_KIND_UNSPECIFIED" } + }, + { + "key": "status.code", + "value": { "stringValue": "STATUS_CODE_UNSET" } + } + ], + "startTimeUnixNano": "1702582936761872000", + "timeUnixNano": "1702582936761872012", + "asInt": "1" + } + ], + "aggregationTemporality": 2, + "isMonotonic": true + } + } + ] + } + ] + } + ] + } + ``` + {{< /collapse >}} + ## Component health `otelcol.connector.spanmetrics` is only reported as unhealthy if given an invalid @@ -259,42 +616,152 @@ otelcol.exporter.otlp "production" { ### Sending metrics via a Prometheus remote write -In order for a `target_info` metric to be generated, the incoming spans resource scope -attributes must contain `service.name` and `service.instance.id` attributes. +The generated metrics can be sent to a Prometheus-compatible database such as Grafana Mimir. +However, extra steps are required in order to make sure all metric samples are received. +This is because `otelcol.connector.spanmetrics` aims to [preserve resource attributes][Handling of resource attributes] in the metrics which it outputs. -The `target_info` metric will be generated for each resource scope, while OpenTelemetry -metric names and attributes will be normalized to be compliant with Prometheus naming rules. +Unfortunately, the [Prometheus data model][prom-data-model] has no notion of resource attributes. +This means that if `otelcol.connector.spanmetrics` outputs metrics with identical metric attributes, +but different resource attributes, `otelcol.exporter.prometheus` will convert the metrics into the same metric series. +This problem can be solved by doing **either** of the following: -```river -otelcol.receiver.otlp "default" { - http {} - grpc {} +- **Recommended approach:** Prior to `otelcol.connector.spanmetrics`, remove all resource attributes from the incoming spans which are not needed by `otelcol.connector.spanmetrics`. + {{< collapse title="Example River configuration to remove unnecessary resource attributes." >}} + ```river + otelcol.receiver.otlp "default" { + http {} + grpc {} - output { - traces = [otelcol.connector.spanmetrics.default.input] + output { + traces = [otelcol.processor.transform.default.input] + } } -} -otelcol.connector.spanmetrics "default" { - histogram { - exponential {} + // Remove all resource attributes except the ones which + // the otelcol.connector.spanmetrics needs. + // If this is not done, otelcol.exporter.prometheus may fail to + // write some samples due to an "err-mimir-sample-duplicate-timestamp" error. + // This is because the spanmetricsconnector will create a new + // metrics resource scope for each traces resource scope. + otelcol.processor.transform "default" { + error_mode = "ignore" + + trace_statements { + context = "resource" + statements = [ + // We keep only the "service.name" and "special.attr" resource attributes, + // because they are the only ones which otelcol.connector.spanmetrics needs. + // + // There is no need to list "span.name", "span.kind", and "status.code" + // here because they are properties of the span (and not resource attributes): + // https://github.com/open-telemetry/opentelemetry-proto/blob/v1.0.0/opentelemetry/proto/trace/v1/trace.proto + `keep_keys(attributes, ["service.name", "special.attr"])`, + ] + } + + output { + traces = [otelcol.connector.spanmetrics.default.input] + } } - output { - metrics = [otelcol.exporter.prometheus.default.input] + otelcol.connector.spanmetrics "default" { + histogram { + explicit {} + } + + dimension { + name = "special.attr" + } + output { + metrics = [otelcol.exporter.prometheus.default.input] + } } -} -otelcol.exporter.prometheus "default" { - forward_to = [prometheus.remote_write.mimir.receiver] -} + otelcol.exporter.prometheus "default" { + forward_to = [prometheus.remote_write.mimir.receiver] + } -prometheus.remote_write "mimir" { - endpoint { - url = "http://mimir:9009/api/v1/push" + prometheus.remote_write "mimir" { + endpoint { + url = "http://mimir:9009/api/v1/push" + } } -} -``` + ``` + {{< /collapse >}} + +- Or, after `otelcol.connector.spanmetrics`, copy each of the resource attributes as a metric datapoint attribute. +This has the advantage that the resource attributes will be visible as metric labels. +However, the {{< term "cardinality" >}}cardinality{{< /term >}} of the metrics may be much higher, which could increase the cost of storing and querying them. +The example below uses the [merge_maps][] OTTL function. + + {{< collapse title="Example River configuration to add all resource attributes as metric datapoint attributes." >}} + ```river + otelcol.receiver.otlp "default" { + http {} + grpc {} + + output { + traces = [otelcol.connector.spanmetrics.default.input] + } + } + + otelcol.connector.spanmetrics "default" { + histogram { + explicit {} + } + + dimension { + name = "special.attr" + } + output { + metrics = [otelcol.processor.transform.default.input] + } + } + + // Insert resource attributes as metric data point attributes. + otelcol.processor.transform "default" { + error_mode = "ignore" + + metric_statements { + context = "datapoint" + statements = [ + // "insert" means that a metric datapoint attribute will be inserted + // only if an attribute with the same key does not already exist. + `merge_maps(attributes, resource.attributes, "insert")`, + ] + } + + output { + metrics = [otelcol.exporter.prometheus.default.input] + } + } + + otelcol.exporter.prometheus "default" { + forward_to = [prometheus.remote_write.mimir.receiver] + } + + prometheus.remote_write "mimir" { + endpoint { + url = "http://mimir:9009/api/v1/push" + } + } + ``` + {{< /collapse >}} + +If the resource attributes are not treated in either of the ways described above, an error such as this one could be logged by `prometheus.remote_write`: +`the sample has been rejected because another sample with the same timestamp, but a different value, has already been ingested (err-mimir-sample-duplicate-timestamp)`. + +{{% admonition type="note" %}} +In order for a Prometheus `target_info` metric to be generated, the incoming spans resource scope +attributes must contain `service.name` and `service.instance.id` attributes. + +The `target_info` metric will be generated for each resource scope, while OpenTelemetry +metric names and attributes will be normalized to be compliant with Prometheus naming rules. +{{% /admonition %}} + +[merge_maps]: https://github.com/open-telemetry/opentelemetry-collector-contrib/blob/{{< param "OTEL_VERSION" >}}/pkg/ottl/ottlfuncs/README.md#merge_maps +[prom-data-model]: https://prometheus.io/docs/concepts/data_model/ + ## Compatible components From ab2be32453f4f1de71cce7ca58814f2a1748f7da Mon Sep 17 00:00:00 2001 From: Paschalis Tsilias Date: Wed, 10 Jan 2024 10:55:56 +0200 Subject: [PATCH 41/68] loki.source.docker: deduplicate matching container IDs (#6055) Signed-off-by: Paschalis Tsilias Co-authored-by: Clayton Cornell <131809008+clayton-cornell@users.noreply.github.com> --- CHANGELOG.md | 4 ++ Makefile | 2 +- component/loki/source/docker/docker.go | 5 +++ component/loki/source/docker/docker_test.go | 40 +++++++++++++++++++ .../components/loki.source.docker.md | 8 ++++ 5 files changed, 58 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bfc3e447ddcb..07db2c44cee5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -103,11 +103,15 @@ v0.39.0 (2024-01-09) - Add `max_cache_size` to `prometheus.relabel` to allow configurability instead of hard coded 100,000. (@mattdurham) - Add support for `http_sd_config` within a `scrape_config` for prometheus to flow config conversion. (@erikbaranowski) + - `discovery.lightsail` now supports additional parameters for configuring HTTP client settings. (@ptodev) - Add `sample_age_limit` to remote_write config to drop samples older than a specified duration. (@marctc) - Handle paths in the Kubelet URL for `discovery.kubelet`. (@petewall) +- `loki.source.docker` now deduplicates targets which report the same container + ID. (@tpaschalis) + ### Bugfixes - Update `pyroscope.ebpf` to fix a logical bug causing to profile to many kthreads instead of regular processes https://github.com/grafana/pyroscope/pull/2778 (@korniltsev) diff --git a/Makefile b/Makefile index 024a624d2223..5b7d4f424759 100644 --- a/Makefile +++ b/Makefile @@ -174,7 +174,7 @@ lint: agentlint # more without -race for packages that have known race detection issues. test: $(GO_ENV) go test $(GO_FLAGS) -race $(shell go list ./... | grep -v /integration-tests/) - $(GO_ENV) go test $(GO_FLAGS) ./pkg/integrations/node_exporter ./pkg/logs ./pkg/operator ./pkg/util/k8s ./component/otelcol/processor/tail_sampling ./component/loki/source/file + $(GO_ENV) go test $(GO_FLAGS) ./pkg/integrations/node_exporter ./pkg/logs ./pkg/operator ./pkg/util/k8s ./component/otelcol/processor/tail_sampling ./component/loki/source/file ./component/loki/source/docker test-packages: docker pull $(BUILD_IMAGE) diff --git a/component/loki/source/docker/docker.go b/component/loki/source/docker/docker.go index 400b1d30b5e6..193f27f1d7a2 100644 --- a/component/loki/source/docker/docker.go +++ b/component/loki/source/docker/docker.go @@ -215,6 +215,7 @@ func (c *Component) Update(args component.Arguments) error { // Convert input targets into targets to give to tailer. targets := make([]*dt.Target, 0, len(newArgs.Targets)) + seenTargets := make(map[string]struct{}, len(newArgs.Targets)) for _, target := range newArgs.Targets { containerID, ok := target[dockerLabelContainerID] @@ -222,6 +223,10 @@ func (c *Component) Update(args component.Arguments) error { level.Debug(c.opts.Logger).Log("msg", "docker target did not include container ID label:"+dockerLabelContainerID) continue } + if _, seen := seenTargets[containerID]; seen { + continue + } + seenTargets[containerID] = struct{}{} var labels = make(model.LabelSet) for k, v := range target { diff --git a/component/loki/source/docker/docker_test.go b/component/loki/source/docker/docker_test.go index 51c2a4568cff..c4b99c47388c 100644 --- a/component/loki/source/docker/docker_test.go +++ b/component/loki/source/docker/docker_test.go @@ -1,3 +1,5 @@ +//go:build !race + package docker import ( @@ -5,9 +7,11 @@ import ( "testing" "time" + "github.com/grafana/agent/component" "github.com/grafana/agent/pkg/flow/componenttest" "github.com/grafana/agent/pkg/util" "github.com/grafana/river" + "github.com/prometheus/client_golang/prometheus" "github.com/stretchr/testify/require" ) @@ -33,3 +37,39 @@ func Test(t *testing.T) { require.NoError(t, ctrl.WaitRunning(time.Minute)) } + +func TestDuplicateTargets(t *testing.T) { + // Use host that works on all platforms (including Windows). + var cfg = ` + host = "tcp://127.0.0.1:9376" + targets = [ + {__meta_docker_container_id = "foo", __meta_docker_port_private = "8080"}, + {__meta_docker_container_id = "foo", __meta_docker_port_private = "8081"}, + ] + forward_to = [] + ` + + var args Arguments + err := river.Unmarshal([]byte(cfg), &args) + require.NoError(t, err) + + ctrl, err := componenttest.NewControllerFromID(util.TestLogger(t), "loki.source.docker") + require.NoError(t, err) + + go func() { + err := ctrl.Run(context.Background(), args) + require.NoError(t, err) + }() + + require.NoError(t, ctrl.WaitRunning(time.Minute)) + + cmp, err := New(component.Options{ + ID: "loki.source.docker.test", + Logger: util.TestFlowLogger(t), + Registerer: prometheus.NewRegistry(), + DataPath: t.TempDir(), + }, args) + require.NoError(t, err) + + require.Len(t, cmp.manager.tasks, 1) +} diff --git a/docs/sources/flow/reference/components/loki.source.docker.md b/docs/sources/flow/reference/components/loki.source.docker.md index cbf77163d646..3dd327f70a80 100644 --- a/docs/sources/flow/reference/components/loki.source.docker.md +++ b/docs/sources/flow/reference/components/loki.source.docker.md @@ -131,6 +131,14 @@ fully qualified name) to store its _positions file_. The positions file stores the read offsets so that if there is a component or Agent restart, `loki.source.docker` can pick up tailing from the same spot. +If the target's argument contains multiple entries with the same container +ID (for example as a result of `discovery.docker` picking up multiple exposed +ports or networks), `loki.source.docker` will deduplicate them, and only keep +the first of each container ID instances, based on the +`__meta_docker_container_id` label. As such, the Docker daemon is queried +for each container ID only once, and only one target will be available in the +component's debug info. + ## Example This example collects log entries from the files specified in the `targets` From f70a0cd1d6ee30d19fd0622bc0e522999f5277d2 Mon Sep 17 00:00:00 2001 From: Sergey Akhmatov Date: Wed, 10 Jan 2024 14:13:06 +0400 Subject: [PATCH 42/68] prometheus.exporter.kafka: fix ignored config option (#5991) Co-authored-by: Paschalis Tsilias --- CHANGELOG.md | 2 ++ component/prometheus/exporter/kafka/kafka.go | 1 + component/prometheus/exporter/kafka/kafka_test.go | 1 + pkg/integrations/kafka_exporter/kafka_exporter.go | 10 ++++++++-- 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 07db2c44cee5..8654bd9567bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,8 @@ Main (unreleased) - Fix an issue in `remote.s3` where the exported content of an object would be an empty string if `remote.s3` failed to fully retrieve the file in a single read call. (@grafana/agent-squad) +- Utilize the `instance` Argument of `prometheus.exporter.kafka` when set. (@akhmatov-s) + ### Other changes - Removed support for Windows 2012 in line with Microsoft end of life. (@mattdurham) diff --git a/component/prometheus/exporter/kafka/kafka.go b/component/prometheus/exporter/kafka/kafka.go index f68985b50d2c..e57bb69cd5a1 100644 --- a/component/prometheus/exporter/kafka/kafka.go +++ b/component/prometheus/exporter/kafka/kafka.go @@ -90,6 +90,7 @@ func createExporter(opts component.Options, args component.Arguments, defaultIns func (a *Arguments) Convert() *kafka_exporter.Config { return &kafka_exporter.Config{ + Instance: a.Instance, KafkaURIs: a.KafkaURIs, UseSASL: a.UseSASL, UseSASLHandshake: a.UseSASLHandshake, diff --git a/component/prometheus/exporter/kafka/kafka_test.go b/component/prometheus/exporter/kafka/kafka_test.go index 4209da21cb7d..7529677dbef6 100644 --- a/component/prometheus/exporter/kafka/kafka_test.go +++ b/component/prometheus/exporter/kafka/kafka_test.go @@ -83,6 +83,7 @@ func TestRiverConvert(t *testing.T) { } converted := orig.Convert() expected := kafka_exporter.Config{ + Instance: "example", KafkaURIs: []string{"localhost:9092", "localhost:19092"}, KafkaVersion: "2.0.0", MetadataRefreshInterval: "1m", diff --git a/pkg/integrations/kafka_exporter/kafka_exporter.go b/pkg/integrations/kafka_exporter/kafka_exporter.go index b8cc491b120a..5d50fe1452ea 100644 --- a/pkg/integrations/kafka_exporter/kafka_exporter.go +++ b/pkg/integrations/kafka_exporter/kafka_exporter.go @@ -28,6 +28,9 @@ var DefaultConfig = Config{ // Config controls kafka_exporter type Config struct { + // The instance label for metrics. + Instance string `yaml:"instance,omitempty"` + // Address array (host:port) of Kafka server KafkaURIs []string `yaml:"kafka_uris,omitempty"` @@ -109,11 +112,14 @@ func (c *Config) Name() string { // there is not exactly one Kafka node, the user must manually provide // their own value for instance key in the common config. func (c *Config) InstanceKey(agentKey string) (string, error) { - if len(c.KafkaURIs) != 1 { + if len(c.KafkaURIs) == 1 { + return c.KafkaURIs[0], nil + } + if c.Instance == "" && len(c.KafkaURIs) > 1 { return "", fmt.Errorf("an automatic value for `instance` cannot be determined from %d kafka servers, manually provide one for this integration", len(c.KafkaURIs)) } - return c.KafkaURIs[0], nil + return c.Instance, nil } // NewIntegration creates a new elasticsearch_exporter From 0e8794e3bb7e8ed80492973b5c06ecf7e6df6c95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Tudur=C3=AD?= Date: Wed, 10 Jan 2024 16:18:57 +0100 Subject: [PATCH 43/68] helm: update agent version to v0.39.0 (#6092) --- operations/helm/charts/grafana-agent/CHANGELOG.md | 7 +++++++ operations/helm/charts/grafana-agent/Chart.yaml | 4 ++-- operations/helm/charts/grafana-agent/README.md | 2 +- .../grafana-agent/templates/controllers/daemonset.yaml | 2 +- .../grafana-agent/templates/controllers/statefulset.yaml | 2 +- .../grafana-agent/templates/controllers/daemonset.yaml | 2 +- .../grafana-agent/templates/controllers/daemonset.yaml | 2 +- .../grafana-agent/templates/controllers/daemonset.yaml | 2 +- .../grafana-agent/templates/controllers/deployment.yaml | 2 +- .../grafana-agent/templates/controllers/deployment.yaml | 2 +- .../grafana-agent/templates/controllers/statefulset.yaml | 2 +- .../grafana-agent/templates/controllers/statefulset.yaml | 2 +- .../grafana-agent/templates/controllers/daemonset.yaml | 2 +- .../grafana-agent/templates/controllers/daemonset.yaml | 2 +- .../grafana-agent/templates/controllers/daemonset.yaml | 2 +- .../grafana-agent/templates/controllers/daemonset.yaml | 2 +- .../grafana-agent/templates/controllers/daemonset.yaml | 2 +- .../grafana-agent/templates/controllers/daemonset.yaml | 2 +- .../grafana-agent/templates/controllers/daemonset.yaml | 2 +- .../grafana-agent/templates/controllers/daemonset.yaml | 2 +- .../grafana-agent/templates/controllers/daemonset.yaml | 2 +- .../grafana-agent/templates/controllers/daemonset.yaml | 2 +- .../grafana-agent/templates/controllers/daemonset.yaml | 2 +- .../grafana-agent/templates/controllers/daemonset.yaml | 2 +- .../grafana-agent/templates/controllers/daemonset.yaml | 2 +- .../grafana-agent/templates/controllers/daemonset.yaml | 2 +- .../grafana-agent/templates/controllers/daemonset.yaml | 2 +- .../grafana-agent/templates/controllers/daemonset.yaml | 2 +- 28 files changed, 35 insertions(+), 28 deletions(-) diff --git a/operations/helm/charts/grafana-agent/CHANGELOG.md b/operations/helm/charts/grafana-agent/CHANGELOG.md index 5fdfcb54ba54..f281cc937317 100644 --- a/operations/helm/charts/grafana-agent/CHANGELOG.md +++ b/operations/helm/charts/grafana-agent/CHANGELOG.md @@ -10,6 +10,13 @@ internal API changes are not present. Unreleased ---------- +0.31.0 (2024-01-10) +------------------- + +### Enhancements + +- Update Grafana Agent version to v0.39.0. (@marctc) + ### Bugfixes - Configure namespace for service account when RBAC resources is created. (@hainenber) diff --git a/operations/helm/charts/grafana-agent/Chart.yaml b/operations/helm/charts/grafana-agent/Chart.yaml index 45ab45dd8ba2..992503befc2a 100644 --- a/operations/helm/charts/grafana-agent/Chart.yaml +++ b/operations/helm/charts/grafana-agent/Chart.yaml @@ -2,8 +2,8 @@ apiVersion: v2 name: grafana-agent description: 'Grafana Agent' type: application -version: 0.30.0 -appVersion: 'v0.38.1' +version: 0.31.0 +appVersion: 'v0.39.0' dependencies: - name: crds diff --git a/operations/helm/charts/grafana-agent/README.md b/operations/helm/charts/grafana-agent/README.md index 2423a23cbc66..281fc208cf23 100644 --- a/operations/helm/charts/grafana-agent/README.md +++ b/operations/helm/charts/grafana-agent/README.md @@ -1,6 +1,6 @@ # Grafana Agent Helm chart -![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![Version: 0.30.0](https://img.shields.io/badge/Version-0.30.0-informational?style=flat-square) ![AppVersion: v0.38.1](https://img.shields.io/badge/AppVersion-v0.38.1-informational?style=flat-square) +![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![Version: 0.31.0](https://img.shields.io/badge/Version-0.31.0-informational?style=flat-square) ![AppVersion: v0.39.0](https://img.shields.io/badge/AppVersion-v0.39.0-informational?style=flat-square) Helm chart for deploying [Grafana Agent][] to Kubernetes. diff --git a/operations/helm/tests/additional-serviceaccount-label/grafana-agent/templates/controllers/daemonset.yaml b/operations/helm/tests/additional-serviceaccount-label/grafana-agent/templates/controllers/daemonset.yaml index 4a6e72f132cf..a99f2fd4cbf6 100644 --- a/operations/helm/tests/additional-serviceaccount-label/grafana-agent/templates/controllers/daemonset.yaml +++ b/operations/helm/tests/additional-serviceaccount-label/grafana-agent/templates/controllers/daemonset.yaml @@ -25,7 +25,7 @@ spec: serviceAccountName: grafana-agent containers: - name: grafana-agent - image: docker.io/grafana/agent:v0.38.1 + image: docker.io/grafana/agent:v0.39.0 imagePullPolicy: IfNotPresent args: - run diff --git a/operations/helm/tests/clustering/grafana-agent/templates/controllers/statefulset.yaml b/operations/helm/tests/clustering/grafana-agent/templates/controllers/statefulset.yaml index af3b0c1fd7e4..340ec8ca04fd 100644 --- a/operations/helm/tests/clustering/grafana-agent/templates/controllers/statefulset.yaml +++ b/operations/helm/tests/clustering/grafana-agent/templates/controllers/statefulset.yaml @@ -28,7 +28,7 @@ spec: serviceAccountName: grafana-agent containers: - name: grafana-agent - image: docker.io/grafana/agent:v0.38.1 + image: docker.io/grafana/agent:v0.39.0 imagePullPolicy: IfNotPresent args: - run diff --git a/operations/helm/tests/controller-volumes-extra/grafana-agent/templates/controllers/daemonset.yaml b/operations/helm/tests/controller-volumes-extra/grafana-agent/templates/controllers/daemonset.yaml index ef17189995f4..01a82312a35c 100644 --- a/operations/helm/tests/controller-volumes-extra/grafana-agent/templates/controllers/daemonset.yaml +++ b/operations/helm/tests/controller-volumes-extra/grafana-agent/templates/controllers/daemonset.yaml @@ -25,7 +25,7 @@ spec: serviceAccountName: grafana-agent containers: - name: grafana-agent - image: docker.io/grafana/agent:v0.38.1 + image: docker.io/grafana/agent:v0.39.0 imagePullPolicy: IfNotPresent args: - run diff --git a/operations/helm/tests/create-daemonset-hostnetwork/grafana-agent/templates/controllers/daemonset.yaml b/operations/helm/tests/create-daemonset-hostnetwork/grafana-agent/templates/controllers/daemonset.yaml index b43c8b537889..0f6c1dc493bd 100644 --- a/operations/helm/tests/create-daemonset-hostnetwork/grafana-agent/templates/controllers/daemonset.yaml +++ b/operations/helm/tests/create-daemonset-hostnetwork/grafana-agent/templates/controllers/daemonset.yaml @@ -25,7 +25,7 @@ spec: serviceAccountName: grafana-agent containers: - name: grafana-agent - image: docker.io/grafana/agent:v0.38.1 + image: docker.io/grafana/agent:v0.39.0 imagePullPolicy: IfNotPresent args: - run diff --git a/operations/helm/tests/create-daemonset/grafana-agent/templates/controllers/daemonset.yaml b/operations/helm/tests/create-daemonset/grafana-agent/templates/controllers/daemonset.yaml index 4a6e72f132cf..a99f2fd4cbf6 100644 --- a/operations/helm/tests/create-daemonset/grafana-agent/templates/controllers/daemonset.yaml +++ b/operations/helm/tests/create-daemonset/grafana-agent/templates/controllers/daemonset.yaml @@ -25,7 +25,7 @@ spec: serviceAccountName: grafana-agent containers: - name: grafana-agent - image: docker.io/grafana/agent:v0.38.1 + image: docker.io/grafana/agent:v0.39.0 imagePullPolicy: IfNotPresent args: - run diff --git a/operations/helm/tests/create-deployment-autoscaling/grafana-agent/templates/controllers/deployment.yaml b/operations/helm/tests/create-deployment-autoscaling/grafana-agent/templates/controllers/deployment.yaml index 74959bc95b9e..b8d1f559d7a4 100644 --- a/operations/helm/tests/create-deployment-autoscaling/grafana-agent/templates/controllers/deployment.yaml +++ b/operations/helm/tests/create-deployment-autoscaling/grafana-agent/templates/controllers/deployment.yaml @@ -25,7 +25,7 @@ spec: serviceAccountName: grafana-agent containers: - name: grafana-agent - image: docker.io/grafana/agent:v0.38.1 + image: docker.io/grafana/agent:v0.39.0 imagePullPolicy: IfNotPresent args: - run diff --git a/operations/helm/tests/create-deployment/grafana-agent/templates/controllers/deployment.yaml b/operations/helm/tests/create-deployment/grafana-agent/templates/controllers/deployment.yaml index e6b30b603cd8..7de807bd5238 100644 --- a/operations/helm/tests/create-deployment/grafana-agent/templates/controllers/deployment.yaml +++ b/operations/helm/tests/create-deployment/grafana-agent/templates/controllers/deployment.yaml @@ -26,7 +26,7 @@ spec: serviceAccountName: grafana-agent containers: - name: grafana-agent - image: docker.io/grafana/agent:v0.38.1 + image: docker.io/grafana/agent:v0.39.0 imagePullPolicy: IfNotPresent args: - run diff --git a/operations/helm/tests/create-statefulset-autoscaling/grafana-agent/templates/controllers/statefulset.yaml b/operations/helm/tests/create-statefulset-autoscaling/grafana-agent/templates/controllers/statefulset.yaml index 9ad9d83989c9..6a127404aecb 100644 --- a/operations/helm/tests/create-statefulset-autoscaling/grafana-agent/templates/controllers/statefulset.yaml +++ b/operations/helm/tests/create-statefulset-autoscaling/grafana-agent/templates/controllers/statefulset.yaml @@ -27,7 +27,7 @@ spec: serviceAccountName: grafana-agent containers: - name: grafana-agent - image: docker.io/grafana/agent:v0.38.1 + image: docker.io/grafana/agent:v0.39.0 imagePullPolicy: IfNotPresent args: - run diff --git a/operations/helm/tests/create-statefulset/grafana-agent/templates/controllers/statefulset.yaml b/operations/helm/tests/create-statefulset/grafana-agent/templates/controllers/statefulset.yaml index 14069e356960..c0b85e38db1d 100644 --- a/operations/helm/tests/create-statefulset/grafana-agent/templates/controllers/statefulset.yaml +++ b/operations/helm/tests/create-statefulset/grafana-agent/templates/controllers/statefulset.yaml @@ -28,7 +28,7 @@ spec: serviceAccountName: grafana-agent containers: - name: grafana-agent - image: docker.io/grafana/agent:v0.38.1 + image: docker.io/grafana/agent:v0.39.0 imagePullPolicy: IfNotPresent args: - run diff --git a/operations/helm/tests/custom-config/grafana-agent/templates/controllers/daemonset.yaml b/operations/helm/tests/custom-config/grafana-agent/templates/controllers/daemonset.yaml index 4a6e72f132cf..a99f2fd4cbf6 100644 --- a/operations/helm/tests/custom-config/grafana-agent/templates/controllers/daemonset.yaml +++ b/operations/helm/tests/custom-config/grafana-agent/templates/controllers/daemonset.yaml @@ -25,7 +25,7 @@ spec: serviceAccountName: grafana-agent containers: - name: grafana-agent - image: docker.io/grafana/agent:v0.38.1 + image: docker.io/grafana/agent:v0.39.0 imagePullPolicy: IfNotPresent args: - run diff --git a/operations/helm/tests/default-values/grafana-agent/templates/controllers/daemonset.yaml b/operations/helm/tests/default-values/grafana-agent/templates/controllers/daemonset.yaml index 4a6e72f132cf..a99f2fd4cbf6 100644 --- a/operations/helm/tests/default-values/grafana-agent/templates/controllers/daemonset.yaml +++ b/operations/helm/tests/default-values/grafana-agent/templates/controllers/daemonset.yaml @@ -25,7 +25,7 @@ spec: serviceAccountName: grafana-agent containers: - name: grafana-agent - image: docker.io/grafana/agent:v0.38.1 + image: docker.io/grafana/agent:v0.39.0 imagePullPolicy: IfNotPresent args: - run diff --git a/operations/helm/tests/enable-servicemonitor/grafana-agent/templates/controllers/daemonset.yaml b/operations/helm/tests/enable-servicemonitor/grafana-agent/templates/controllers/daemonset.yaml index 4a6e72f132cf..a99f2fd4cbf6 100644 --- a/operations/helm/tests/enable-servicemonitor/grafana-agent/templates/controllers/daemonset.yaml +++ b/operations/helm/tests/enable-servicemonitor/grafana-agent/templates/controllers/daemonset.yaml @@ -25,7 +25,7 @@ spec: serviceAccountName: grafana-agent containers: - name: grafana-agent - image: docker.io/grafana/agent:v0.38.1 + image: docker.io/grafana/agent:v0.39.0 imagePullPolicy: IfNotPresent args: - run diff --git a/operations/helm/tests/envFrom/grafana-agent/templates/controllers/daemonset.yaml b/operations/helm/tests/envFrom/grafana-agent/templates/controllers/daemonset.yaml index 47e8370cba61..e9b849f6ee3f 100644 --- a/operations/helm/tests/envFrom/grafana-agent/templates/controllers/daemonset.yaml +++ b/operations/helm/tests/envFrom/grafana-agent/templates/controllers/daemonset.yaml @@ -25,7 +25,7 @@ spec: serviceAccountName: grafana-agent containers: - name: grafana-agent - image: docker.io/grafana/agent:v0.38.1 + image: docker.io/grafana/agent:v0.39.0 imagePullPolicy: IfNotPresent args: - run diff --git a/operations/helm/tests/existing-config/grafana-agent/templates/controllers/daemonset.yaml b/operations/helm/tests/existing-config/grafana-agent/templates/controllers/daemonset.yaml index 204bc2f541ff..fbdb2752b3ed 100644 --- a/operations/helm/tests/existing-config/grafana-agent/templates/controllers/daemonset.yaml +++ b/operations/helm/tests/existing-config/grafana-agent/templates/controllers/daemonset.yaml @@ -25,7 +25,7 @@ spec: serviceAccountName: grafana-agent containers: - name: grafana-agent - image: docker.io/grafana/agent:v0.38.1 + image: docker.io/grafana/agent:v0.39.0 imagePullPolicy: IfNotPresent args: - run diff --git a/operations/helm/tests/extra-env/grafana-agent/templates/controllers/daemonset.yaml b/operations/helm/tests/extra-env/grafana-agent/templates/controllers/daemonset.yaml index a68d13450e34..c2ee2305fce5 100644 --- a/operations/helm/tests/extra-env/grafana-agent/templates/controllers/daemonset.yaml +++ b/operations/helm/tests/extra-env/grafana-agent/templates/controllers/daemonset.yaml @@ -25,7 +25,7 @@ spec: serviceAccountName: grafana-agent containers: - name: grafana-agent - image: docker.io/grafana/agent:v0.38.1 + image: docker.io/grafana/agent:v0.39.0 imagePullPolicy: IfNotPresent args: - run diff --git a/operations/helm/tests/extra-ports/grafana-agent/templates/controllers/daemonset.yaml b/operations/helm/tests/extra-ports/grafana-agent/templates/controllers/daemonset.yaml index 4b2b1c4bad5c..8e51da6a86f5 100644 --- a/operations/helm/tests/extra-ports/grafana-agent/templates/controllers/daemonset.yaml +++ b/operations/helm/tests/extra-ports/grafana-agent/templates/controllers/daemonset.yaml @@ -25,7 +25,7 @@ spec: serviceAccountName: grafana-agent containers: - name: grafana-agent - image: docker.io/grafana/agent:v0.38.1 + image: docker.io/grafana/agent:v0.39.0 imagePullPolicy: IfNotPresent args: - run diff --git a/operations/helm/tests/faro-ingress/grafana-agent/templates/controllers/daemonset.yaml b/operations/helm/tests/faro-ingress/grafana-agent/templates/controllers/daemonset.yaml index c4d490e0fc70..d366cde166d3 100644 --- a/operations/helm/tests/faro-ingress/grafana-agent/templates/controllers/daemonset.yaml +++ b/operations/helm/tests/faro-ingress/grafana-agent/templates/controllers/daemonset.yaml @@ -25,7 +25,7 @@ spec: serviceAccountName: grafana-agent containers: - name: grafana-agent - image: docker.io/grafana/agent:v0.38.1 + image: docker.io/grafana/agent:v0.39.0 imagePullPolicy: IfNotPresent args: - run diff --git a/operations/helm/tests/global-image-pullsecrets/grafana-agent/templates/controllers/daemonset.yaml b/operations/helm/tests/global-image-pullsecrets/grafana-agent/templates/controllers/daemonset.yaml index 1a6efea09785..808c1056ba2b 100644 --- a/operations/helm/tests/global-image-pullsecrets/grafana-agent/templates/controllers/daemonset.yaml +++ b/operations/helm/tests/global-image-pullsecrets/grafana-agent/templates/controllers/daemonset.yaml @@ -30,7 +30,7 @@ spec: - name: global-cred containers: - name: grafana-agent - image: docker.io/grafana/agent:v0.38.1 + image: docker.io/grafana/agent:v0.39.0 imagePullPolicy: IfNotPresent args: - run diff --git a/operations/helm/tests/global-image-registry/grafana-agent/templates/controllers/daemonset.yaml b/operations/helm/tests/global-image-registry/grafana-agent/templates/controllers/daemonset.yaml index 692304acd2f1..014f4b84925d 100644 --- a/operations/helm/tests/global-image-registry/grafana-agent/templates/controllers/daemonset.yaml +++ b/operations/helm/tests/global-image-registry/grafana-agent/templates/controllers/daemonset.yaml @@ -25,7 +25,7 @@ spec: serviceAccountName: grafana-agent containers: - name: grafana-agent - image: quay.io/grafana/agent:v0.38.1 + image: quay.io/grafana/agent:v0.39.0 imagePullPolicy: IfNotPresent args: - run diff --git a/operations/helm/tests/initcontainers/grafana-agent/templates/controllers/daemonset.yaml b/operations/helm/tests/initcontainers/grafana-agent/templates/controllers/daemonset.yaml index ccf576637bed..70c184364e58 100644 --- a/operations/helm/tests/initcontainers/grafana-agent/templates/controllers/daemonset.yaml +++ b/operations/helm/tests/initcontainers/grafana-agent/templates/controllers/daemonset.yaml @@ -43,7 +43,7 @@ spec: name: geoip containers: - name: grafana-agent - image: docker.io/grafana/agent:v0.38.1 + image: docker.io/grafana/agent:v0.39.0 imagePullPolicy: IfNotPresent args: - run diff --git a/operations/helm/tests/local-image-pullsecrets/grafana-agent/templates/controllers/daemonset.yaml b/operations/helm/tests/local-image-pullsecrets/grafana-agent/templates/controllers/daemonset.yaml index 9aa16540da65..319e1cf07ad2 100644 --- a/operations/helm/tests/local-image-pullsecrets/grafana-agent/templates/controllers/daemonset.yaml +++ b/operations/helm/tests/local-image-pullsecrets/grafana-agent/templates/controllers/daemonset.yaml @@ -27,7 +27,7 @@ spec: - name: local-cred containers: - name: grafana-agent - image: docker.io/grafana/agent:v0.38.1 + image: docker.io/grafana/agent:v0.39.0 imagePullPolicy: IfNotPresent args: - run diff --git a/operations/helm/tests/local-image-registry/grafana-agent/templates/controllers/daemonset.yaml b/operations/helm/tests/local-image-registry/grafana-agent/templates/controllers/daemonset.yaml index 692304acd2f1..014f4b84925d 100644 --- a/operations/helm/tests/local-image-registry/grafana-agent/templates/controllers/daemonset.yaml +++ b/operations/helm/tests/local-image-registry/grafana-agent/templates/controllers/daemonset.yaml @@ -25,7 +25,7 @@ spec: serviceAccountName: grafana-agent containers: - name: grafana-agent - image: quay.io/grafana/agent:v0.38.1 + image: quay.io/grafana/agent:v0.39.0 imagePullPolicy: IfNotPresent args: - run diff --git a/operations/helm/tests/nodeselectors-and-tolerations/grafana-agent/templates/controllers/daemonset.yaml b/operations/helm/tests/nodeselectors-and-tolerations/grafana-agent/templates/controllers/daemonset.yaml index 8cb19e413aa5..21338cf3979f 100644 --- a/operations/helm/tests/nodeselectors-and-tolerations/grafana-agent/templates/controllers/daemonset.yaml +++ b/operations/helm/tests/nodeselectors-and-tolerations/grafana-agent/templates/controllers/daemonset.yaml @@ -25,7 +25,7 @@ spec: serviceAccountName: grafana-agent containers: - name: grafana-agent - image: docker.io/grafana/agent:v0.38.1 + image: docker.io/grafana/agent:v0.39.0 imagePullPolicy: IfNotPresent args: - run diff --git a/operations/helm/tests/sidecars/grafana-agent/templates/controllers/daemonset.yaml b/operations/helm/tests/sidecars/grafana-agent/templates/controllers/daemonset.yaml index f2d72440edf6..b98de68b1306 100644 --- a/operations/helm/tests/sidecars/grafana-agent/templates/controllers/daemonset.yaml +++ b/operations/helm/tests/sidecars/grafana-agent/templates/controllers/daemonset.yaml @@ -25,7 +25,7 @@ spec: serviceAccountName: grafana-agent containers: - name: grafana-agent - image: docker.io/grafana/agent:v0.38.1 + image: docker.io/grafana/agent:v0.39.0 imagePullPolicy: IfNotPresent args: - run diff --git a/operations/helm/tests/static-mode/grafana-agent/templates/controllers/daemonset.yaml b/operations/helm/tests/static-mode/grafana-agent/templates/controllers/daemonset.yaml index 34b4d0a38504..1f9e23a47bf0 100644 --- a/operations/helm/tests/static-mode/grafana-agent/templates/controllers/daemonset.yaml +++ b/operations/helm/tests/static-mode/grafana-agent/templates/controllers/daemonset.yaml @@ -25,7 +25,7 @@ spec: serviceAccountName: grafana-agent containers: - name: grafana-agent - image: docker.io/grafana/agent:v0.38.1 + image: docker.io/grafana/agent:v0.39.0 imagePullPolicy: IfNotPresent args: - -config.file=/etc/agent/config.yaml From 340cc95d0028ba25ed36450983885e9adae2bc5d Mon Sep 17 00:00:00 2001 From: Piotr <17101802+thampiotr@users.noreply.github.com> Date: Wed, 10 Jan 2024 18:13:35 +0000 Subject: [PATCH 44/68] Split 'Start agent' into per-platform pages (#6087) * Split 'Start agent' into per-platform pages * Add links from Start to Configure * feedback & fix typo --- docs/sources/flow/setup/deploy-agent.md | 2 +- docs/sources/flow/setup/install/_index.md | 4 +- docs/sources/flow/setup/install/binary.md | 11 +- docs/sources/flow/setup/install/linux.md | 4 +- docs/sources/flow/setup/install/macos.md | 4 +- docs/sources/flow/setup/install/windows.md | 4 +- docs/sources/flow/setup/start-agent.md | 257 ------------------ docs/sources/flow/setup/start/_index.md | 31 +++ docs/sources/flow/setup/start/binary.md | 126 +++++++++ docs/sources/flow/setup/start/linux.md | 75 +++++ docs/sources/flow/setup/start/macos.md | 69 +++++ docs/sources/flow/setup/start/windows.md | 54 ++++ .../flow/tasks/migrate/from-prometheus.md | 4 +- .../flow/tasks/migrate/from-promtail.md | 4 +- .../sources/flow/tasks/migrate/from-static.md | 4 +- 15 files changed, 374 insertions(+), 279 deletions(-) delete mode 100644 docs/sources/flow/setup/start-agent.md create mode 100644 docs/sources/flow/setup/start/_index.md create mode 100644 docs/sources/flow/setup/start/binary.md create mode 100644 docs/sources/flow/setup/start/linux.md create mode 100644 docs/sources/flow/setup/start/macos.md create mode 100644 docs/sources/flow/setup/start/windows.md diff --git a/docs/sources/flow/setup/deploy-agent.md b/docs/sources/flow/setup/deploy-agent.md index 60afd38aeb17..0396b537123c 100644 --- a/docs/sources/flow/setup/deploy-agent.md +++ b/docs/sources/flow/setup/deploy-agent.md @@ -4,7 +4,7 @@ aliases: - /docs/grafana-cloud/monitor-infrastructure/agent/flow/setup/deploy-agent/ - /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/setup/deploy-agent/ - /docs/grafana-cloud/send-data/agent/flow/setup/deploy-agent/ -canonical: https://grafana.com/docs/agent/latest/flow/setup/start-agent/ +canonical: https://grafana.com/docs/agent/latest/flow/setup/deploy-agent/ description: Learn about possible deployment topologies for Grafana Agent Flow menuTitle: Deploy Grafana Agent Flow title: Grafana Agent Flow deployment topologies diff --git a/docs/sources/flow/setup/install/_index.md b/docs/sources/flow/setup/install/_index.md index 8305e7bf9a39..c9bb81a239b4 100644 --- a/docs/sources/flow/setup/install/_index.md +++ b/docs/sources/flow/setup/install/_index.md @@ -6,8 +6,8 @@ aliases: - /docs/grafana-cloud/send-data/agent/flow/setup/install/ - /docs/sources/flow/install/ canonical: https://grafana.com/docs/agent/latest/flow/setup/install/ -description: Learn how to install Grafana Agent Flow -menuTitle: Install Grafana Agent Flow +description: Learn how to install Grafana Agent Flow +menuTitle: Install title: Install Grafana Agent Flow weight: 50 --- diff --git a/docs/sources/flow/setup/install/binary.md b/docs/sources/flow/setup/install/binary.md index 88560dbf63e0..ed55b7e5e873 100644 --- a/docs/sources/flow/setup/install/binary.md +++ b/docs/sources/flow/setup/install/binary.md @@ -8,7 +8,7 @@ aliases: canonical: https://grafana.com/docs/agent/latest/flow/setup/install/binary/ description: Learn how to install Grafana Agent Flow as a standalone binary menuTitle: Standalone -title: Install Grafana Agent Flow as a standalone binary +title: Install Grafana Agent Flow as a standalone binary weight: 600 --- @@ -45,12 +45,9 @@ To download {{< param "PRODUCT_NAME" >}} as a standalone binary, perform the fol ## Next steps -- [Start {{< param "PRODUCT_NAME" >}}[Start] -- [Configure {{< param "PRODUCT_NAME" >}}[Configure] +- [Start {{< param "PRODUCT_NAME" >}}][Start] {{% docs/reference %}} -[Start]: "/docs/agent/ -> /docs/agent//flow/setup/start-agent.md#standalone-binary" -[Start]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/setup/start-agent.md#standalone-binary" -[Configure]: "/docs/agent/ -> /docs/agent//flow/tasks/configure" -[Configure]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/tasks/configure/" +[Start]: "/docs/agent/ -> /docs/agent//flow/setup/start/binary.md" +[Start]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/setup/start/binary.md" {{% /docs/reference %}} diff --git a/docs/sources/flow/setup/install/linux.md b/docs/sources/flow/setup/install/linux.md index 12e4f3323e7e..be7bd6246454 100644 --- a/docs/sources/flow/setup/install/linux.md +++ b/docs/sources/flow/setup/install/linux.md @@ -123,8 +123,8 @@ To uninstall {{< param "PRODUCT_NAME" >}} on Linux, run the following commands i - [Configure {{< param "PRODUCT_NAME" >}}][Configure] {{% docs/reference %}} -[Start]: "/docs/agent/ -> /docs/agent//flow/setup/start-agent.md#linux" -[Start]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/setup/start-agent.md#linux" +[Start]: "/docs/agent/ -> /docs/agent//flow/setup/start/linux.md" +[Start]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/setup/start/linux.md" [Configure]: "/docs/agent/ -> /docs/agent//flow/tasks/configure/configure-linux.md" [Configure]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/tasks/configure/configure-linux.md" {{% /docs/reference %}} diff --git a/docs/sources/flow/setup/install/macos.md b/docs/sources/flow/setup/install/macos.md index 9aa7e86ee265..5c61c6c82b95 100644 --- a/docs/sources/flow/setup/install/macos.md +++ b/docs/sources/flow/setup/install/macos.md @@ -72,8 +72,8 @@ brew uninstall grafana-agent-flow [Homebrew]: https://brew.sh {{% docs/reference %}} -[Start]: "/docs/agent/ -> /docs/agent//flow/setup/start-agent.md#macos" -[Start]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/setup/start-agent.md#macos" +[Start]: "/docs/agent/ -> /docs/agent//flow/setup/start/macos.md" +[Start]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/setup/start/macos.md" [Configure]: "/docs/agent/ -> /docs/agent//flow/tasks/configure/configure-macos.md" [Configure]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/tasks/configure/configure-macos.md" {{% /docs/reference %}} diff --git a/docs/sources/flow/setup/install/windows.md b/docs/sources/flow/setup/install/windows.md index 031b0caeab06..5157967a07e4 100644 --- a/docs/sources/flow/setup/install/windows.md +++ b/docs/sources/flow/setup/install/windows.md @@ -84,8 +84,8 @@ This includes any configuration files in the installation directory. [latest]: https://github.com/grafana/agent/releases/latest {{% docs/reference %}} -[Start]: "/docs/agent/ -> /docs/agent//flow/setup/start-agent.md#windows" -[Start]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/setup/start-agent.md#windows" +[Start]: "/docs/agent/ -> /docs/agent//flow/setup/start/windows.md" +[Start]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/setup/start/windows.md" [Configure]: "/docs/agent/ -> /docs/agent//flow/tasks/configure/configure-windows.md" [Configure]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/tasks/configure/configure-windows.md" [data collection]: "/docs/agent/ -> /docs/agent//data-collection.md" diff --git a/docs/sources/flow/setup/start-agent.md b/docs/sources/flow/setup/start-agent.md deleted file mode 100644 index b8bd97a75e05..000000000000 --- a/docs/sources/flow/setup/start-agent.md +++ /dev/null @@ -1,257 +0,0 @@ ---- -aliases: -- /docs/grafana-cloud/agent/flow/setup/start-agent/ -- /docs/grafana-cloud/monitor-infrastructure/agent/flow/setup/start-agent/ -- /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/setup/start-agent/ -- /docs/grafana-cloud/send-data/agent/flow/setup/start-agent/ -canonical: https://grafana.com/docs/agent/latest/flow/setup/start-agent/ -description: Learn how to start, restart, and stop Grafana Agent after it is installed -menuTitle: Start Grafana Agent Flow -title: Start, restart, and stop Grafana Agent Flow -weight: 800 ---- - -# Start, restart, and stop {{% param "PRODUCT_NAME" %}} - -You can start, restart, and stop {{< param "PRODUCT_NAME" >}} after it is installed. - -## Linux - -{{< param "PRODUCT_NAME" >}} is installed as a [systemd][] service on Linux. - -[systemd]: https://systemd.io/ - -### Start {{% param "PRODUCT_NAME" %}} - -To start {{< param "PRODUCT_NAME" >}}, run the following command in a terminal window: - -```shell -sudo systemctl start grafana-agent-flow -``` - -(Optional) To verify that the service is running, run the following command in a terminal window: - -```shell -sudo systemctl status grafana-agent-flow -``` - -### Configure {{% param "PRODUCT_NAME" %}} to start at boot - -To automatically run {{< param "PRODUCT_NAME" >}} when the system starts, run the following command in a terminal window: - -```shell -sudo systemctl enable grafana-agent-flow.service -``` - -### Restart {{% param "PRODUCT_NAME" %}} - -To restart {{< param "PRODUCT_NAME" >}}, run the following command in a terminal window: - -```shell -sudo systemctl restart grafana-agent-flow -``` - -### Stop {{% param "PRODUCT_NAME" %}} - -To stop {{< param "PRODUCT_NAME" >}}, run the following command in a terminal window: - -```shell -sudo systemctl stop grafana-agent-flow -``` - -### View {{% param "PRODUCT_NAME" %}} logs on Linux - -To view {{< param "PRODUCT_NAME" >}} log files, run the following command in a terminal window: - -```shell -sudo journalctl -u grafana-agent-flow -``` - -## macOS - -{{< param "PRODUCT_NAME" >}} is installed as a launchd service on macOS. - -### Start {{% param "PRODUCT_NAME" %}} - -To start {{< param "PRODUCT_NAME" >}}, run the following command in a terminal window: - -```shell -brew services start grafana-agent-flow -``` - -{{< param "PRODUCT_NAME" >}} automatically runs when the system starts. - -(Optional) To verify that the service is running, run the following command in a terminal window: - -```shell -brew services info grafana-agent-flow -``` - -### Restart {{% param "PRODUCT_NAME" %}} - -To restart {{< param "PRODUCT_NAME" >}}, run the following command in a terminal window: - -```shell -brew services restart grafana-agent-flow -``` - -### Stop {{% param "PRODUCT_NAME" %}} - -To stop {{< param "PRODUCT_NAME" >}}, run the following command in a terminal window: - -```shell -brew services stop grafana-agent-flow -``` - -### View {{% param "PRODUCT_NAME" %}} logs on macOS - -By default, logs are written to `$(brew --prefix)/var/log/grafana-agent-flow.log` and -`$(brew --prefix)/var/log/grafana-agent-flow.err.log`. - -If you followed [Configure the {{< param "PRODUCT_NAME" >}} service][Configure] and changed the path where logs are written, -refer to your current copy of the {{< param "PRODUCT_NAME" >}} formula to locate your log files. - -## Windows - -{{< param "PRODUCT_NAME" >}} is installed as a Windows Service. The service is configured to automatically run on startup. - -To verify that {{< param "PRODUCT_NAME" >}} is running as a Windows Service: - -1. Open the Windows Services manager (services.msc): - - 1. Right click on the Start Menu and select **Run**. - - 1. Type: `services.msc` and click **OK**. - -1. Scroll down to find the **{{< param "PRODUCT_NAME" >}}** service and verify that the **Status** is **Running**. - -### View {{% param "PRODUCT_NAME" %}} logs - -When running on Windows, {{< param "PRODUCT_NAME" >}} writes its logs to Windows Event -Logs with an event source name of **{{< param "PRODUCT_NAME" >}}**. - -To view the logs, perform the following steps: - -1. Open the Event Viewer: - - 1. Right click on the Start Menu and select **Run**. - - 1. Type `eventvwr` and click **OK**. - -1. In the Event Viewer, click on **Windows Logs > Application**. - -1. Search for events with the source **{{< param "PRODUCT_NAME" >}}**. - -## Standalone binary - -If you downloaded the standalone binary, you must run {{< param "PRODUCT_NAME" >}} from a terminal or command window. - -### Start {{% param "PRODUCT_NAME" %}} on Linux, macOS, or FreeBSD - -To start {{< param "PRODUCT_NAME" >}} on Linux, macOS, or FreeBSD, run the following command in a terminal window: - -```shell -AGENT_MODE=flow run -``` - -Replace the following: - -* _``_: The path to the {{< param "PRODUCT_NAME" >}} binary file. -* _``_: The path to the {{< param "PRODUCT_NAME" >}} configuration file. - -### Start {{% param "PRODUCT_NAME" %}} on Windows - -To start {{< param "PRODUCT_NAME" >}} on Windows, run the following commands in a command prompt: - -```cmd -set AGENT_MODE=flow - run -``` - -Replace the following: - -* _``_: The path to the {{< param "PRODUCT_NAME" >}} binary file. -* _``_: The path to the {{< param "PRODUCT_NAME" >}} configuration file. - -### Set up {{% param "PRODUCT_NAME" %}} as a Linux systemd service - -You can set up and manage the standalone binary for {{< param "PRODUCT_NAME" >}} as a Linux systemd service. - -{{% admonition type="note" %}} -These steps assume you have a default systemd and {{< param "PRODUCT_NAME" >}} configuration. -{{% /admonition %}} - -1. To create a new user called `grafana-agent-flow` run the following command in a terminal window: - - ```shell - sudo useradd --no-create-home --shell /bin/false grafana-agent-flow - ``` - -1. Create a service file in `/etc/systemd/system` called `grafana-agent-flow.service` with the following contents: - - ```systemd - [Unit] - Description=Vendor-neutral programmable observability pipelines. - Documentation=https://grafana.com/docs/agent/latest/flow/ - Wants=network-online.target - After=network-online.target - - [Service] - Restart=always - User=grafana-agent-flow - Environment=HOSTNAME=%H - EnvironmentFile=/etc/default/grafana-agent-flow - WorkingDirectory= - ExecStart= run $CUSTOM_ARGS --storage.path= $CONFIG_FILE - ExecReload=/usr/bin/env kill -HUP $MAINPID - TimeoutStopSec=20s - SendSIGKILL=no - - [Install] - WantedBy=multi-user.target - ``` - - Replace the following: - - * _``_: The path to the {{< param "PRODUCT_NAME" >}} binary file. - * _``_: The path to a working directory, for example `/var/lib/grafana-agent-flow`. - -1. Create an environment file in `/etc/default/` called `grafana-agent-flow` with the following contents: - - ```shell - ## Path: - ## Description: Grafana Agent Flow settings - ## Type: string - ## Default: "" - ## ServiceRestart: grafana-agent-flow - # - # Command line options for grafana-agent - # - # The configuration file holding the Grafana Agent Flow configuration. - CONFIG_FILE="" - - # User-defined arguments to pass to the run command. - CUSTOM_ARGS="" - - # Restart on system upgrade. Defaults to true. - RESTART_ON_UPGRADE=true - ``` - - Replace the following: - - * _``_: The path to the {{< param "PRODUCT_NAME" >}} configuration file. - -1. To reload the service files, run the following command in a terminal window: - - ```shell - sudo systemctl daemon-reload - ``` - -1. Use the [Linux](#linux) systemd commands to manage your standalone Linux installation of {{< param "PRODUCT_NAME" >}}. - -[release]: https://github.com/grafana/agent/releases/latest - -{{% docs/reference %}} -[Configure]: "/docs/agent/ -> /docs/agent//flow/tasks/configure/configure-macos.md#configure-the-grafana-agent-service" -[Configure]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/tasks/configure/configure-macos.md#configure-the-grafana-agent-service" -{{% /docs/reference %}} diff --git a/docs/sources/flow/setup/start/_index.md b/docs/sources/flow/setup/start/_index.md new file mode 100644 index 000000000000..0f989a07f56c --- /dev/null +++ b/docs/sources/flow/setup/start/_index.md @@ -0,0 +1,31 @@ +--- +aliases: +- /docs/grafana-cloud/agent/flow/setup/start/ +- /docs/grafana-cloud/monitor-infrastructure/agent/flow/setup/start/ +- /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/setup/start/ +- /docs/grafana-cloud/send-data/agent/flow/setup/start/ +- /docs/sources/flow/start/ +# Previous pages aliases for backwards compatibility: +- /docs/grafana-cloud/agent/flow/setup/start-agent/ +- /docs/grafana-cloud/monitor-infrastructure/agent/flow/setup/start-agent/ +- /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/setup/start-agent/ +- /docs/grafana-cloud/send-data/agent/flow/setup/start-agent/ +- ./start-agent/ # /docs/agent/latest/flow/setup/start-agent/ +canonical: https://grafana.com/docs/agent/latest/flow/setup/start/ +description: Learn how to start Grafana Agent Flow +menuTitle: Start +title: Start Grafana Agent Flow +weight: 50 +--- + +# Start {{% param "PRODUCT_NAME" %}} + +Use the following pages to learn how to start, restart, and stop {{< param "PRODUCT_NAME" >}} after it is installed. +For installation instructions, refer to [Install {{< param "PRODUCT_NAME" >}}][Install]. + +{{< section >}} + +{{% docs/reference %}} +[Install]: "/docs/agent/ -> /docs/agent//flow/setup/install/" +[Install]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/setup/install/" +{{% /docs/reference %}} diff --git a/docs/sources/flow/setup/start/binary.md b/docs/sources/flow/setup/start/binary.md new file mode 100644 index 000000000000..7d931217280a --- /dev/null +++ b/docs/sources/flow/setup/start/binary.md @@ -0,0 +1,126 @@ +--- +aliases: +- /docs/grafana-cloud/agent/flow/setup/start/binary/ +- /docs/grafana-cloud/monitor-infrastructure/agent/flow/setup/start/binary/ +- /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/setup/start/binary/ +- /docs/grafana-cloud/send-data/agent/flow/setup/start/binary/ +canonical: https://grafana.com/docs/agent/latest/flow/setup/start/binary/ +description: Learn how to start Grafana Agent Flow as a standalone binary +menuTitle: Standalone +title: Start Grafana Agent Flow as a standalone binary +weight: 600 +--- + +# Start {{% param "PRODUCT_NAME" %}} as a standalone binary + +If you [downloaded][InstallBinary] the standalone binary, you must run {{< param "PRODUCT_NAME" >}} from a terminal or command window. + +## Start {{% param "PRODUCT_NAME" %}} on Linux, macOS, or FreeBSD + +To start {{< param "PRODUCT_NAME" >}} on Linux, macOS, or FreeBSD, run the following command in a terminal window: + +```shell +AGENT_MODE=flow run +``` + +Replace the following: + +* _``_: The path to the {{< param "PRODUCT_NAME" >}} binary file. +* _``_: The path to the {{< param "PRODUCT_NAME" >}} configuration file. + +## Start {{% param "PRODUCT_NAME" %}} on Windows + +To start {{< param "PRODUCT_NAME" >}} on Windows, run the following commands in a command prompt: + +```cmd +set AGENT_MODE=flow + run +``` + +Replace the following: + +* _``_: The path to the {{< param "PRODUCT_NAME" >}} binary file. +* _``_: The path to the {{< param "PRODUCT_NAME" >}} configuration file. + +## Set up {{% param "PRODUCT_NAME" %}} as a Linux systemd service + +You can set up and manage the standalone binary for {{< param "PRODUCT_NAME" >}} as a Linux systemd service. + +{{% admonition type="note" %}} +These steps assume you have a default systemd and {{< param "PRODUCT_NAME" >}} configuration. +{{% /admonition %}} + +1. To create a new user called `grafana-agent-flow` run the following command in a terminal window: + + ```shell + sudo useradd --no-create-home --shell /bin/false grafana-agent-flow + ``` + +1. Create a service file in `/etc/systemd/system` called `grafana-agent-flow.service` with the following contents: + + ```systemd + [Unit] + Description=Vendor-neutral programmable observability pipelines. + Documentation=https://grafana.com/docs/agent/latest/flow/ + Wants=network-online.target + After=network-online.target + + [Service] + Restart=always + User=grafana-agent-flow + Environment=HOSTNAME=%H + EnvironmentFile=/etc/default/grafana-agent-flow + WorkingDirectory= + ExecStart= run $CUSTOM_ARGS --storage.path= $CONFIG_FILE + ExecReload=/usr/bin/env kill -HUP $MAINPID + TimeoutStopSec=20s + SendSIGKILL=no + + [Install] + WantedBy=multi-user.target + ``` + + Replace the following: + + * _``_: The path to the {{< param "PRODUCT_NAME" >}} binary file. + * _``_: The path to a working directory, for example `/var/lib/grafana-agent-flow`. + +1. Create an environment file in `/etc/default/` called `grafana-agent-flow` with the following contents: + + ```shell + ## Path: + ## Description: Grafana Agent Flow settings + ## Type: string + ## Default: "" + ## ServiceRestart: grafana-agent-flow + # + # Command line options for grafana-agent + # + # The configuration file holding the Grafana Agent Flow configuration. + CONFIG_FILE="" + + # User-defined arguments to pass to the run command. + CUSTOM_ARGS="" + + # Restart on system upgrade. Defaults to true. + RESTART_ON_UPGRADE=true + ``` + + Replace the following: + + * _``_: The path to the {{< param "PRODUCT_NAME" >}} configuration file. + +1. To reload the service files, run the following command in a terminal window: + + ```shell + sudo systemctl daemon-reload + ``` + +1. Use the [Linux][StartLinux] systemd commands to manage your standalone Linux installation of {{< param "PRODUCT_NAME" >}}. + +{{% docs/reference %}} +[InstallBinary]: "/docs/agent/ -> /docs/agent//flow/setup/install/binary.md" +[InstallBinary]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/flow/setup/install/binary.md" +[StartLinux]: "/docs/agent/ -> /docs/agent//flow/setup/start/linux.md" +[StartLinux]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/flow/setup/start/linux.md" +{{% /docs/reference %}} diff --git a/docs/sources/flow/setup/start/linux.md b/docs/sources/flow/setup/start/linux.md new file mode 100644 index 000000000000..673f15d2c7a1 --- /dev/null +++ b/docs/sources/flow/setup/start/linux.md @@ -0,0 +1,75 @@ +--- +aliases: + - /docs/grafana-cloud/agent/flow/setup/start/linux/ + - /docs/grafana-cloud/monitor-infrastructure/agent/flow/setup/start/linux/ + - /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/setup/start/linux/ + - /docs/grafana-cloud/send-data/agent/flow/setup/start/linux/ +canonical: https://grafana.com/docs/agent/latest/flow/setup/start/linux/ +description: Learn how to start Grafana Agent Flow on Linux +menuTitle: Linux +title: Start Grafana Agent Flow on Linux +weight: 300 +--- + +# Start {{% param "PRODUCT_NAME" %}} on Linux + +{{< param "PRODUCT_NAME" >}} is [installed][InstallLinux] as a [systemd][] service on Linux. + +[systemd]: https://systemd.io/ + +## Start {{% param "PRODUCT_NAME" %}} + +To start {{< param "PRODUCT_NAME" >}}, run the following command in a terminal window: + +```shell +sudo systemctl start grafana-agent-flow +``` + +(Optional) To verify that the service is running, run the following command in a terminal window: + +```shell +sudo systemctl status grafana-agent-flow +``` + +## Configure {{% param "PRODUCT_NAME" %}} to start at boot + +To automatically run {{< param "PRODUCT_NAME" >}} when the system starts, run the following command in a terminal window: + +```shell +sudo systemctl enable grafana-agent-flow.service +``` + +## Restart {{% param "PRODUCT_NAME" %}} + +To restart {{< param "PRODUCT_NAME" >}}, run the following command in a terminal window: + +```shell +sudo systemctl restart grafana-agent-flow +``` + +## Stop {{% param "PRODUCT_NAME" %}} + +To stop {{< param "PRODUCT_NAME" >}}, run the following command in a terminal window: + +```shell +sudo systemctl stop grafana-agent-flow +``` + +## View {{% param "PRODUCT_NAME" %}} logs on Linux + +To view {{< param "PRODUCT_NAME" >}} log files, run the following command in a terminal window: + +```shell +sudo journalctl -u grafana-agent-flow +``` + +## Next steps + +- [Configure {{< param "PRODUCT_NAME" >}}][Configure] + +{{% docs/reference %}} +[InstallLinux]: "/docs/agent/ -> /docs/agent//flow/setup/install/linux.md" +[InstallLinux]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/flow/setup/install/linux.md" +[Configure]: "/docs/agent/ -> /docs/agent//flow/tasks/configure/configure-linux.md" +[Configure]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/tasks/configure/configure-linux.md" +{{% /docs/reference %}} diff --git a/docs/sources/flow/setup/start/macos.md b/docs/sources/flow/setup/start/macos.md new file mode 100644 index 000000000000..53fe8b05b22f --- /dev/null +++ b/docs/sources/flow/setup/start/macos.md @@ -0,0 +1,69 @@ +--- +aliases: + - /docs/grafana-cloud/agent/flow/setup/start/macos/ + - /docs/grafana-cloud/monitor-infrastructure/agent/flow/setup/start/macos/ + - /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/setup/start/macos/ + - /docs/grafana-cloud/send-data/agent/flow/setup/start/macos/ +canonical: https://grafana.com/docs/agent/latest/flow/setup/start/macos/ +description: Learn how to start Grafana Agent Flow on macOS +menuTitle: macOS +title: Start Grafana Agent Flow on macOS +weight: 400 +--- + +# Start {{% param "PRODUCT_NAME" %}} on macOS + +{{< param "PRODUCT_NAME" >}} is [installed][InstallMacOS] as a launchd service on macOS. + +## Start {{% param "PRODUCT_NAME" %}} + +To start {{< param "PRODUCT_NAME" >}}, run the following command in a terminal window: + +```shell +brew services start grafana-agent-flow +``` + +{{< param "PRODUCT_NAME" >}} automatically runs when the system starts. + +(Optional) To verify that the service is running, run the following command in a terminal window: + +```shell +brew services info grafana-agent-flow +``` + +## Restart {{% param "PRODUCT_NAME" %}} + +To restart {{< param "PRODUCT_NAME" >}}, run the following command in a terminal window: + +```shell +brew services restart grafana-agent-flow +``` + +## Stop {{% param "PRODUCT_NAME" %}} + +To stop {{< param "PRODUCT_NAME" >}}, run the following command in a terminal window: + +```shell +brew services stop grafana-agent-flow +``` + +## View {{% param "PRODUCT_NAME" %}} logs on macOS + +By default, logs are written to `$(brew --prefix)/var/log/grafana-agent-flow.log` and +`$(brew --prefix)/var/log/grafana-agent-flow.err.log`. + +If you followed [Configure the {{< param "PRODUCT_NAME" >}} service][ConfigureService] and changed the path where logs are written, +refer to your current copy of the {{< param "PRODUCT_NAME" >}} formula to locate your log files. + +## Next steps + +- [Configure {{< param "PRODUCT_NAME" >}}][ConfigureMacOS] + +{{% docs/reference %}} +[InstallMacOS]: "/docs/agent/ -> /docs/agent//flow/setup/install/macos.md" +[InstallMacOS]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/flow/setup/install/macos.md" +[ConfigureMacOS]: "/docs/agent/ -> /docs/agent//flow/tasks/configure/configure-macos.md" +[ConfigureMacOS]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/tasks/configure/configure-macos.md" +[ConfigureService]: "/docs/agent/ -> /docs/agent//flow/tasks/configure/configure-macos.md#configure-the-grafana-agent-flow-service" +[ConfigureService]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/tasks/configure/configure-macos.md#configure-the-grafana-agent-flow-service" +{{% /docs/reference %}} diff --git a/docs/sources/flow/setup/start/windows.md b/docs/sources/flow/setup/start/windows.md new file mode 100644 index 000000000000..e586fa075ddc --- /dev/null +++ b/docs/sources/flow/setup/start/windows.md @@ -0,0 +1,54 @@ +--- +aliases: + - /docs/grafana-cloud/agent/flow/setup/start/windows/ + - /docs/grafana-cloud/monitor-infrastructure/agent/flow/setup/start/windows/ + - /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/setup/start/windows/ + - /docs/grafana-cloud/send-data/agent/flow/setup/start/windows/ +canonical: https://grafana.com/docs/agent/latest/flow/setup/start/windows/ +description: Learn how to start Grafana Agent Flow on Windows +menuTitle: Windows +title: Start Grafana Agent Flow on Windows +weight: 500 +--- + +# Start {{% param "PRODUCT_NAME" %}} on Windows + +{{< param "PRODUCT_NAME" >}} is [installed][InstallWindows] as a Windows Service. The service is configured to automatically run on startup. + +To verify that {{< param "PRODUCT_NAME" >}} is running as a Windows Service: + +1. Open the Windows Services manager (services.msc): + + 1. Right click on the Start Menu and select **Run**. + + 1. Type: `services.msc` and click **OK**. + +1. Scroll down to find the **{{< param "PRODUCT_NAME" >}}** service and verify that the **Status** is **Running**. + +## View {{% param "PRODUCT_NAME" %}} logs + +When running on Windows, {{< param "PRODUCT_NAME" >}} writes its logs to Windows Event +Logs with an event source name of **{{< param "PRODUCT_NAME" >}}**. + +To view the logs, perform the following steps: + +1. Open the Event Viewer: + + 1. Right click on the Start Menu and select **Run**. + + 1. Type `eventvwr` and click **OK**. + +1. In the Event Viewer, click on **Windows Logs > Application**. + +1. Search for events with the source **{{< param "PRODUCT_NAME" >}}**. + +## Next steps + +- [Configure {{< param "PRODUCT_NAME" >}}][Configure] + +{{% docs/reference %}} +[InstallWindows]: "/docs/agent/ -> /docs/agent//flow/setup/install/windows.md" +[InstallWindows]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/flow/setup/install/windows.md" +[Configure]: "/docs/agent/ -> /docs/agent//flow/tasks/configure/configure-windows.md" +[Configure]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/tasks/configure/configure-windows.md" +{{% /docs/reference %}} diff --git a/docs/sources/flow/tasks/migrate/from-prometheus.md b/docs/sources/flow/tasks/migrate/from-prometheus.md index aa106d940b3b..fae212aae6e8 100644 --- a/docs/sources/flow/tasks/migrate/from-prometheus.md +++ b/docs/sources/flow/tasks/migrate/from-prometheus.md @@ -256,8 +256,8 @@ The following list is specific to the convert command and not {{< param "PRODUCT [convert]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/reference/cli/convert.md" [run]: "/docs/agent/ -> /docs/agent//flow/reference/cli/run.md" [run]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/reference/cli/run.md" -[Start]: "/docs/agent/ -> /docs/agent//flow/setup/start-agent.md" -[Start]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/setup/start-agent.md" +[Start]: "/docs/agent/ -> /docs/agent//flow/setup/start/" +[Start]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/setup/start/" [DebuggingUI]: "/docs/agent/ -> /docs/agent//flow/tasks/debug.md" [DebuggingUI]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/tasks/debug.md" [River]: "/docs/agent/ -> /docs/agent//flow/concepts/config-language/_index.md" diff --git a/docs/sources/flow/tasks/migrate/from-promtail.md b/docs/sources/flow/tasks/migrate/from-promtail.md index 1416efea88c1..bf116e755c7b 100644 --- a/docs/sources/flow/tasks/migrate/from-promtail.md +++ b/docs/sources/flow/tasks/migrate/from-promtail.md @@ -239,8 +239,8 @@ The following list is specific to the convert command and not {{< param "PRODUCT [convert]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/reference/cli/convert.md" [run]: "/docs/agent/ -> /docs/agent//flow/reference/cli/run.md" [run]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/reference/cli/run.md" -[Start]: "/docs/agent/ -> /docs/agent//flow/setup/start-agent.md" -[Start]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/setup/start-agent.md" +[Start]: "/docs/agent/ -> /docs/agent//flow/setup/start/" +[Start]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/setup/start/" [DebuggingUI]: "/docs/agent/ -> /docs/agent//flow/tasks/debug.md" [DebuggingUI]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/tasks/debug.md" [River]: "/docs/agent/ -> /docs/agent//flow/concepts/config-language/_index.md" diff --git a/docs/sources/flow/tasks/migrate/from-static.md b/docs/sources/flow/tasks/migrate/from-static.md index a08935fff859..6f7c30d994a8 100644 --- a/docs/sources/flow/tasks/migrate/from-static.md +++ b/docs/sources/flow/tasks/migrate/from-static.md @@ -374,8 +374,8 @@ The following list is specific to the convert command and not {{< param "PRODUCT [convert]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/reference/cli/convert.md" [run]: "/docs/agent/ -> /docs/agent//flow/reference/cli/run.md" [run]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/reference/cli/run.md" -[Start]: "/docs/agent/ -> /docs/agent//flow/setup/start-agent.md" -[Start]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/setup/start-agent.md" +[Start]: "/docs/agent/ -> /docs/agent//flow/setup/start/" +[Start]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/setup/start/" [DebuggingUI]: "/docs/agent/ -> /docs/agent//flow/tasks/debug.md" [DebuggingUI]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/tasks/debug.md" [River]: "/docs/agent/ -> /docs/agent//flow/concepts/config-language/" From 3b95da44088b6e31b65f7a864c297958ce95d6c8 Mon Sep 17 00:00:00 2001 From: Robert Fratto Date: Wed, 10 Jan 2024 13:40:33 -0500 Subject: [PATCH 45/68] docs: remove reference to production/kubernetes (#6079) This commit modifies the Kubernetes installation instructions for static mode to use the Grafana Agent Helm chart instead of the abandoned production/kubernetes manifests. Related to #6077. Co-authored-by: Clayton Cornell <131809008+clayton-cornell@users.noreply.github.com> --- .../install/install-agent-kubernetes.md | 51 ++++++++++++------- 1 file changed, 32 insertions(+), 19 deletions(-) diff --git a/docs/sources/static/set-up/install/install-agent-kubernetes.md b/docs/sources/static/set-up/install/install-agent-kubernetes.md index c8df4dd8fa33..95fdd5597b53 100644 --- a/docs/sources/static/set-up/install/install-agent-kubernetes.md +++ b/docs/sources/static/set-up/install/install-agent-kubernetes.md @@ -11,40 +11,53 @@ weight: 300 # Deploy Grafana Agent in static mode on Kubernetes -You can deploy Grafana Agent in static mode on Kubernetes. +You can use the Helm chart for Grafana Agent to deploy Grafana Agent in static mode on Kubernetes. + +## Before you begin + +* Install [Helm][] on your computer. +* Configure a Kubernetes cluster that you can use for Grafana Agent. +* Configure your local Kubernetes context to point to the cluster. + +[Helm]: https://helm.sh ## Deploy -To deploy Grafana Agent in static mode on Kubernetes, perform the following steps. +{{% admonition type="note" %}} +These instructions show you how to install the generic [Helm chart](https://github.com/grafana/agent/tree/main/operations/helm/charts/grafana-agent) for Grafana Agent. +You can deploy Grafana Agent in static mode or flow mode. The Helm chart deploys flow mode by default. +{{% /admonition %}} -1. Download one of the following manifests from GitHub and save it as `manifest.yaml`: +To deploy Grafana Agent in static mode on Kubernetes using Helm, run the following commands in a terminal window: - - Metric collection (StatefulSet): [agent-bare.yaml](https://github.com/grafana/agent/blob/main/production/kubernetes/agent-bare.yaml) - - Log collection (DaemonSet): [agent-loki.yaml](https://github.com/grafana/agent/blob/main/production/kubernetes/agent-loki.yaml) - - Trace collection (Deployment): [agent-traces.yaml](https://github.com/grafana/agent/blob/main/production/kubernetes/agent-traces.yaml) +1. Add the Grafana Helm chart repository: -1. Edit the downloaded `manifest.yaml` and replace the placeholders with information relevant to your Kubernetes deployment. + ```shell + helm repo add grafana https://grafana.github.io/helm-charts + ``` -1. Apply the modified manifest file: +1. Update the Grafana Helm chart repository: ```shell - kubectl -n default apply -f manifest.yaml + helm repo update ``` -{{% admonition type="note" %}} -The manifests do not include the `ConfigMaps` which are necessary to run Grafana Agent. -{{% /admonition %}} +1. Install Grafana Agent in static mode: -For sample configuration files and detailed instructions, refer to [Configure Kubernetes Monitoring](/docs/grafana-cloud/monitor-infrastructure/kubernetes-monitoring/configuration/) in the Grafana Cloud documentation. + ```shell + helm install grafana/grafana-agent --set agent.mode=static + ``` + Replace the following: -## Rebuild the Kubernetes manifests + - _``_: The name to use for your Grafana Agent installation, such as `grafana-agent`. -The manifests provided are created using Grafana Labs' production Tanka configs with some default values. If you want to build the YAML file with some custom values, you must install the following applications: + {{% admonition type="warning" %}} + Always pass `--set agent.mode=static` in `helm install` or `helm upgrade` commands to ensure Grafana Agent gets installed in static mode. + Alternatively, set `agent.mode` to `static` in your values.yaml file. + {{% /admonition %}} -- [Tanka](https://github.com/grafana/tanka) version 0.8 or higher -- [jsonnet-bundler](https://github.com/jsonnet-bundler/jsonnet-bundler) version 0.2.1 or higher +For more information on the Grafana Agent Helm chart, refer to the Helm chart documentation on [Artifact Hub][]. -Refer to the [`template` Tanka environment](https://github.com/grafana/agent/blob/main/production/kubernetes/build/templates) for the current settings that initialize the Grafana Agent Tanka configurations. +[Artifact Hub]: https://artifacthub.io/packages/helm/grafana/grafana-agent -To build the YAML files, run the `/build/build.sh` script, or run `make example-kubernetes` from the project's root directory. From 38c8468ad881d284925c36624d53501f822e2dc8 Mon Sep 17 00:00:00 2001 From: Erik Baranowski <39704712+erikbaranowski@users.noreply.github.com> Date: Wed, 10 Jan 2024 15:02:14 -0500 Subject: [PATCH 46/68] Add a new configurable option to the windows installer for static mode for expanding env vars (#5958) * Add a new configurable option to the windows installer for static mode for expanding env vars Signed-off-by: erikbaranowski <39704712+erikbaranowski@users.noreply.github.com> * Update docs/sources/static/set-up/install/install-agent-on-windows.md Co-authored-by: Clayton Cornell <131809008+clayton-cornell@users.noreply.github.com> --------- Signed-off-by: erikbaranowski <39704712+erikbaranowski@users.noreply.github.com> Co-authored-by: Clayton Cornell <131809008+clayton-cornell@users.noreply.github.com> --- CHANGELOG.md | 4 +++ .../install/install-agent-on-windows.md | 26 +++++++++++++- .../grafana-agent/windows/install_script.nsis | 36 ++++++++++++++----- 3 files changed, 57 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8654bd9567bb..a4c13c5d97b7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,10 @@ Main (unreleased) - [GO-2023-2412](https://github.com/advisories/GHSA-7ww5-4wqc-m92c) - [CVE-2023-49568](https://github.com/advisories/GHSA-mw99-9chc-xw7r) +### Enhancements + +- Add an option to the windows static mode installer for expanding environment vars in the yaml config. (@erikbaranowski) + ### Bugfixes - Fix an issue in `remote.s3` where the exported content of an object would be an empty string if `remote.s3` failed to fully retrieve diff --git a/docs/sources/static/set-up/install/install-agent-on-windows.md b/docs/sources/static/set-up/install/install-agent-on-windows.md index 1ff2a05e61a4..ddda581a5355 100644 --- a/docs/sources/static/set-up/install/install-agent-on-windows.md +++ b/docs/sources/static/set-up/install/install-agent-on-windows.md @@ -30,7 +30,11 @@ To do a standard graphical install of Grafana Agent on Windows, perform the foll 1. Double-click on `grafana-agent-installer.exe` to install Grafana Agent. Grafana Agent is installed into the default directory `C:\Program Files\Grafana Agent`. - The [windows_exporter integration](/docs/agent/latest/static/configuration/integrations/windows-exporter-config) can be enabled with all default windows_exporter options. + + The following options are available: + + - The [windows_exporter integration][windows_exporter_config] can be enabled with all default windows_exporter options. + - The [-config.expand-env][flags] command line flag can be enabled. ## Silent install @@ -78,6 +82,24 @@ If you are using `remote_write` you must enable Windows Exporter and set the glo If you are using Powershell, make sure you use triple quotes `"""http://example.com"""` around the URL parameter. +## Silent install with `-config.expand_env` + +You can enable [-config.expand-env][flags] during a silent install. + +1. Navigate to the [latest release](https://github.com/grafana/agent/releases) on GitHub. + +1. Scroll down to the **Assets** section. + +1. Download the file called `grafana-agent-installer.exe.zip`. + +1. Unzip the downloaded file. + +1. Run the following command in PowerShell or Command Prompt: + + ```shell + PATH_TO_INSTALLER/grafana-agent-installer.exe /S /ExpandEnv true + ``` + ## Verify the installation 1. Make sure you can access `http://localhost:12345/-/healthy` and `http://localhost:12345/agent/api/v1/metrics/targets`. @@ -146,6 +168,8 @@ Refer to [windows_events](/docs/loki/latest/clients/promtail/configuration/#wind - [Configure Grafana Agent][configure] {{% docs/reference %}} +[flags]: "/docs/agent/ -> /docs/agent//static/configuration/flags" +[windows_exporter_config]: "/docs/agent/ -> /docs/agent//static/configuration/integrations/windows-exporter-config" [start]: "/docs/agent/ -> /docs/agent//static/set-up/start-agent" [start]: "/docs/grafana-cloud/ -> ../start-agent" [configure]: "/docs/agent/ -> /docs/agent//static/configuration/create-config-file" diff --git a/packaging/grafana-agent/windows/install_script.nsis b/packaging/grafana-agent/windows/install_script.nsis index 07f8986026da..b08a8216c691 100644 --- a/packaging/grafana-agent/windows/install_script.nsis +++ b/packaging/grafana-agent/windows/install_script.nsis @@ -24,17 +24,19 @@ outFile "${OUT}" LicenseData LICENSE # Everything must be global Vars +Var EnableOptionsDialog +Var PassedInParameters Var EnableExporterCheck Var EnableExporterValue -Var EnableExporterDialog -Var PassedInParameters Var Url Var Username Var Password +Var ExpandEnvCheck +Var ExpandEnvValue Page license Page directory -Page custom enableWindowsExporter enableWindowsExporterLeave +Page custom enableOptions enableOptionsLeave Page instfiles # Annoyingly macros need to be defined before use @@ -61,17 +63,18 @@ Section "install" ${GetOptions} $PassedInParameters "/Url" $Url ${GetOptions} $PassedInParameters "/Username" $Username ${GetOptions} $PassedInParameters "/Password" $Password + ${GetOptions} $PassedInParameters "/ExpandEnv" $ExpandEnvValue Call Install Return RunInstaller: Call Install SectionEnd -Function enableWindowsExporter +Function enableOptions nsDialogs::Create 1018 - Pop $EnableExporterDialog + Pop $EnableOptionsDialog - ${If} $EnableExporterDialog == error + ${If} $EnableOptionsDialog == error Abort ${EndIf} @@ -81,16 +84,29 @@ Function enableWindowsExporter ${NSD_CreateCheckBox} 0 13u 100% 12u "" Pop $EnableExporterCheck + ${NSD_CreateLabel} 0 26u 100% 12u "Expand Environment Variables" + Pop $0 + + ${NSD_CreateCheckBox} 0 39u 100% 12u "" + Pop $ExpandEnvCheck + nsDialogs::Show FunctionEnd -Function enableWindowsExporterLeave +Function enableOptionsLeave ${NSD_GetState} $EnableExporterCheck $EnableExporterValue ${If} $EnableExporterValue == ${BST_CHECKED} StrCpy $EnableExporterValue "true" ${Else} StrCpy $EnableExporterValue "false" ${EndIf} + + ${NSD_GetState} $ExpandEnvCheck $ExpandEnvValue + ${If} $ExpandEnvValue == ${BST_CHECKED} + StrCpy $ExpandEnvValue "true" + ${Else} + StrCpy $ExpandEnvValue "false" + ${EndIf} FunctionEnd Function Install @@ -128,7 +144,11 @@ Function Install nsExec::ExecToLog 'sc create "Grafana Agent" binpath= "\"$INSTDIR\grafana-agent-windows-amd64.exe\""' Pop $0 # These separate create and config commands are needed, on the config the binpath is required - nsExec::ExecToLog 'sc config "Grafana Agent" start= auto binpath= "\"$INSTDIR\grafana-agent-windows-amd64.exe\" -config.file=\"$INSTDIR\agent-config.yaml\""' + ${If} $ExpandEnvValue == "true" + nsExec::ExecToLog 'sc config "Grafana Agent" start= auto binpath= "\"$INSTDIR\grafana-agent-windows-amd64.exe\" -config.expand-env -config.file=\"$INSTDIR\agent-config.yaml\""' + ${Else} + nsExec::ExecToLog 'sc config "Grafana Agent" start= auto binpath= "\"$INSTDIR\grafana-agent-windows-amd64.exe\" -config.file=\"$INSTDIR\agent-config.yaml\""' + ${EndIf} Pop $0 nsExec::ExecToLog `sc start "Grafana Agent"` Pop $0 From 7d987dfdca9c97473e39edaaa5b59a3c44124935 Mon Sep 17 00:00:00 2001 From: Paulin Todev Date: Wed, 10 Jan 2024 20:03:33 +0000 Subject: [PATCH 47/68] Clarify usage of resource_to_telemetry_conversion (#6076) * Clarify usage of resource_to_telemetry_conversion * Apply suggestions from code review Co-authored-by: Clayton Cornell <131809008+clayton-cornell@users.noreply.github.com> --------- Co-authored-by: Clayton Cornell <131809008+clayton-cornell@users.noreply.github.com> --- .../components/otelcol.exporter.prometheus.md | 62 +++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/docs/sources/flow/reference/components/otelcol.exporter.prometheus.md b/docs/sources/flow/reference/components/otelcol.exporter.prometheus.md index 3008f22f4353..4285f34cc799 100644 --- a/docs/sources/flow/reference/components/otelcol.exporter.prometheus.md +++ b/docs/sources/flow/reference/components/otelcol.exporter.prometheus.md @@ -58,6 +58,18 @@ When `include_scope_labels` is `true` the `otel_scope_name` and When `include_target_info` is true, OpenTelemetry Collector resources are converted into `target_info` metrics. +{{% admonition type="note" %}} + +OTLP metrics can have a lot of resource attributes. +Setting `resource_to_telemetry_conversion` to `true` would convert all of them to Prometheus labels, which may not be what you want. +Instead of using `resource_to_telemetry_conversion`, most users need to use `otelcol.processor.transform` +to convert OTLP resource attributes to OTLP metric datapoint attributes before using `otelcol.exporter.prometheus`. +See [Creating Prometheus labels from OTLP resource attributes][] for an example. + +[Creating Prometheus labels from OTLP resource attributes]: #creating-prometheus-labels-from-otlp-resource-attributes + +{{% /admonition %}} + ## Exported fields The following fields are exported and can be referenced by other components: @@ -87,6 +99,8 @@ information. ## Example +## Basic usage + This example accepts metrics over OTLP and forwards it using `prometheus.remote_write`: @@ -109,6 +123,54 @@ prometheus.remote_write "mimir" { } } ``` + +## Create Prometheus labels from OTLP resource attributes + +This example uses `otelcol.processor.transform` to add extra `key1` and `key2` OTLP metric datapoint attributes from the +`key1` and `key2` OTLP resource attributes. + +`otelcol.exporter.prometheus` then converts `key1` and `key2` to Prometheus labels along with any other OTLP metric datapoint attributes. + +This avoids the need to set `resource_to_telemetry_conversion` to `true`, +which could have created too many unnecessary metric labels. + +```river +otelcol.receiver.otlp "default" { + grpc {} + + output { + metrics = [otelcol.processor.transform.default.input] + } +} + +otelcol.processor.transform "default" { + error_mode = "ignore" + + metric_statements { + context = "datapoint" + + statements = [ + `set(attributes["key1"], resource.attributes["key1"])`, + `set(attributes["key2"], resource.attributes["key2"])`, + ] + } + + output { + metrics = [otelcol.exporter.prometheus.default.input] + } +} + +otelcol.exporter.prometheus "default" { + forward_to = [prometheus.remote_write.mimir.receiver] +} + +prometheus.remote_write "mimir" { + endpoint { + url = "http://mimir:9009/api/v1/push" + } +} +``` + ## Compatible components From 7df0c05aeaa2019e3efef6c5d62c46f690d1221a Mon Sep 17 00:00:00 2001 From: Robert Fratto Date: Wed, 10 Jan 2024 15:05:44 -0500 Subject: [PATCH 48/68] docs: remove release instructions for `release` branch (#6097) The branch called `release` is an old branch created when we had Grafana Cloud install scripts and needed to update it dynamically. This branch has not been used, and there are no remaining references to it, so we can remove the branch and remove the instructions to update it. --- .../release/5-update-release-branch.md | 20 ------------------- docs/developer/release/README.md | 19 ++++++++---------- 2 files changed, 8 insertions(+), 31 deletions(-) delete mode 100644 docs/developer/release/5-update-release-branch.md diff --git a/docs/developer/release/5-update-release-branch.md b/docs/developer/release/5-update-release-branch.md deleted file mode 100644 index 2cb91166850f..000000000000 --- a/docs/developer/release/5-update-release-branch.md +++ /dev/null @@ -1,20 +0,0 @@ -# Update Release Branch - -The `release` branch is a special branch that is used for grafana cloud to point at our install scripts and example kubernetes manifests. This is not to be confused with `release-VERSION_PREFIX` created in [Create Release Branch](./1-create-release-branch.md) - -## Before you begin - -1. The release tag should exist from completing [Tag Release](./4-tag-release.md) - -## Steps - -1. Force push the release tag to the `release` branch - - ``` - git fetch - git checkout main - git branch -f release VERSION - git push -f origin refs/heads/release - ``` - - > **NOTE**: This requires force push permissions on this branch. If this fails, reach out to one of the project maintainers for help. diff --git a/docs/developer/release/README.md b/docs/developer/release/README.md index 2c87654908f3..27bba296303b 100644 --- a/docs/developer/release/README.md +++ b/docs/developer/release/README.md @@ -8,13 +8,13 @@ The processes described here are for v0.24.0 and above. # Release Cycle -A typical release cycle is to have a Release Candidate published for at least 48 +A typical release cycle is to have a Release Candidate published for at least 48 hours followed by a Stable Release. 0 or more Patch Releases may occur between the Stable Release and the creation of the next Release Candidate. # Workflows -Once a release is scheduled, a release shepherd is determined. This person will be +Once a release is scheduled, a release shepherd is determined. This person will be responsible for ownership of the following workflows: ## Release Candidate Publish @@ -39,20 +39,18 @@ responsible for ownership of the following workflows: 2. [Update Version in Code](./3-update-version-in-code.md) 3. [Tag Release](./4-tag-release.md) 4. [Publish Release](./6-publish-release.md) -5. [Update Release Branch](./5-update-release-branch.md) -6. [Test Release](./7-test-release.md) -7. [Update Helm Charts](./8-update-helm-charts.md) -8. [Announce Release](./9-announce-release.md) -9. [Update OTEL Contrib](./10-update-otel.md) +5. [Test Release](./7-test-release.md) +6. [Update Helm Charts](./8-update-helm-charts.md) +7. [Announce Release](./9-announce-release.md) +8. [Update OTEL Contrib](./10-update-otel.md) ## Patch Release Publish (latest version) 1. [Cherry Pick Commits](./2-cherry-pick-commits.md) 2. [Update Version in Code](./3-update-version-in-code.md) 3. [Tag Release](./4-tag-release.md) 4. [Publish Release](./6-publish-release.md) -5. [Update Release Branch](./5-update-release-branch.md) -6. [Update Helm Charts](./8-update-helm-charts.md) -7. [Announce Release](./9-announce-release.md) +5. [Update Helm Charts](./8-update-helm-charts.md) +6. [Announce Release](./9-announce-release.md) ## Patch Release Publish (older version) - Not documented yet (but here are some hints) @@ -61,6 +59,5 @@ responsible for ownership of the following workflows: - cherry-pick commit[s] into it - don't update the version in the project on main - changes go into the changelog under the patch release version plus stay in unreleased - - don't update the `release` branch - don't publish in github as latest release - don't update deployment tools or helm charts From ed6128e9f601f8fb59ec679894cc5a26898d6ab3 Mon Sep 17 00:00:00 2001 From: Paulin Todev Date: Wed, 10 Jan 2024 20:09:03 +0000 Subject: [PATCH 49/68] Improve the docs of pyroscope.scrape (#5847) * Clarify some aspects of pyroscope.scrape --------- Co-authored-by: Piotr <17101802+thampiotr@users.noreply.github.com> Co-authored-by: Ryan Perry --- .../reference/components/pyroscope.scrape.md | 370 ++++++++++++------ 1 file changed, 260 insertions(+), 110 deletions(-) diff --git a/docs/sources/flow/reference/components/pyroscope.scrape.md b/docs/sources/flow/reference/components/pyroscope.scrape.md index c2c54a83bfc8..74c1fa30e873 100644 --- a/docs/sources/flow/reference/components/pyroscope.scrape.md +++ b/docs/sources/flow/reference/components/pyroscope.scrape.md @@ -15,12 +15,35 @@ title: pyroscope.scrape {{< docs/shared lookup="flow/stability/beta.md" source="agent" version="" >}} -`pyroscope.scrape` configures a [pprof] scraping job for a given set of -`targets`. The scraped performance profiles are forwarded to the list of receivers passed in -`forward_to`. +`pyroscope.scrape` collects [pprof] performance profiles for a given set of HTTP `targets`. + +`pyroscope.scrape` mimcks the scraping behavior of `prometheus.scrape`. +Similarly to how Prometheus scrapes metrics via HTTP, `pyroscope.scrape` collects profiles via HTTP requests. + +Unlike Prometheus, which usually only scrapes one `/metrics` endpoint per target, +`pyroscope.scrape` may need to scrape multiple endpoints for the same target. +This is because different types of profiles are scraped on different endpoints. +For example, "mutex" profiles may be scraped on a `/debug/pprof/delta_mutex` HTTP endpoint, whereas +memory consumption may be scraped on a `/debug/pprof/allocs` HTTP endpoint. + +The profile paths, protocol scheme, scrape interval, scrape timeout, +query parameters, as well as any other settings can be configured within `pyroscope.scrape`. + +The `pyroscope.scrape` component regards a scrape as successful if it +responded with an HTTP `200 OK` status code and returned the body of a valid [pprof] profile. + +If a scrape request fails, the [debug UI][] for `pyroscope.scrape` will show: +* Detailed information about the failure. +* The time of the last successful scrape. +* The labels last used for scraping. + +The scraped performance profiles can be forwarded to components such as +`pyroscope.write` via the `forward_to` argument. Multiple `pyroscope.scrape` components can be specified by giving them different labels. +[debug UI]: {{< relref "../../tasks/debug.md" >}} + ## Usage ```river @@ -32,45 +55,106 @@ pyroscope.scrape "LABEL" { ## Arguments -The component configures and starts a new scrape job to scrape all of the -input targets. Multiple scrape jobs can be spawned for a single input target +`pyroscope.scrape` starts a new scrape job to scrape all of the input targets. +Multiple scrape jobs can be started for a single input target when scraping multiple profile types. The list of arguments that can be used to configure the block is presented below. -The scrape job name defaults to the component's unique identifier. - -Any omitted fields take on their default values. If conflicting -attributes are being passed (e.g., defining both a BearerToken and -BearerTokenFile or configuring both Basic Authorization and OAuth2 at the same -time), the component reports an error. +Any omitted arguments take on their default values. If conflicting +arguments are being passed (for example, configuring both `bearer_token` +and `bearer_token_file`), then `pyroscope.scrape` will fail to start and will report an error. The following arguments are supported: -Name | Type | Description | Default | Required ----- | ---- | ----------- | ------- | -------- -`targets` | `list(map(string))` | List of targets to scrape. | | yes -`forward_to` | `list(ProfilesReceiver)` | List of receivers to send scraped profiles to. | | yes -`job_name` | `string` | The job name to override the job label with. | component name | no -`params` | `map(list(string))` | A set of query parameters with which the target is scraped. | | no -`scrape_interval` | `duration` | How frequently to scrape the targets of this scrape configuration. | `"15s"` | no -`scrape_timeout` | `duration` | The timeout for scraping targets of this configuration. | `"15s"` | no -`scheme` | `string` | The URL scheme with which to fetch metrics from targets. | | no -`bearer_token` | `secret` | Bearer token to authenticate with. | | no -`bearer_token_file` | `string` | File containing a bearer token to authenticate with. | | no -`proxy_url` | `string` | HTTP proxy to proxy requests through. | | no -`follow_redirects` | `bool` | Whether redirects returned by the server should be followed. | `true` | no -`enable_http2` | `bool` | Whether HTTP2 is supported for requests. | `true` | no - - At most one of the following can be provided: +Name | Type | Description | Default | Required +------------------- | ------------------------ | ------------------------------------------------------------------ | -------------- | -------- +`targets` | `list(map(string))` | List of targets to scrape. | | yes +`forward_to` | `list(ProfilesReceiver)` | List of receivers to send scraped profiles to. | | yes +`job_name` | `string` | The job name to override the job label with. | component name | no +`params` | `map(list(string))` | A set of query parameters with which the target is scraped. | | no +`scrape_interval` | `duration` | How frequently to scrape the targets of this scrape configuration. | `"15s"` | no +`scrape_timeout` | `duration` | The timeout for scraping targets of this configuration. Must be larger than `scrape_interval`. | `"18s"` | no +`scheme` | `string` | The URL scheme with which to fetch metrics from targets. | `"http"` | no +`bearer_token` | `secret` | Bearer token to authenticate with. | | no +`bearer_token_file` | `string` | File containing a bearer token to authenticate with. | | no +`proxy_url` | `string` | HTTP proxy to proxy requests through. | | no +`follow_redirects` | `bool` | Whether redirects returned by the server should be followed. | `true` | no +`enable_http2` | `bool` | Whether HTTP2 is supported for requests. | `true` | no + +At most one of the following authentication mechanisms can be provided: - [`bearer_token` argument](#arguments). - [`bearer_token_file` argument](#arguments). - [`basic_auth` block][basic_auth]. - [`authorization` block][authorization]. - [`oauth2` block][oauth2]. - [arguments]: #arguments +[arguments]: #arguments + +#### `job_name` argument + +`job_name` defaults to the component's unique identifier. + +For example, the `job_name` of `pyroscope.scrape "local" { ... }` will be `"pyroscope.scrape.local"`. + +#### `targets` argument + +The list of `targets` can be provided [statically][example_static_targets], [dynamically][example_dynamic_targets], +or a [combination of both][example_static_and_dynamic_targets]. + +The special `__address__` label _must always_ be present and corresponds to the +`:` that is used for the scrape request. + +Labels starting with a double underscore (`__`) are treated as _internal_, and are removed prior to scraping. + +The special label `service_name` is required and must always be present. +If it is not specified, `pyroscope.scrape` will attempt to infer it from +either of the following sources, in this order: +1. `__meta_kubernetes_pod_annotation_pyroscope_io_service_name` which is a `pyroscope.io/service_name` pod annotation. +2. `__meta_kubernetes_namespace` and `__meta_kubernetes_pod_container_name` +3. `__meta_docker_container_name` + +If `service_name` is not specified and could not be inferred, then it is set to `unspecified`. + +The following labels are automatically injected to the scraped profiles +so that they can be linked to a scrape target: + +| Label | Description | +|------------------|----------------------------------------------------------------- | +| `"job"` | The `job_name` that the target belongs to. | +| `"instance"` | The `__address__` or `:` of the scrape target's URL. | +| `"service_name"` | The inferred Pyroscope service name. | + +#### `scrape_interval` argument + +The `scrape_interval` typically refers to the frequency with which {{< param "PRODUCT_NAME" >}} collects performance profiles from the monitored targets. +It represents the time interval between consecutive scrapes or data collection events. +This parameter is important for controlling the trade-off between resource usage and the freshness of the collected data. + +If `scrape_interval` is short: +* Advantages: + * Fewer profiles may be lost if the application being scraped crashes. +* Disadvantages: + * Greater consumption of CPU, memory, and network resources during scrapes and remote writes. + * The backend database (Pyroscope) will consume more storage space. + +If `scrape_interval` is long: +* Advantages: + * Lower resource consumption. +* Disadvantages: + * More profiles may be lost if the application being scraped crashes. + * If the [delta argument][] is set to `true`, the batch size of + each remote write to Pyroscope may be bigger. + The Pyroscope database may need to be tuned with higher limits. + * If the [delta argument][] is set to `true`, there is a larger risk of + reaching the HTTP server timeouts of the application being scraped. + +For example, consider this situation: +* `pyroscope.scrape` is configured with a `scrape_interval` of `"60s"`. +* The application being scraped is running an HTTP server with a timeout of 30 seconds. +* Any scrape HTTP requests where the [delta argument][] is set to `true` will fail, + because they will attempt to run for 59 seconds. ## Blocks @@ -92,7 +176,7 @@ The following blocks are supported inside the definition of `pyroscope.scrape`: | profiling_config > profile.fgprof | [profile.fgprof][] | Collect [fgprof][] profiles. | no | | profiling_config > profile.godeltaprof_memory | [profile.godeltaprof_memory][] | Collect [godeltaprof][] memory profiles. | no | | profiling_config > profile.godeltaprof_mutex | [profile.godeltaprof_mutex][] | Collect [godeltaprof][] mutex profiles. | no | -| profiling_config > profile.godeltaprof_block | [profile.godeltaprof_block][] | Collect [godeltaprof][] block profiles. | no | +| profiling_config > profile.godeltaprof_block | [profile.godeltaprof_block][] | Collect [godeltaprof][] block profiles. | no | | profiling_config > profile.custom | [profile.custom][] | Collect custom profiles. | no | | clustering | [clustering][] | Configure the component for when {{< param "PRODUCT_NAME" >}} is running in clustered mode. | no | @@ -100,26 +184,32 @@ The `>` symbol indicates deeper levels of nesting. For example, `oauth2 > tls_config` refers to a `tls_config` block defined inside an `oauth2` block. +Any omitted blocks take on their default values. For example, +if `profile.mutex` is not specified in the config, +the defaults documented in [profile.mutex][] will be used. + [basic_auth]: #basic_auth-block [authorization]: #authorization-block [oauth2]: #oauth2-block [tls_config]: #tls_config-block [profiling_config]: #profiling_config-block -[profile.memory]: #profile.memory-block -[profile.block]: #profile.block-block -[profile.goroutine]: #profile.goroutine-block -[profile.mutex]: #profile.mutex-block -[profile.process_cpu]: #profile.process_cpu-block -[profile.fgprof]: #profile.fgprof-block -[profile.godeltaprof_memory]: #profile.godeltaprof_memory-block -[profile.godeltaprof_mutex]: #profile.godeltaprof_mutex-block -[profile.godeltaprof_block]: #profile.godeltaprof_block-block -[profile.custom]: #profile.custom-block +[profile.memory]: #profilememory-block +[profile.block]: #profileblock-block +[profile.goroutine]: #profilegoroutine-block +[profile.mutex]: #profilemutex-block +[profile.process_cpu]: #profileprocess_cpu-block +[profile.fgprof]: #profilefgprof-block +[profile.godeltaprof_memory]: #profilegodeltaprof_memory-block +[profile.godeltaprof_mutex]: #profilegodeltaprof_mutex-block +[profile.godeltaprof_block]: #profilegodeltaprof_block-block +[profile.custom]: #profilecustom-block [pprof]: https://github.com/google/pprof/blob/main/doc/README.md [clustering]: #clustering-beta [fgprof]: https://github.com/felixge/fgprof -[godeltaprof]: https://github.com/grafana/godeltaprof +[godeltaprof]: https://github.com/grafana/pyroscope-go/tree/main/godeltaprof + +[delta argument]: #delta-argument ### basic_auth block @@ -142,7 +232,7 @@ an `oauth2` block. The `profiling_config` block configures the profiling settings when scraping targets. -The block contains the following attributes: +The following arguments are supported: Name | Type | Description | Default | Required ---- | ---- | ----------- | ------- | -------- @@ -152,7 +242,7 @@ Name | Type | Description | Default | Required The `profile.memory` block collects profiles on memory consumption. -It accepts the following arguments: +The following arguments are supported: Name | Type | Description | Default | Required ---- | ---- | ----------- | ------- | -------- @@ -160,14 +250,13 @@ Name | Type | Description | Default | Required `path` | `string` | The path to the profile type on the target. | `"/debug/pprof/allocs"` | no `delta` | `boolean` | Whether to scrape the profile as a delta. | `false` | no -When the `delta` argument is `true`, a `seconds` query parameter is -automatically added to requests. +For more information about the `delta` argument, see the [delta argument][] section. ### profile.block block The `profile.block` block collects profiles on process blocking. -It accepts the following arguments: +The following arguments are supported: Name | Type | Description | Default | Required ---- | ---- | ----------- | ------- | -------- @@ -175,14 +264,13 @@ Name | Type | Description | Default | Required `path` | `string` | The path to the profile type on the target. | `"/debug/pprof/block"` | no `delta` | `boolean` | Whether to scrape the profile as a delta. | `false` | no -When the `delta` argument is `true`, a `seconds` query parameter is -automatically added to requests. +For more information about the `delta` argument, see the [delta argument][] section. ### profile.goroutine block The `profile.goroutine` block collects profiles on the number of goroutines. -It accepts the following arguments: +The following arguments are supported: Name | Type | Description | Default | Required ---- | ---- | ----------- | ------- | -------- @@ -190,14 +278,13 @@ Name | Type | Description | Default | Required `path` | `string` | The path to the profile type on the target. | `"/debug/pprof/goroutine"` | no `delta` | `boolean` | Whether to scrape the profile as a delta. | `false` | no -When the `delta` argument is `true`, a `seconds` query parameter is -automatically added to requests. +For more information about the `delta` argument, see the [delta argument][] section. ### profile.mutex block The `profile.mutex` block collects profiles on mutexes. -It accepts the following arguments: +The following arguments are supported: Name | Type | Description | Default | Required ---- | ---- | ----------- | ------- | -------- @@ -205,15 +292,14 @@ Name | Type | Description | Default | Required `path` | `string` | The path to the profile type on the target. | `"/debug/pprof/mutex"` | no `delta` | `boolean` | Whether to scrape the profile as a delta. | `false` | no -When the `delta` argument is `true`, a `seconds` query parameter is -automatically added to requests. +For more information about the `delta` argument, see the [delta argument][] section. ### profile.process_cpu block The `profile.process_cpu` block collects profiles on CPU consumption for the process. -It accepts the following arguments: +The following arguments are supported: Name | Type | Description | Default | Required ---- | ---- | ----------- | ------- | -------- @@ -221,14 +307,13 @@ Name | Type | Description | Default | Required `path` | `string` | The path to the profile type on the target. | `"/debug/pprof/profile"` | no `delta` | `boolean` | Whether to scrape the profile as a delta. | `true` | no -When the `delta` argument is `true`, a `seconds` query parameter is -automatically added to requests. +For more information about the `delta` argument, see the [delta argument][] section. ### profile.fgprof block The `profile.fgprof` block collects profiles from an [fgprof][] endpoint. -It accepts the following arguments: +The following arguments are supported: Name | Type | Description | Default | Required ---- | ---- | ----------- | ------- | -------- @@ -236,14 +321,13 @@ Name | Type | Description | Default | Required `path` | `string` | The path to the profile type on the target. | `"/debug/fgprof"` | no `delta` | `boolean` | Whether to scrape the profile as a delta. | `true` | no -When the `delta` argument is `true`, a `seconds` query parameter is -automatically added to requests. +For more information about the `delta` argument, see the [delta argument][] section. ### profile.godeltaprof_memory block The `profile.godeltaprof_memory` block collects profiles from [godeltaprof][] memory endpoint. The delta is computed on the target. -It accepts the following arguments: +The following arguments are supported: | Name | Type | Description | Default | Required | |-----------|-----------|---------------------------------------------|-----------------------------|----------| @@ -254,7 +338,7 @@ It accepts the following arguments: The `profile.godeltaprof_mutex` block collects profiles from [godeltaprof][] mutex endpoint. The delta is computed on the target. -It accepts the following arguments: +The following arguments are supported: | Name | Type | Description | Default | Required | |-----------|-----------|---------------------------------------------|------------------------------|----------| @@ -265,7 +349,7 @@ It accepts the following arguments: The `profile.godeltaprof_block` block collects profiles from [godeltaprof][] block endpoint. The delta is computed on the target. -It accepts the following arguments: +The following arguments are supported: | Name | Type | Description | Default | Required | |-----------|-----------|---------------------------------------------|------------------------------|----------| @@ -288,7 +372,7 @@ profile.custom "PROFILE_TYPE" { Multiple `profile.custom` blocks can be specified. Labels assigned to `profile.custom` blocks must be unique across the component. -The `profile.custom` block accepts the following arguments: +The following arguments are supported: Name | Type | Description | Default | Required ---- | ---- | ----------- | ------- | -------- @@ -297,7 +381,7 @@ Name | Type | Description | Default | Required `delta` | `boolean` | Whether to scrape the profile as a delta. | `false` | no When the `delta` argument is `true`, a `seconds` query parameter is -automatically added to requests. +automatically added to requests. The `seconds` used will be equal to `scrape_interval - 1`. ### clustering (beta) @@ -322,6 +406,19 @@ If {{< param "PRODUCT_NAME" >}} is _not_ running in clustered mode, this block i [using clustering]: {{< relref "../../concepts/clustering.md" >}} +## Common configuration + +### `delta` argument + +When the `delta` argument is `false`, the [pprof][] HTTP query will be instantaneous. + +When the `delta` argument is `true`: +* The [pprof][] HTTP query will run for a certain amount of time. +* A `seconds` parameter is automatically added to the HTTP request. +* The `seconds` used will be equal to `scrape_interval - 1`. + For example, if `scrape_interval` is `"15s"`, `seconds` will be 14 seconds. + If the HTTP endpoint is `/debug/pprof/profile`, then the HTTP query will become `/debug/pprof/profile?seconds=14` + ## Exported fields `pyroscope.scrape` does not export any fields that can be referenced by other @@ -341,67 +438,115 @@ scrape job on the component's debug endpoint. * `pyroscope_fanout_latency` (histogram): Write latency for sending to direct and indirect components. -## Scraping behavior +## Examples -The `pyroscope.scrape` component borrows the scraping behavior of Prometheus. -Prometheus, and by extension, this component, uses a pull model for scraping -profiles from a given set of _targets_. -Each scrape target is defined as a set of key-value pairs called _labels_. +[example_static_targets]: #default-endpoints-of-static-targets -The set of targets can either be _static_, or dynamically provided periodically -by a service discovery component such as `discovery.kubernetes`. The special -label `__address__` _must always_ be present and corresponds to the -`:` that is used for the scrape request. +### Default endpoints of static targets -The special label `service_name` is required and must always be present. If it's not specified, it is -attempted to be inferred from multiple sources: -- `__meta_kubernetes_pod_annotation_pyroscope_io_service_name` which is a `pyroscope.io/service_name` pod annotation. -- `__meta_kubernetes_namespace` and `__meta_kubernetes_pod_container_name` -- `__meta_docker_container_name` +The following example sets up a scrape job of a statically configured +list of targets - {{< param "PRODUCT_ROOT_NAME" >}} itself and Pyroscope. +The scraped profiles are sent to `pyroscope.write` which remote writes them to a Pyroscope database. -If `service_name` is not specified and could not be inferred it is set to `unspecified`. +```river +pyroscope.scrape "local" { + targets = [ + {"__address__" = "localhost:4100", "service_name"="pyroscope"}, + {"__address__" = "localhost:12345", "service_name"="agent"}, + ] -By default, the scrape job tries to scrape all available targets' `/debug/pprof` -endpoints using HTTP, with a scrape interval of 15 seconds and scrape timeout of -15 seconds. The profile paths, protocol scheme, scrape interval and timeout, -query parameters, as well as any other settings can be configured using the -component's arguments. + forward_to = [pyroscope.write.local.receiver] +} -The scrape job expects profiles exposed by the endpoint to follow the -[pprof] protobuf format. All profiles are then propagated -to each receiver listed in the component's `forward_to` argument. +pyroscope.write "local" { + endpoint { + url = "http://pyroscope:4100" + } +} +``` -Labels coming from targets, that start with a double underscore `__` are -treated as _internal_, and are removed prior to scraping. +These endpoints will be scraped every 15 seconds: -The `pyroscope.scrape` component regards a scrape as successful if it -responded with an HTTP `200 OK` status code and returned a body of valid [pprof] profile. +``` +http://localhost:4100/debug/pprof/allocs +http://localhost:4100/debug/pprof/block +http://localhost:4100/debug/pprof/goroutine +http://localhost:4100/debug/pprof/mutex +http://localhost:4100/debug/pprof/profile?seconds=14 + +http://localhost:12345/debug/pprof/allocs +http://localhost:12345/debug/pprof/block +http://localhost:12345/debug/pprof/goroutine +http://localhost:12345/debug/pprof/mutex +http://localhost:12345/debug/pprof/profile?seconds=14 +``` + +Note that `seconds=14` is added to the `/debug/pprof/profile` endpoint, because: +* The `delta` argument of the `profile.process_cpu` block is `true` by default. +* `scrape_interval` is `"15s"` by default. -If the scrape request fails, the component's debug UI section contains more -detailed information about the failure, the last successful scrape, as well as -the labels last used for scraping. +Also note that the `/debug/fgprof` endpoint will not be scraped, because +the `enabled` argument of the `profile.fgprof` block is `false` by default. -The following labels are automatically injected to the scraped profiles and -can help pin down a scrape target. +[example_dynamic_targets]: #default-endpoints-of-dynamic-targets -| Label | Description | -|--------------|--------------------------------------------------------------------------------------------------| -| job | The configured job name that the target belongs to. Defaults to the fully formed component name. | -| instance | The `__address__` or `:` of the scrape target's URL. | -| service_name | The inferred pyroscope service name | +### Default endpoints of dynamic targets + +```river +discovery.http "dynamic_targets" { + url = "https://example.com/scrape_targets" + refresh_interval = "15s" +} + +pyroscope.scrape "local" { + targets = [discovery.http.dynamic_targets.targets] + + forward_to = [pyroscope.write.local.receiver] +} + +pyroscope.write "local" { + endpoint { + url = "http://pyroscope:4100" + } +} +``` -## Example +[example_static_and_dynamic_targets]: #default-endpoints-of-static-and-dynamic-targets -The following example sets up the scrape job with certain attributes (profiling configuration, targets) and lets it scrape two local applications ({{< param "PRODUCT_ROOT_NAME" >}} itself and Pyroscope). -The exposed profiles are sent over to the provided list of receivers, as defined by other components. +### Default endpoints of static and dynamic targets ```river +discovery.http "dynamic_targets" { + url = "https://example.com/scrape_targets" + refresh_interval = "15s" +} + pyroscope.scrape "local" { - targets = [ + targets = [ {"__address__" = "localhost:4100", "service_name"="pyroscope"}, {"__address__" = "localhost:12345", "service_name"="agent"}, + discovery.http.dynamic_targets.targets, ] + forward_to = [pyroscope.write.local.receiver] +} + +pyroscope.write "local" { + endpoint { + url = "http://pyroscope:4100" + } +} +``` + + +### Enabling and disabling profiles + +```river +pyroscope.scrape "local" { + targets = [ + {"__address__" = "localhost:12345", "service_name"="agent"}, + ] + profiling_config { profile.fgprof { enabled = true @@ -413,22 +558,27 @@ pyroscope.scrape "local" { enabled = false } } + + forward_to = [pyroscope.write.local.receiver] } ``` -Here are the endpoints that are being scraped every 15 seconds: +These endpoints will be scraped every 15 seconds: ``` -http://localhost:4100/debug/pprof/allocs -http://localhost:4100/debug/pprof/goroutine -http://localhost:4100/debug/pprof/profile?seconds=14 -http://localhost:4100/debug/fgprof?seconds=14 http://localhost:12345/debug/pprof/allocs http://localhost:12345/debug/pprof/goroutine http://localhost:12345/debug/pprof/profile?seconds=14 http://localhost:12345/debug/fgprof?seconds=14 ``` +These endpoints will **NOT** be scraped because they are explicitly disabled: + +``` +http://localhost:12345/debug/pprof/block +http://localhost:12345/debug/pprof/mutex +``` + ## Compatible components From ee98c5fe90e990f9740e9349028d234be8ee877b Mon Sep 17 00:00:00 2001 From: Paschalis Tsilias Date: Wed, 10 Jan 2024 22:30:10 +0200 Subject: [PATCH 50/68] loki.process: document limitation of stage.json (#6082) * loki.process: document limitation of stage.json Signed-off-by: Paschalis Tsilias * Add example error for future grepping Signed-off-by: Paschalis Tsilias * Apply Clayton's suggestions Signed-off-by: Paschalis Tsilias --------- Signed-off-by: Paschalis Tsilias Co-authored-by: Clayton Cornell <131809008+clayton-cornell@users.noreply.github.com> --- .../flow/reference/components/loki.process.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/docs/sources/flow/reference/components/loki.process.md b/docs/sources/flow/reference/components/loki.process.md index c2793abbfe2e..d1c8ef723bd9 100644 --- a/docs/sources/flow/reference/components/loki.process.md +++ b/docs/sources/flow/reference/components/loki.process.md @@ -382,6 +382,20 @@ following key-value pair to the set of extracted data. username: agent ``` +{{% admonition type="note" %}} +Due to a limitation of the upstream jmespath library, you must wrap any string +that contains a hyphen `-` in quotes so that it's not considered a numerical +expression. + +If you don't use quotes to wrap a string that contains a hyphen, you will get +errors like: `Unexpected token at the end of the expression: tNumber` + +You can use one of two options to circumvent this issue: + +1. An escaped double quote. For example: `http_user_agent = "\"request_User-Agent\""` +1. A backtick quote. For example: ``http_user_agent = `"request_User-Agent"` `` +{{% /admonition %}} + ### stage.label_drop block The `stage.label_drop` inner block configures a processing stage that drops labels From d226a0e7e733dd5a1793a1f39d352457f106e48c Mon Sep 17 00:00:00 2001 From: Robert Fratto Date: Wed, 10 Jan 2024 17:25:28 -0500 Subject: [PATCH 51/68] misc: remove production/ in favor of operations/ (#6107) This commit entirely removes the production/ folder in favor of operations/; all known valid external references to the old production folder have been removed. Closes #6077. --- .drone/drone.yml | 20 +- .drone/pipelines/test.jsonnet | 17 - Makefile | 12 +- .../grafana/dashboards/template.jsonnet | 4 +- example/docker-compose/jsonnetfile.json | 2 +- example/docker-compose/jsonnetfile.lock.json | 2 +- production/README.md | 1 - .../grafana-agent-mixin/alerts.libsonnet | 414 - .../grafana-agent-mixin/config.libsonnet | 13 - .../grafana-agent-mixin/dashboards.libsonnet | 789 -- .../grafana-agent-mixin/debugging.libsonnet | 128 - .../grafana-agent-mixin/jsonnetfile.json | 25 - .../grafana-agent-mixin/mixin.libsonnet | 4 - .../grafana-agent-mixin/utils.libsonnet | 34 - production/kubernetes/README.md | 50 - production/kubernetes/agent-bare.yaml | 115 - production/kubernetes/agent-loki.yaml | 100 - production/kubernetes/agent-traces.yaml | 154 - production/kubernetes/build/build.sh | 15 - production/kubernetes/build/jsonnetfile.json | 49 - .../kubernetes/build/jsonnetfile.lock.json | 74 - production/kubernetes/build/lib/k.libsonnet | 1 - .../kubernetes/build/lib/version.libsonnet | 1 - .../build/templates/bare/main.jsonnet | 41 - .../kubernetes/build/templates/bare/spec.json | 11 - .../build/templates/base-sigv4/main.jsonnet | 31 - .../build/templates/base-sigv4/spec.json | 11 - .../build/templates/base/main.jsonnet | 23 - .../kubernetes/build/templates/base/spec.json | 11 - .../build/templates/loki/main.jsonnet | 17 - .../kubernetes/build/templates/loki/spec.json | 11 - .../build/templates/operator/main.jsonnet | 160 - .../build/templates/operator/spec.json | 11 - .../build/templates/traces/main.jsonnet | 41 - .../build/templates/traces/spec.json | 11 - production/kubernetes/install-bare.sh | 34 - .../monitoring.coreos.com_podmonitors.yaml | 679 -- .../crds/monitoring.coreos.com_probes.yaml | 722 -- ...monitoring.coreos.com_servicemonitors.yaml | 709 -- .../monitoring.grafana.com_grafanaagents.yaml | 7795 ----------------- .../monitoring.grafana.com_integrations.yaml | 1738 ---- .../monitoring.grafana.com_logsinstances.yaml | 500 -- ...nitoring.grafana.com_metricsinstances.yaml | 861 -- .../crds/monitoring.grafana.com_podlogs.yaml | 588 -- .../operator/templates/agent-operator.yaml | 645 -- .../grafana-agent-operator/jsonnetfile.json | 34 - .../grafana-agent-operator/operator.libsonnet | 60 - .../util/grafana-agent.libsonnet | 23 - .../util/integrations.libsonnet | 17 - .../util/k8slogs.libsonnet | 33 - .../util/k8smonitors.libsonnet | 56 - .../util/logsinstance.libsonnet | 21 - .../util/metricsinstance.libsonnet | 20 - .../tanka/grafana-agent/config.libsonnet | 117 - .../grafana-agent/grafana-agent.libsonnet | 85 - .../tanka/grafana-agent/jsonnetfile.json | 14 - .../grafana-agent/scraping-svc/main.libsonnet | 107 - .../scraping-svc/syncer.libsonnet | 61 - .../smoke/avalanche/main.libsonnet | 49 - .../grafana-agent/smoke/crow/main.libsonnet | 36 - .../grafana-agent/smoke/etcd/main.libsonnet | 30 - .../tanka/grafana-agent/smoke/main.libsonnet | 69 - production/tanka/grafana-agent/v1/README.md | 79 - .../grafana-agent/v1/internal/agent.libsonnet | 72 - .../v1/internal/kubernetes_instance.libsonnet | 27 - .../v1/internal/kubernetes_logs.libsonnet | 7 - .../grafana-agent/v1/internal/utils.libsonnet | 36 - .../grafana-agent/v1/lib/deployment.libsonnet | 83 - .../v1/lib/integrations.libsonnet | 33 - .../tanka/grafana-agent/v1/lib/logs.libsonnet | 82 - .../grafana-agent/v1/lib/metrics.libsonnet | 116 - .../v1/lib/scraping_service.libsonnet | 4 - .../grafana-agent/v1/lib/traces.libsonnet | 121 - .../tanka/grafana-agent/v1/main.libsonnet | 142 - production/tanka/grafana-agent/v2/README.md | 84 - .../grafana-agent/v2/internal/base.libsonnet | 56 - .../internal/controllers/daemonset.libsonnet | 22 - .../internal/controllers/deployment.libsonnet | 22 - .../controllers/statefulset.libsonnet | 23 - .../v2/internal/helpers/k8s.libsonnet | 523 -- .../v2/internal/helpers/logs.libsonnet | 27 - .../v2/internal/helpers/service.libsonnet | 13 - .../v2/internal/syncer.libsonnet | 62 - .../tanka/grafana-agent/v2/main.libsonnet | 50 - tools/generate-crds.bash | 12 +- 85 files changed, 13 insertions(+), 19189 deletions(-) delete mode 100644 production/README.md delete mode 100644 production/grafana-agent-mixin/alerts.libsonnet delete mode 100644 production/grafana-agent-mixin/config.libsonnet delete mode 100644 production/grafana-agent-mixin/dashboards.libsonnet delete mode 100644 production/grafana-agent-mixin/debugging.libsonnet delete mode 100644 production/grafana-agent-mixin/jsonnetfile.json delete mode 100644 production/grafana-agent-mixin/mixin.libsonnet delete mode 100644 production/grafana-agent-mixin/utils.libsonnet delete mode 100644 production/kubernetes/README.md delete mode 100644 production/kubernetes/agent-bare.yaml delete mode 100644 production/kubernetes/agent-loki.yaml delete mode 100644 production/kubernetes/agent-traces.yaml delete mode 100755 production/kubernetes/build/build.sh delete mode 100644 production/kubernetes/build/jsonnetfile.json delete mode 100644 production/kubernetes/build/jsonnetfile.lock.json delete mode 100644 production/kubernetes/build/lib/k.libsonnet delete mode 100644 production/kubernetes/build/lib/version.libsonnet delete mode 100644 production/kubernetes/build/templates/bare/main.jsonnet delete mode 100644 production/kubernetes/build/templates/bare/spec.json delete mode 100644 production/kubernetes/build/templates/base-sigv4/main.jsonnet delete mode 100644 production/kubernetes/build/templates/base-sigv4/spec.json delete mode 100644 production/kubernetes/build/templates/base/main.jsonnet delete mode 100644 production/kubernetes/build/templates/base/spec.json delete mode 100644 production/kubernetes/build/templates/loki/main.jsonnet delete mode 100644 production/kubernetes/build/templates/loki/spec.json delete mode 100644 production/kubernetes/build/templates/operator/main.jsonnet delete mode 100644 production/kubernetes/build/templates/operator/spec.json delete mode 100644 production/kubernetes/build/templates/traces/main.jsonnet delete mode 100644 production/kubernetes/build/templates/traces/spec.json delete mode 100644 production/kubernetes/install-bare.sh delete mode 100644 production/operator/crds/monitoring.coreos.com_podmonitors.yaml delete mode 100644 production/operator/crds/monitoring.coreos.com_probes.yaml delete mode 100644 production/operator/crds/monitoring.coreos.com_servicemonitors.yaml delete mode 100644 production/operator/crds/monitoring.grafana.com_grafanaagents.yaml delete mode 100644 production/operator/crds/monitoring.grafana.com_integrations.yaml delete mode 100644 production/operator/crds/monitoring.grafana.com_logsinstances.yaml delete mode 100644 production/operator/crds/monitoring.grafana.com_metricsinstances.yaml delete mode 100644 production/operator/crds/monitoring.grafana.com_podlogs.yaml delete mode 100644 production/operator/templates/agent-operator.yaml delete mode 100644 production/tanka/grafana-agent-operator/jsonnetfile.json delete mode 100644 production/tanka/grafana-agent-operator/operator.libsonnet delete mode 100644 production/tanka/grafana-agent-operator/util/grafana-agent.libsonnet delete mode 100644 production/tanka/grafana-agent-operator/util/integrations.libsonnet delete mode 100644 production/tanka/grafana-agent-operator/util/k8slogs.libsonnet delete mode 100644 production/tanka/grafana-agent-operator/util/k8smonitors.libsonnet delete mode 100644 production/tanka/grafana-agent-operator/util/logsinstance.libsonnet delete mode 100644 production/tanka/grafana-agent-operator/util/metricsinstance.libsonnet delete mode 100644 production/tanka/grafana-agent/config.libsonnet delete mode 100644 production/tanka/grafana-agent/grafana-agent.libsonnet delete mode 100644 production/tanka/grafana-agent/jsonnetfile.json delete mode 100644 production/tanka/grafana-agent/scraping-svc/main.libsonnet delete mode 100644 production/tanka/grafana-agent/scraping-svc/syncer.libsonnet delete mode 100644 production/tanka/grafana-agent/smoke/avalanche/main.libsonnet delete mode 100644 production/tanka/grafana-agent/smoke/crow/main.libsonnet delete mode 100644 production/tanka/grafana-agent/smoke/etcd/main.libsonnet delete mode 100644 production/tanka/grafana-agent/smoke/main.libsonnet delete mode 100644 production/tanka/grafana-agent/v1/README.md delete mode 100644 production/tanka/grafana-agent/v1/internal/agent.libsonnet delete mode 100644 production/tanka/grafana-agent/v1/internal/kubernetes_instance.libsonnet delete mode 100644 production/tanka/grafana-agent/v1/internal/kubernetes_logs.libsonnet delete mode 100644 production/tanka/grafana-agent/v1/internal/utils.libsonnet delete mode 100644 production/tanka/grafana-agent/v1/lib/deployment.libsonnet delete mode 100644 production/tanka/grafana-agent/v1/lib/integrations.libsonnet delete mode 100644 production/tanka/grafana-agent/v1/lib/logs.libsonnet delete mode 100644 production/tanka/grafana-agent/v1/lib/metrics.libsonnet delete mode 100644 production/tanka/grafana-agent/v1/lib/scraping_service.libsonnet delete mode 100644 production/tanka/grafana-agent/v1/lib/traces.libsonnet delete mode 100644 production/tanka/grafana-agent/v1/main.libsonnet delete mode 100644 production/tanka/grafana-agent/v2/README.md delete mode 100644 production/tanka/grafana-agent/v2/internal/base.libsonnet delete mode 100644 production/tanka/grafana-agent/v2/internal/controllers/daemonset.libsonnet delete mode 100644 production/tanka/grafana-agent/v2/internal/controllers/deployment.libsonnet delete mode 100644 production/tanka/grafana-agent/v2/internal/controllers/statefulset.libsonnet delete mode 100644 production/tanka/grafana-agent/v2/internal/helpers/k8s.libsonnet delete mode 100644 production/tanka/grafana-agent/v2/internal/helpers/logs.libsonnet delete mode 100644 production/tanka/grafana-agent/v2/internal/helpers/service.libsonnet delete mode 100644 production/tanka/grafana-agent/v2/internal/syncer.libsonnet delete mode 100644 production/tanka/grafana-agent/v2/main.libsonnet diff --git a/.drone/drone.yml b/.drone/drone.yml index 43e4161ef322..b65be33159f8 100644 --- a/.drone/drone.yml +++ b/.drone/drone.yml @@ -119,24 +119,6 @@ trigger: type: docker --- kind: pipeline -name: Test manifests -platform: - arch: amd64 - os: linux -steps: -- commands: - - make generate-manifests - - ERR_MSG="The environment manifests are out of date. Please run 'make generate-manifests' - and commit changes!" - - if [ ! -z "$(git status --porcelain)" ]; then echo $ERR_MSG >&2; exit 1; fi - image: grafana/agent-build-image:0.30.4 - name: Regenerate environment manifests -trigger: - event: - - pull_request -type: docker ---- -kind: pipeline name: Test platform: arch: amd64 @@ -1427,6 +1409,6 @@ kind: secret name: updater_private_key --- kind: signature -hmac: 28ba52df6f22c10bf77a95386a49aff65a1c372127f7d89489ac2d3ee02ce618 +hmac: c6d9dd05507a2967a2ba394ee5e411e9dff9135335d31881d0d3ee262c7ea63a ... diff --git a/.drone/pipelines/test.jsonnet b/.drone/pipelines/test.jsonnet index 438447f99325..6daa113d2019 100644 --- a/.drone/pipelines/test.jsonnet +++ b/.drone/pipelines/test.jsonnet @@ -50,23 +50,6 @@ local pipelines = import '../util/pipelines.jsonnet'; }], }, - pipelines.linux('Test manifests') { - trigger: { - event: ['pull_request'], - }, - steps: [{ - name: 'Regenerate environment manifests', - image: build_image.linux, - - commands: [ - 'make generate-manifests', - 'ERR_MSG="The environment manifests are out of date. Please run \'make generate-manifests\' and commit changes!"', - // "git status --porcelain" reports if there's any new, modified, or deleted files. - 'if [ ! -z "$(git status --porcelain)" ]; then echo $ERR_MSG >&2; exit 1; fi', - ], - }], - }, - pipelines.linux('Test') { trigger: { event: ['pull_request'], diff --git a/Makefile b/Makefile index 5b7d4f424759..7b86fcae9080 100644 --- a/Makefile +++ b/Makefile @@ -56,7 +56,6 @@ ## generate-drone Generate the Drone YAML from Jsonnet. ## generate-helm-docs Generate Helm chart documentation. ## generate-helm-tests Generate Helm chart tests. -## generate-manifests Generate production/kubernetes YAML manifests. ## generate-dashboards Generate dashboards in example/docker-compose after ## changing Jsonnet. ## generate-protos Generate protobuf files. @@ -286,8 +285,8 @@ smoke-image: # Targets for generating assets # -.PHONY: generate generate-crds generate-drone generate-helm-docs generate-helm-tests generate-manifests generate-dashboards generate-protos generate-ui generate-versioned-files -generate: generate-crds generate-drone generate-helm-docs generate-helm-tests generate-manifests generate-dashboards generate-protos generate-ui generate-versioned-files generate-docs +.PHONY: generate generate-crds generate-drone generate-helm-docs generate-helm-tests generate-dashboards generate-protos generate-ui generate-versioned-files +generate: generate-crds generate-drone generate-helm-docs generate-helm-tests generate-dashboards generate-protos generate-ui generate-versioned-files generate-docs generate-crds: ifeq ($(USE_CONTAINER),1) @@ -314,13 +313,6 @@ else bash ./operations/helm/scripts/rebuild-tests.sh endif -generate-manifests: -ifeq ($(USE_CONTAINER),1) - $(RERUN_IN_CONTAINER) -else - cd production/kubernetes/build && bash build.sh -endif - generate-dashboards: ifeq ($(USE_CONTAINER),1) $(RERUN_IN_CONTAINER) diff --git a/example/docker-compose/grafana/dashboards/template.jsonnet b/example/docker-compose/grafana/dashboards/template.jsonnet index edc460218987..157860f0a389 100644 --- a/example/docker-compose/grafana/dashboards/template.jsonnet +++ b/example/docker-compose/grafana/dashboards/template.jsonnet @@ -1,5 +1,5 @@ -local agentDashboards = import 'grafana-agent-mixin/dashboards.libsonnet'; -local agentDebugging = import 'grafana-agent-mixin/debugging.libsonnet'; +local agentDashboards = import 'agent-static-mixin/dashboards.libsonnet'; +local agentDebugging = import 'agent-static-mixin/debugging.libsonnet'; local result = agentDashboards + agentDebugging { files: { diff --git a/example/docker-compose/jsonnetfile.json b/example/docker-compose/jsonnetfile.json index 1f2735e529cf..bee24c1dcf32 100644 --- a/example/docker-compose/jsonnetfile.json +++ b/example/docker-compose/jsonnetfile.json @@ -4,7 +4,7 @@ { "source": { "local": { - "directory": "../../production/grafana-agent-mixin" + "directory": "../../operations/agent-static-mixin" } }, "version": "" diff --git a/example/docker-compose/jsonnetfile.lock.json b/example/docker-compose/jsonnetfile.lock.json index 1803372b5348..463fc7a6776b 100644 --- a/example/docker-compose/jsonnetfile.lock.json +++ b/example/docker-compose/jsonnetfile.lock.json @@ -24,7 +24,7 @@ { "source": { "local": { - "directory": "../../production/grafana-agent-mixin" + "directory": "../../operations/agent-static-mixin" } }, "version": "" diff --git a/production/README.md b/production/README.md deleted file mode 100644 index 93a7f2594349..000000000000 --- a/production/README.md +++ /dev/null @@ -1 +0,0 @@ -**NOTE**: This folder has been deprecated in favor of [operations/](../operations/) and will be removed. diff --git a/production/grafana-agent-mixin/alerts.libsonnet b/production/grafana-agent-mixin/alerts.libsonnet deleted file mode 100644 index 51fe81e0e539..000000000000 --- a/production/grafana-agent-mixin/alerts.libsonnet +++ /dev/null @@ -1,414 +0,0 @@ -local config = import 'config.libsonnet'; -local _config = config._config; - -{ - prometheusAlerts+:: { - groups+: [ - { - name: 'grafana-agent-tracing', - rules: [ - { - alert: 'AgentTracingReceiverErrors', - // TODO(@mapno): add recording rule for total spans - expr: ||| - 100 * sum(rate(traces_receiver_refused_spans{receiver!="otlp/lb"}[1m])) by (%(group_by_cluster)s, receiver) - / - (sum(rate(traces_receiver_refused_spans{receiver!="otlp/lb"}[1m])) by (%(group_by_cluster)s, receiver) + sum(rate(traces_receiver_accepted_spans{receiver!="otlp/lb"}[1m])) by (%(group_by_cluster)s, receiver)) - > 10 - ||| % _config, - 'for': '15m', - labels: { - severity: 'warning', - }, - annotations: { - message: ||| - Receiver {{ $labels.receiver }} is experiencing {{ printf "%.2f" $value }}% errors. - |||, - }, - }, - { - alert: 'AgentTracingExporterErrors', - // TODO(@mapno): add recording rule for total spans - expr: ||| - 100 * sum(rate(traces_exporter_send_failed_spans{exporter!="otlp"}[1m])) by (%(group_by_cluster)s, exporter) - / - (sum(rate(traces_exporter_send_failed_spans{exporter!="otlp"}[1m])) by (%(group_by_cluster)s, exporter) + sum(rate(traces_exporter_sent_spans{exporter!="otlp"}[1m])) by (%(group_by_cluster)s, exporter)) - > 10 - ||| % _config, - 'for': '15m', - labels: { - severity: 'warning', - }, - annotations: { - message: ||| - Exporter {{ $labels.exporter }} is experiencing {{ printf "%.2f" $value }}% errors. - |||, - }, - }, - { - alert: 'AgentTracingLoadBalancingErrors', - expr: ||| - 100 * sum(rate(traces_loadbalancer_backend_outcome{success="false"}[1m])) by (%(group_by_cluster)s) - / - sum(rate(traces_loadbalancer_backend_outcome{success="true"}[1m])) by (%(group_by_cluster)s) - > 10 - ||| % _config, - 'for': '15m', - labels: { - severity: 'warning', - }, - annotations: { - message: ||| - Load balancing is experiencing {{ printf "%.2f" $value }}% errors. - |||, - }, - }, - ], - }, - { - name: 'GrafanaAgentSmokeChecks', - rules: [ - { - alert: 'GrafanaAgentDown', - expr: ||| - up{ - namespace="agent-smoke-test", - pod=~"grafana-agent-smoke-test-(0|cluster-0|cluster-1|cluster-2)", - } == 0 - |||, - 'for': '5m', - annotations: { - summary: '{{ $labels.job }} is down', - }, - }, - { - alert: 'GrafanaAgentFlapping', - expr: ||| - avg_over_time(up{ - namespace="agent-smoke-test", - pod=~"grafana-agent-smoke-test-(0|cluster-0|cluster-1|cluster-2)", - }[5m]) < 1 - |||, - 'for': '15m', - annotations: { - summary: '{{ $labels.job }} is flapping', - }, - }, - - // Checks that the CPU usage doesn't go too high. This was generated from internal usage where - // every 1,000 active series used roughly 0.0013441% of CPU. This alert only fires if there is a - // minimum load threshold of at least 1000 active series. - { - alert: 'GrafanaAgentCPUHigh', - expr: ||| - (sum by (pod) (rate(container_cpu_usage_seconds_total{cluster=~".+", namespace=~"agent-smoke-test", container=~".+", pod="grafana-agent-smoke-test-cluster-2"}[5m])) - / - (sum by (pod) (agent_wal_storage_active_series{cluster=~".+", namespace=~"agent-smoke-test", container=~".+", pod="grafana-agent-smoke-test-cluster-2"}) / 1000) - > 0.0013441) - and - sum by (pod) (agent_wal_storage_active_series{cluster=~".+", namespace=~"agent-smoke-test", container=~".+", pod="grafana-agent-smoke-test-cluster-2"}) > 1000 - |||, - 'for': '1h', - annotations: { - summary: '{{ $labels.pod }} is using more than 0.0013441 CPU per 1000 series over the last 5 minutes', - }, - }, - - // We assume roughly ~8KB per series. Check that each deployment - // doesn't go too far above this. - // - // We aggregate the memory of the scraping service together since an individual - // node with a really small number of active series will throw this metric off. - { - alert: 'GrafanaAgentMemHigh', - expr: ||| - sum without (pod, instance) (go_memstats_heap_inuse_bytes{job=~"agent-smoke-test/grafana-agent-smoke-test.*"}) / - sum without (pod, instance, instance_group_name) (agent_wal_storage_active_series{job=~"agent-smoke-test/grafana-agent-smoke-test.*"}) / 1e3 > 10 - |||, - 'for': '1h', - annotations: { - summary: '{{ $labels.job }} has used more than 10KB per series for more than 5 minutes', - }, - }, - { - alert: 'GrafanaAgentContainerRestarts', - expr: ||| - sum by (pod) (rate(kube_pod_container_status_restarts_total{namespace="agent-smoke-test"}[10m])) > 0 - |||, - annotations: { - summary: '{{ $labels.pod }} has a high rate of container restarts', - }, - }, - ], - }, - { - name: 'GrafanaAgentCrowChecks', - rules: [ - { - alert: 'CrowDown', - expr: ||| - up{job=~"agent-smoke-test/crow-.*"} == 0 - |||, - 'for': '5m', - annotations: { - summary: 'Crow {{ $labels.job }} is down.', - }, - }, - { - alert: 'CrowFlapping', - expr: ||| - avg_over_time(up{job=~"agent-smoke-test/crow-.*"}[5m]) < 1 - |||, - 'for': '15m', - annotations: { - summary: 'Crow {{ $labels.job }} is flapping.', - }, - }, - { - alert: 'CrowNotScraped', - expr: ||| - rate(crow_test_samples_total[5m]) == 0 - |||, - 'for': '15m', - annotations: { - summary: 'Crow {{ $labels.job }} is not being scraped.', - }, - }, - { - alert: 'CrowFailures', - expr: ||| - ( - rate(crow_test_sample_results_total{result="success"}[5m]) - / - ignoring(result) sum without (result) (rate(crow_test_sample_results_total[5m])) - ) - < 1 - |||, - 'for': '15m', - annotations: { - summary: 'Crow {{ $labels.job }} has had failures for at least 5m', - }, - }, - ], - }, - { - name: 'VultureChecks', - rules: [ - { - alert: 'VultureDown', - expr: ||| - up{job=~"agent-smoke-test/vulture"} == 0 - |||, - 'for': '5m', - annotations: { - summary: 'Vulture {{ $labels.job }} is down.', - }, - }, - { - alert: 'VultureFlapping', - expr: ||| - avg_over_time(up{job=~"agent-smoke-test/vulture"}[5m]) < 1 - |||, - 'for': '15m', - annotations: { - summary: 'Vulture {{ $labels.job }} is flapping.', - }, - }, - { - alert: 'VultureNotScraped', - expr: ||| - rate(tempo_vulture_trace_total[1m]) == 0 - |||, - 'for': '5m', - annotations: { - summary: 'Vulture {{ $labels.job }} is not being scraped.', - }, - }, - { - alert: 'VultureFailures', - expr: ||| - (rate(tempo_vulture_error_total[5m]) / rate(tempo_vulture_trace_total[5m])) > 0.3 - |||, - 'for': '5m', - annotations: { - summary: 'Vulture {{ $labels.job }} has had failures for at least 5m', - }, - }, - ], - }, - { - name: 'GrafanaAgentConfig', - rules: [ - { - alert: 'AgentRemoteConfigBadAPIRequests', - expr: ||| - 100 * sum(rate(agent_remote_config_fetches_total{status_code=~"(4|5).."}[10m])) by (%(group_by_cluster)s) - / - sum(rate(agent_remote_config_fetches_total[10m])) by (%(group_by_cluster)s) - > 5 - ||| % _config, - 'for': '10m', - labels: { - severity: 'warning', - }, - annotations: { - message: ||| - Receiving HTTP {{ $labels.status_code }} errors from API in {{ printf "%.2f" $value }}% of cases. - |||, - }, - }, - { - alert: 'AgentRemoteConfigBadAPIRequests', - expr: ||| - 100 * sum(rate(agent_remote_config_fetches_total{status_code=~"(4|5).."}[10m])) by (%(group_by_cluster)s) - / - sum(rate(agent_remote_config_fetches_total[10m])) by (%(group_by_cluster)s) - > 10 - ||| % _config, - 'for': '10m', - labels: { - severity: 'critical', - }, - annotations: { - message: ||| - Receiving HTTP {{ $labels.status_code }} errors from API in {{ printf "%.2f" $value }}% of cases. - |||, - }, - }, - { - alert: 'AgentRemoteConfigFetchErrors', - expr: ||| - 100 * sum(rate(agent_remote_config_fetch_errors_total[10m])) by (%(group_by_cluster)s) - / - sum(rate(agent_remote_config_fetches_total[10m])) by (%(group_by_cluster)s) - > 5 - ||| % _config, - 'for': '10m', - labels: { - severity: 'warning', - }, - annotations: { - message: ||| - Failing to reach Agent Management API. - |||, - }, - }, - { - alert: 'AgentRemoteConfigFetchErrors', - expr: ||| - 100 * sum(rate(agent_remote_config_fetch_errors_total[10m])) by (%(group_by_cluster)s) - / - sum(rate(agent_remote_config_fetches_total[10m])) by (%(group_by_cluster)s) - > 10 - ||| % _config, - 'for': '10m', - labels: { - severity: 'critical', - }, - annotations: { - message: ||| - Failing to reach Agent Management API. - |||, - }, - }, - { - alert: 'AgentRemoteConfigInvalidAPIResponse', - expr: ||| - 100 * sum(rate(agent_remote_config_invalid_total{reason=~".+"}[10m])) by (%(group_by_cluster)s) - / - sum(rate(agent_remote_config_fetches_total[10m])) by (%(group_by_cluster)s) - > 5 - ||| % _config, - 'for': '10m', - labels: { - severity: 'warning', - }, - annotations: { - message: ||| - API is responding with {{ $labels.reason }} in {{ printf "%.2f" $value }}% of cases. - |||, - }, - }, - { - alert: 'AgentRemoteConfigInvalidAPIResponse', - expr: ||| - 100 * sum(rate(agent_remote_config_invalid_total{reason=~".+"}[10m])) by (%(group_by_cluster)s) - / - sum(rate(agent_remote_config_fetches_total[10m])) by (%(group_by_cluster)s) - > 10 - ||| % _config, - 'for': '10m', - labels: { - severity: 'critical', - }, - annotations: { - message: ||| - API is responding with {{ $labels.reason }} in {{ printf "%.2f" $value }}% of cases. - |||, - }, - }, - { - alert: 'AgentFailureToReloadConfig', - expr: ||| - avg_over_time(agent_config_last_load_successful[10m]) < 0.9 - ||| % _config, - 'for': '10m', - labels: { - severity: 'warning', - }, - annotations: { - message: ||| - Instance {{ $labels.instance }} failed to successfully reload the config. - |||, - }, - }, - { - alert: 'AgentFailureToReloadConfig', - expr: ||| - avg_over_time(agent_config_last_load_successful[10m]) < 0.9 - ||| % _config, - 'for': '30m', - labels: { - severity: 'critical', - }, - annotations: { - message: ||| - Instance {{ $labels.instance }} failed to successfully reload the config. - |||, - }, - }, - { - alert: 'AgentManagementFallbackToEmptyConfig', - expr: ||| - sum(rate(agent_management_config_fallbacks_total{fallback_to="empty_config"}[10m])) by (%(group_by_cluster)s) > 0 - ||| % _config, - 'for': '10m', - labels: { - severity: 'warning', - }, - annotations: { - message: ||| - Instance {{ $labels.instance }} fell back to empty configuration. - |||, - }, - }, - { - alert: 'AgentManagementFallbackToEmptyConfig', - expr: ||| - sum(rate(agent_management_config_fallbacks_total{fallback_to="empty_config"}[10m])) by (%(group_by_cluster)s) > 0 - ||| % _config, - 'for': '30m', - labels: { - severity: 'critical', - }, - annotations: { - message: ||| - Instance {{ $labels.instance }} fell back to empty configuration. - |||, - }, - }, - ], - }, - ], - }, -} diff --git a/production/grafana-agent-mixin/config.libsonnet b/production/grafana-agent-mixin/config.libsonnet deleted file mode 100644 index 8a7df26c0d3a..000000000000 --- a/production/grafana-agent-mixin/config.libsonnet +++ /dev/null @@ -1,13 +0,0 @@ -{ - local makeGroupBy(groups) = std.join(', ', groups), - - _config+:: { - namespace: '.*', - - // Groups labels to uniquely identify and group by clusters - cluster_selectors: ['cluster', 'namespace'], - - // Each group-by label list is `, `-separated and unique identifies - group_by_cluster: makeGroupBy($._config.cluster_selectors), - }, -} diff --git a/production/grafana-agent-mixin/dashboards.libsonnet b/production/grafana-agent-mixin/dashboards.libsonnet deleted file mode 100644 index 834ec5181312..000000000000 --- a/production/grafana-agent-mixin/dashboards.libsonnet +++ /dev/null @@ -1,789 +0,0 @@ -local utils = import './utils.libsonnet'; -local g = import 'grafana-builder/grafana.libsonnet'; -local grafana = import 'grafonnet/grafana.libsonnet'; - -local dashboard = grafana.dashboard; -local row = grafana.row; -local singlestat = grafana.singlestat; -local prometheus = grafana.prometheus; -local graphPanel = grafana.graphPanel; -local tablePanel = grafana.tablePanel; -local template = grafana.template; - -{ - grafanaDashboards+:: { - 'agent.json': - utils.injectUtils(g.dashboard('Agent')) - .addMultiTemplate('cluster', 'agent_build_info', 'cluster') - .addMultiTemplate('namespace', 'agent_build_info', 'namespace') - .addMultiTemplate('container', 'agent_build_info', 'container') - .addMultiTemplateWithAll('pod', 'agent_build_info{container=~"$container"}', 'pod', all='grafana-agent-.*') - .addRow( - g.row('Agent Stats') - .addPanel( - g.panel('Agent Stats') + - g.tablePanel([ - 'count by (pod, container, version) (agent_build_info{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"})', - 'max by (pod, container) (time() - process_start_time_seconds{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"})', - ], { - pod: { alias: 'Pod' }, - container: { alias: 'Container' }, - version: { alias: 'Version' }, - 'Value #A': { alias: 'Count', type: 'hidden' }, - 'Value #B': { alias: 'Uptime' }, - }) - ) - ) - .addRow( - g.row('Prometheus Discovery') - .addPanel( - g.panel('Target Sync') + - g.queryPanel('sum(rate(prometheus_target_sync_length_seconds_sum{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"}[5m])) by (pod, scrape_job) * 1e3', '{{pod}}/{{scrape_job}}') + - { yaxes: g.yaxes('ms') } - ) - .addPanel( - g.panel('Targets') + - g.queryPanel('sum by (pod) (prometheus_sd_discovered_targets{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"})', '{{pod}}') + - g.stack - ) - ) - .addRow( - g.row('Prometheus Retrieval') - .addPanel( - g.panel('Average Scrape Interval Duration') + - g.queryPanel(||| - rate(prometheus_target_interval_length_seconds_sum{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"}[5m]) - / - rate(prometheus_target_interval_length_seconds_count{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"}[5m]) - * 1e3 - |||, '{{pod}} {{interval}} configured') + - { yaxes: g.yaxes('ms') } - ) - .addPanel( - g.panel('Scrape failures') + - g.queryPanel([ - 'sum by (job) (rate(prometheus_target_scrapes_exceeded_sample_limit_total{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"}[1m]))', - 'sum by (job) (rate(prometheus_target_scrapes_sample_duplicate_timestamp_total{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"}[1m]))', - 'sum by (job) (rate(prometheus_target_scrapes_sample_out_of_bounds_total{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"}[1m]))', - 'sum by (job) (rate(prometheus_target_scrapes_sample_out_of_order_total{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"}[1m]))', - ], [ - 'exceeded sample limit: {{job}}', - 'duplicate timestamp: {{job}}', - 'out of bounds: {{job}}', - 'out of order: {{job}}', - ]) + - g.stack - ) - .addPanel( - g.panel('Appended Samples') + - g.queryPanel('sum by (job, instance_group_name) (rate(agent_wal_samples_appended_total{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"}[5m]))', '{{job}} {{instance_group_name}}') + - g.stack - ) - ), - - // Remote write specific dashboard. - 'agent-remote-write.json': - local timestampComparison = - graphPanel.new( - 'Highest Timestamp In vs. Highest Timestamp Sent', - datasource='$datasource', - span=6, - ) - .addTarget(prometheus.target( - ||| - ( - prometheus_remote_storage_highest_timestamp_in_seconds{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"} - - - ignoring(url, remote_name) group_right(pod) - prometheus_remote_storage_queue_highest_sent_timestamp_seconds{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"} - ) - |||, - legendFormat='{{cluster}}:{{pod}}-{{instance_group_name}}-{{url}}', - )); - - local remoteSendLatency = - graphPanel.new( - 'Latency [1m]', - datasource='$datasource', - span=6, - ) - .addTarget(prometheus.target( - 'rate(prometheus_remote_storage_sent_batch_duration_seconds_sum{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"}[1m]) / rate(prometheus_remote_storage_sent_batch_duration_seconds_count{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"}[1m])', - legendFormat='mean {{cluster}}:{{pod}}-{{instance_group_name}}-{{url}}', - )) - .addTarget(prometheus.target( - 'histogram_quantile(0.99, rate(prometheus_remote_storage_sent_batch_duration_seconds_bucket{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"}[1m]))', - legendFormat='p99 {{cluster}}:{{pod}}-{{instance_group_name}}-{{url}}', - )); - - local samplesInRate = - graphPanel.new( - 'Rate in [5m]', - datasource='$datasource', - span=6, - ) - .addTarget(prometheus.target( - 'rate(agent_wal_samples_appended_total{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"}[5m])', - legendFormat='{{cluster}}:{{pod}}-{{instance_group_name}}-{{url}}', - )); - - local samplesOutRate = - graphPanel.new( - 'Rate succeeded [5m]', - datasource='$datasource', - span=6, - ) - .addTarget(prometheus.target( - 'rate(prometheus_remote_storage_succeeded_samples_total{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"}[5m]) or rate(prometheus_remote_storage_samples_total{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"}[5m])', - legendFormat='{{cluster}}:{{pod}}-{{instance_group_name}}-{{url}}', - )); - - local currentShards = - graphPanel.new( - 'Current Shards', - datasource='$datasource', - span=12, - min_span=6, - ) - .addTarget(prometheus.target( - 'prometheus_remote_storage_shards{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"}', - legendFormat='{{cluster}}:{{pod}}-{{instance_group_name}}-{{url}}', - )); - - local maxShards = - graphPanel.new( - 'Max Shards', - datasource='$datasource', - span=4, - ) - .addTarget(prometheus.target( - 'prometheus_remote_storage_shards_max{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"}', - legendFormat='{{cluster}}:{{pod}}-{{instance_group_name}}-{{url}}', - )); - - local minShards = - graphPanel.new( - 'Min Shards', - datasource='$datasource', - span=4, - ) - .addTarget(prometheus.target( - 'prometheus_remote_storage_shards_min{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"}', - legendFormat='{{cluster}}:{{pod}}-{{instance_group_name}}-{{url}}', - )); - - local desiredShards = - graphPanel.new( - 'Desired Shards', - datasource='$datasource', - span=4, - ) - .addTarget(prometheus.target( - 'prometheus_remote_storage_shards_desired{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"}', - legendFormat='{{cluster}}:{{pod}}-{{instance_group_name}}-{{url}}', - )); - - local shardsCapacity = - graphPanel.new( - 'Shard Capacity', - datasource='$datasource', - span=6, - ) - .addTarget(prometheus.target( - 'prometheus_remote_storage_shard_capacity{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"}', - legendFormat='{{cluster}}:{{pod}}-{{instance_group_name}}-{{url}}', - )); - - local pendingSamples = - graphPanel.new( - 'Pending Samples', - datasource='$datasource', - span=6, - ) - .addTarget(prometheus.target( - 'prometheus_remote_storage_samples_pending{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"}', - legendFormat='{{cluster}}:{{pod}}-{{instance_group_name}}-{{url}}', - )); - - local queueSegment = - graphPanel.new( - 'Remote Write Current Segment', - datasource='$datasource', - span=6, - formatY1='none', - ) - .addTarget(prometheus.target( - 'prometheus_wal_watcher_current_segment{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"}', - legendFormat='{{cluster}}:{{pod}}-{{instance_group_name}}-{{url}}', - )); - - local droppedSamples = - graphPanel.new( - 'Dropped Samples', - datasource='$datasource', - span=6, - ) - .addTarget(prometheus.target( - 'rate(prometheus_remote_storage_samples_dropped_total{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"}[5m])', - legendFormat='{{cluster}}:{{pod}}-{{instance_group_name}}-{{url}}', - )); - - local failedSamples = - graphPanel.new( - 'Failed Samples', - datasource='$datasource', - span=6, - ) - .addTarget(prometheus.target( - 'rate(prometheus_remote_storage_samples_failed_total{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"}[5m])', - legendFormat='{{cluster}}:{{pod}}-{{instance_group_name}}-{{url}}', - )); - - local retriedSamples = - graphPanel.new( - 'Retried Samples', - datasource='$datasource', - span=6, - ) - .addTarget(prometheus.target( - 'rate(prometheus_remote_storage_samples_retried_total{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"}[5m])', - legendFormat='{{cluster}}:{{pod}}-{{instance_group_name}}-{{url}}', - )); - - local enqueueRetries = - graphPanel.new( - 'Enqueue Retries', - datasource='$datasource', - span=6, - ) - .addTarget(prometheus.target( - 'rate(prometheus_remote_storage_enqueue_retries_total{cluster=~"$cluster", namespace=~"$namespace", container=~"$container"}[5m])', - legendFormat='{{cluster}}:{{pod}}-{{instance_group_name}}-{{url}}', - )); - - dashboard.new('Agent Prometheus Remote Write', tags=['grafana-agent-mixin'], editable=true, refresh='30s', time_from='now-1h') - .addTemplate( - { - hide: 0, - label: null, - name: 'datasource', - options: [], - query: 'prometheus', - refresh: 1, - regex: '', - type: 'datasource', - }, - ) - .addTemplate( - template.new( - 'cluster', - '$datasource', - 'label_values(agent_build_info, cluster)', - refresh='time', - current={ - selected: true, - text: 'All', - value: '$__all', - }, - includeAll=true, - ), - ) - .addTemplate( - template.new( - 'namespace', - '$datasource', - 'label_values(agent_build_info, namespace)', - refresh='time', - current={ - selected: true, - text: 'All', - value: '$__all', - }, - includeAll=true, - ), - ) - .addTemplate( - template.new( - 'container', - '$datasource', - 'label_values(agent_build_info, container)', - refresh='time', - current={ - selected: true, - text: 'All', - value: '$__all', - }, - includeAll=true, - ), - ) - .addTemplate( - template.new( - 'pod', - '$datasource', - 'label_values(agent_build_info{container=~"$container"}, pod)', - refresh='time', - current={ - selected: true, - text: 'All', - value: '$__all', - }, - includeAll=true, - ), - ) - .addTemplate( - template.new( - 'url', - '$datasource', - 'label_values(prometheus_remote_storage_shards{cluster=~"$cluster", pod=~"$pod"}, url)', - refresh='time', - includeAll=true, - ) - ) - .addRow( - row.new('Timestamps') - .addPanel(timestampComparison) - .addPanel(remoteSendLatency) - ) - .addRow( - row.new('Samples') - .addPanel(samplesInRate) - .addPanel(samplesOutRate) - .addPanel(pendingSamples) - .addPanel(droppedSamples) - .addPanel(failedSamples) - .addPanel(retriedSamples) - ) - .addRow( - row.new('Shards') - .addPanel(currentShards) - .addPanel(maxShards) - .addPanel(minShards) - .addPanel(desiredShards) - ) - .addRow( - row.new('Shard Details') - .addPanel(shardsCapacity) - ) - .addRow( - row.new('Segments') - .addPanel(queueSegment) - ) - .addRow( - row.new('Misc. Rates') - .addPanel(enqueueRetries) - ), - - 'agent-tracing-pipeline.json': - local acceptedSpans = - graphPanel.new( - 'Accepted spans', - datasource='$datasource', - interval='1m', - span=3, - legend_show=false, - fill=0, - ) - .addTarget(prometheus.target( - ||| - rate(traces_receiver_accepted_spans{cluster=~"$cluster",namespace=~"$namespace",container=~"$container",pod=~"$pod",receiver!="otlp/lb"}[$__rate_interval]) - |||, - legendFormat='{{ pod }} - {{ receiver }}/{{ transport }}', - )); - - local refusedSpans = - graphPanel.new( - 'Refused spans', - datasource='$datasource', - interval='1m', - span=3, - legend_show=false, - fill=0, - ) - .addTarget(prometheus.target( - ||| - rate(traces_receiver_refused_spans{cluster=~"$cluster",namespace=~"$namespace",container=~"$container",pod=~"$pod",receiver!="otlp/lb"}[$__rate_interval]) - |||, - legendFormat='{{ pod }} - {{ receiver }}/{{ transport }}', - )); - - local sentSpans = - graphPanel.new( - 'Exported spans', - datasource='$datasource', - interval='1m', - span=3, - legend_show=false, - fill=0, - ) - .addTarget(prometheus.target( - ||| - rate(traces_exporter_sent_spans{cluster=~"$cluster",namespace=~"$namespace",container=~"$container",pod=~"$pod",exporter!="otlp"}[$__rate_interval]) - |||, - legendFormat='{{ pod }} - {{ exporter }}', - )); - - local exportedFailedSpans = - graphPanel.new( - 'Exported failed spans', - datasource='$datasource', - interval='1m', - span=3, - legend_show=false, - fill=0, - ) - .addTarget(prometheus.target( - ||| - rate(traces_exporter_send_failed_spans{cluster=~"$cluster",namespace=~"$namespace",container=~"$container",pod=~"$pod",exporter!="otlp"}[$__rate_interval]) - |||, - legendFormat='{{ pod }} - {{ exporter }}', - )); - - local receivedSpans(receiverFilter, width) = - graphPanel.new( - 'Received spans', - datasource='$datasource', - interval='1m', - span=width, - fill=1, - ) - .addTarget(prometheus.target( - ||| - sum(rate(traces_receiver_accepted_spans{cluster=~"$cluster",namespace=~"$namespace",container=~"$container",pod=~"$pod",%s}[$__rate_interval])) - ||| % receiverFilter, - legendFormat='Accepted', - )) - .addTarget(prometheus.target( - ||| - sum(rate(traces_receiver_refused_spans{cluster=~"$cluster",namespace=~"$namespace",container=~"$container",pod=~"$pod",%s}[$__rate_interval])) - ||| % receiverFilter, - legendFormat='Refused', - )); - - local exportedSpans(exporterFilter, width) = - graphPanel.new( - 'Exported spans', - datasource='$datasource', - interval='1m', - span=width, - fill=1, - ) - .addTarget(prometheus.target( - ||| - sum(rate(traces_exporter_sent_spans{cluster=~"$cluster",namespace=~"$namespace",container=~"$container",pod=~"$pod",%s}[$__rate_interval])) - ||| % exporterFilter, - legendFormat='Sent', - )) - .addTarget(prometheus.target( - ||| - sum(rate(traces_exporter_send_failed_spans{cluster=~"$cluster",namespace=~"$namespace",container=~"$container",pod=~"$pod",%s}[$__rate_interval])) - ||| % exporterFilter, - legendFormat='Send failed', - )); - - local loadBalancedSpans = - graphPanel.new( - 'Load-balanced spans', - datasource='$datasource', - interval='1m', - span=3, - fill=1, - stack=true, - ) - .addTarget(prometheus.target( - ||| - rate(traces_loadbalancer_backend_outcome{cluster=~"$cluster",namespace=~"$namespace",success="true",container=~"$container",pod=~"$pod"}[$__rate_interval]) - |||, - legendFormat='{{ pod }}', - )); - - local peersNum = - graphPanel.new( - 'Number of peers', - datasource='$datasource', - interval='1m', - span=3, - legend_show=false, - fill=0, - ) - .addTarget(prometheus.target( - ||| - traces_loadbalancer_num_backends{cluster=~"$cluster",namespace=~"$namespace",container=~"$container",pod=~"$pod"} - |||, - legendFormat='{{ pod }}', - )); - - dashboard.new('Agent Tracing Pipeline', tags=['grafana-agent-mixin'], editable=true, refresh='30s', time_from='now-1h') - .addTemplate( - { - hide: 0, - label: null, - name: 'datasource', - options: [], - query: 'prometheus', - refresh: 1, - regex: '', - type: 'datasource', - }, - ) - .addTemplate( - template.new( - 'cluster', - '$datasource', - 'label_values(agent_build_info, cluster)', - refresh='time', - current={ - selected: true, - text: 'All', - value: '$__all', - }, - includeAll=true, - ), - ) - .addTemplate( - template.new( - 'namespace', - '$datasource', - 'label_values(agent_build_info, namespace)', - refresh='time', - current={ - selected: true, - text: 'All', - value: '$__all', - }, - includeAll=true, - ), - ) - .addTemplate( - template.new( - 'container', - '$datasource', - 'label_values(agent_build_info, container)', - refresh='time', - current={ - selected: true, - text: 'All', - value: '$__all', - }, - includeAll=true, - ), - ) - .addTemplate( - template.new( - 'pod', - '$datasource', - 'label_values(agent_build_info{container=~"$container"}, pod)', - refresh='time', - current={ - selected: true, - text: 'All', - value: '$__all', - }, - includeAll=true, - ), - ) - .addRow( - row.new('Write / Read') - .addPanel(acceptedSpans) - .addPanel(refusedSpans) - .addPanel(sentSpans) - .addPanel(exportedFailedSpans) - .addPanel(receivedSpans('receiver!="otlp/lb"', 6)) - .addPanel(exportedSpans('exporter!="otlp"', 6)) - ) - .addRow( - row.new('Load balancing') - .addPanel(loadBalancedSpans) - .addPanel(peersNum) - .addPanel(receivedSpans('receiver="otlp/lb"', 3)) - .addPanel(exportedSpans('exporter="otlp"', 3)) - ), - - 'agent-logs-pipeline.json': - local sumByPodRateCounter(title, metric, format='short') = - graphPanel.new( - title, - datasource='$datasource', - interval='1m', - span=6, - fill=1, - stack=true, - format=format - ) - .addTarget(prometheus.target( - ||| - sum by($groupBy) (rate(%s{cluster=~"$cluster",namespace=~"$namespace",container=~"$container",pod=~"$pod"}[$__rate_interval])) - ||| % [metric], - legendFormat='{{$groupBy}}', - )); - - local sumByPodGague(title, metric) = - graphPanel.new( - title, - datasource='$datasource', - interval='1m', - span=6, - fill=1, - stack=true, - ) - .addTarget(prometheus.target( - ||| - sum by($groupBy) (%s{cluster=~"$cluster",namespace=~"$namespace",container=~"$container",pod=~"$pod"}) - ||| % [metric], - legendFormat='{{$groupBy}}', - )); - - local requestSuccessRate() = - graphPanel.new( - 'Write requests success rate [%]', - datasource='$datasource', - interval='1m', - fill=0, - span=6, - format='%', - ) - .addTarget(prometheus.target( - ||| - sum by($groupBy) (rate(promtail_request_duration_seconds_bucket{status_code=~"2..", cluster=~"$cluster",namespace=~"$namespace",container=~"$container",pod=~"$pod"}[$__rate_interval])) - / - sum by($groupBy) (rate(promtail_request_duration_seconds_bucket{cluster=~"$cluster",namespace=~"$namespace",container=~"$container",pod=~"$pod"}[$__rate_interval])) - * 100 - |||, - legendFormat='{{$groupBy}}', - )); - - local histogramQuantile(title, metric, q) = - graphPanel.new( - title, - datasource='$datasource', - interval='1m', - span=6, - fill=0, - format='s', - ) - .addTarget(prometheus.target( - ||| - histogram_quantile( - %f, - sum by (le, $groupBy) - (rate(%s{cluster=~"$cluster",namespace=~"$namespace",container=~"$container",pod=~"$pod"}[$__rate_interval])) - ) - ||| % [q, metric], - legendFormat='{{$groupBy}}', - )); - - local histogramAverage(title, metric) = - graphPanel.new( - title, - datasource='$datasource', - interval='1m', - span=6, - fill=0, - format='s', - ) - .addTarget(prometheus.target( - ||| - (sum by (le, $groupBy) (rate(%s_sum{cluster=~"$cluster",namespace=~"$namespace",container=~"$container",pod=~"$pod"}[$__rate_interval]))) - / - (sum by (le, $groupBy) (rate(%s_count{cluster=~"$cluster",namespace=~"$namespace",container=~"$container",pod=~"$pod"}[$__rate_interval]))) - ||| % [metric, metric], - legendFormat='{{$groupBy}}', - )); - - - dashboard.new('Agent Logs Pipeline', tags=['grafana-agent-mixin'], editable=true, refresh='30s', time_from='now-1h') - .addTemplate( - { - hide: 0, - label: null, - name: 'datasource', - options: [], - query: 'prometheus', - refresh: 1, - regex: '', - type: 'datasource', - }, - ) - .addTemplate( - template.new( - 'cluster', - '$datasource', - 'label_values(agent_build_info, cluster)', - refresh='time', - current={ - selected: true, - text: 'All', - value: '$__all', - }, - includeAll=true, - ), - ) - .addTemplate( - template.new( - 'namespace', - '$datasource', - 'label_values(agent_build_info, namespace)', - refresh='time', - current={ - selected: true, - text: 'All', - value: '$__all', - }, - includeAll=true, - ), - ) - .addTemplate( - template.new( - 'container', - '$datasource', - 'label_values(agent_build_info, container)', - refresh='time', - current={ - selected: true, - text: 'All', - value: '$__all', - }, - includeAll=true, - ), - ) - .addTemplate( - template.new( - 'pod', - '$datasource', - 'label_values(agent_build_info{container=~"$container"}, pod)', - refresh='time', - current={ - selected: true, - text: 'All', - value: '$__all', - }, - includeAll=true, - ), - ) - .addTemplate( - template.custom( - 'groupBy', - 'pod,cluster,namespace', - 'pod', - ), - ) - .addRow( - row.new('Errors', height=500) - .addPanel(sumByPodRateCounter('Dropped bytes rate [B/s]', 'promtail_dropped_bytes_total', format='Bps')) - .addPanel(requestSuccessRate()) - ) - .addRow( - row.new('Latencies', height=500) - .addPanel(histogramQuantile('Write latencies p99 [s]', 'promtail_request_duration_seconds_bucket', 0.99)) - .addPanel(histogramQuantile('Write latencies p90 [s]', 'promtail_request_duration_seconds_bucket', 0.90)) - .addPanel(histogramQuantile('Write latencies p50 [s]', 'promtail_request_duration_seconds_bucket', 0.50)) - .addPanel(histogramAverage('Write latencies average [s]', 'promtail_request_duration_seconds')) - ) - .addRow( - row.new('Logs volume', height=500) - .addPanel(sumByPodRateCounter('Bytes read rate [B/s]', 'promtail_read_bytes_total', format='Bps')) - .addPanel(sumByPodRateCounter('Lines read rate [lines/s]', 'promtail_read_lines_total')) - .addPanel(sumByPodGague('Active files count', 'promtail_files_active_total')) - .addPanel(sumByPodRateCounter('Entries sent rate [entries/s]', 'promtail_sent_entries_total')) - ), - }, -} diff --git a/production/grafana-agent-mixin/debugging.libsonnet b/production/grafana-agent-mixin/debugging.libsonnet deleted file mode 100644 index 711184d333f7..000000000000 --- a/production/grafana-agent-mixin/debugging.libsonnet +++ /dev/null @@ -1,128 +0,0 @@ -local utils = import './utils.libsonnet'; -local g = import 'grafana-builder/grafana.libsonnet'; - -{ - grafanaDashboards+:: { - 'agent-operational.json': - utils.injectUtils(g.dashboard('Agent Operational')) - .addMultiTemplate('cluster', 'agent_build_info', 'cluster') - .addMultiTemplate('namespace', 'agent_build_info{cluster=~"$cluster"}', 'namespace') - .addMultiTemplate('container', 'agent_build_info{cluster=~"$cluster", namespace="$namespace"}', 'container') - .addMultiTemplate('pod', 'agent_build_info{cluster=~"$cluster", namespace="$namespace", container="$container"}', 'pod') - .addRow( - g.row('General') - .addPanel( - g.panel('GCs [count/s]') + - g.queryPanel( - 'rate(go_gc_duration_seconds_count{cluster=~"$cluster", namespace=~"$namespace", container=~"$container", pod=~"$pod"}[5m])', - '{{pod}}', - ) - ) - .addPanel( - g.panel('Go Heap In Use') + - { yaxes: g.yaxes('decbytes') } + - g.queryPanel( - 'go_memstats_heap_inuse_bytes{cluster=~"$cluster", namespace=~"$namespace", container=~"$container", pod=~"$pod"}', - '{{pod}}', - ) - ) - .addPanel( - g.panel('Goroutines') + - g.queryPanel( - 'go_goroutines{cluster=~"$cluster", namespace=~"$namespace", container=~"$container", pod=~"$pod"}', - '{{pod}}', - ) - ) - .addPanel( - g.panel('CPU Usage [time/s]') + - g.queryPanel( - 'rate(container_cpu_usage_seconds_total{cluster=~"$cluster", namespace=~"$namespace", container=~"$container", pod=~"$pod"}[5m])', - '{{pod}}', - ) - ) - .addPanel( - g.panel('Working Set Size') + - { yaxes: g.yaxes('decbytes') } + - g.queryPanel( - 'container_memory_working_set_bytes{cluster=~"$cluster", namespace=~"$namespace", container=~"$container", pod=~"$pod"}', - '{{pod}}', - ) - ) - .addPanel( - g.panel('Promtail Bad Words') + - g.queryPanel( - 'rate(promtail_custom_bad_words_total{cluster=~"$cluster", exported_namespace=~"$namespace", exported_job=~"$job"}[5m])', - '{{job}}', - ) - ) - ) - .addRow( - g.row('Network') - .addPanel( - g.panel('Received Bytes [B/s]') + - { yaxes: g.yaxes('Bps') } + - g.queryPanel( - 'sum by (pod) (rate(container_network_receive_bytes_total{cluster=~"$cluster", namespace=~"$namespace", pod=~"$pod"}[5m]))', - '{{pod}}', - ) - ) - .addPanel( - g.panel('Transmitted Bytes [B/s]') + - { yaxes: g.yaxes('Bps') } + - g.queryPanel( - 'sum by (pod) (rate(container_network_transmit_bytes_total{cluster=~"$cluster", namespace=~"$namespace", pod=~"$pod"}[5m]))', - '{{pod}}', - ) - ) - ) - .addRow( - g.row('Prometheus Read') - .addPanel( - g.panel('Heap Used per Series per Pod') + - { yaxes: g.yaxes('decbytes') } + - g.queryPanel( - ||| - (sum by (pod) (avg_over_time(go_memstats_heap_inuse_bytes{cluster=~"$cluster", namespace=~"$namespace", container=~"$container", pod=~"$pod"}[1m]))) - / - (sum by (pod) (agent_wal_storage_active_series{cluster=~"$cluster", namespace=~"$namespace", container=~"$container", pod=~"$pod"})) - |||, - '{{pod}}', - ) - ) - .addPanel( - g.panel('Avg Heap Used per Series') + - { yaxes: g.yaxes('decbytes') } + - g.queryPanel( - ||| - (sum by (container) (avg_over_time(go_memstats_heap_inuse_bytes{cluster=~"$cluster", namespace=~"$namespace", container=~"$container", pod=~"$pod"}[1m]))) - / - (sum by (container) (agent_wal_storage_active_series{cluster=~"$cluster", namespace=~"$namespace", container=~"$container", pod=~"$pod"})) - |||, - '{{container}}', - ) - ) - .addPanel( - g.panel('Series Count per Pod') + - g.queryPanel( - 'sum by (pod) (agent_wal_storage_active_series{cluster=~"$cluster", namespace=~"$namespace", container=~"$container", pod=~"$pod"})', - '{{pod}}', - ) - ) - .addPanel( - g.panel('Series per Config') + - g.queryPanel( - 'sum by (instance_group_name) (agent_wal_storage_active_series{cluster=~"$cluster", namespace=~"$namespace", container=~"$container", pod=~"$pod"})', - '{{instance_group_name}}', - ) - ) - .addPanel( - g.panel('Total Series') + - g.queryPanel( - 'sum by (container) (agent_wal_storage_active_series{cluster=~"$cluster", namespace=~"$namespace", container=~"$container", pod=~"$pod"})', - '{{container}}', - ) - ) - ), - }, -} - diff --git a/production/grafana-agent-mixin/jsonnetfile.json b/production/grafana-agent-mixin/jsonnetfile.json deleted file mode 100644 index e5a27a96ad6a..000000000000 --- a/production/grafana-agent-mixin/jsonnetfile.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "dependencies": [ - { - "name": "grafana-builder", - "source": { - "git": { - "remote": "https://github.com/grafana/jsonnet-libs", - "subdir": "grafana-builder" - } - }, - "version": "master" - }, - { - "name": "grafonnet", - "source": { - "git": { - "remote": "https://github.com/grafana/grafonnet-lib", - "subdir": "grafonnet" - } - }, - "version": "master" - } - ] -} - diff --git a/production/grafana-agent-mixin/mixin.libsonnet b/production/grafana-agent-mixin/mixin.libsonnet deleted file mode 100644 index 2a015d681601..000000000000 --- a/production/grafana-agent-mixin/mixin.libsonnet +++ /dev/null @@ -1,4 +0,0 @@ -{ grafanaDashboardFolder: 'Grafana Agent' } -+ (import 'dashboards.libsonnet') -+ (import 'debugging.libsonnet') -+ (import 'alerts.libsonnet') diff --git a/production/grafana-agent-mixin/utils.libsonnet b/production/grafana-agent-mixin/utils.libsonnet deleted file mode 100644 index 5467553a7d52..000000000000 --- a/production/grafana-agent-mixin/utils.libsonnet +++ /dev/null @@ -1,34 +0,0 @@ -{ - injectUtils(dashboard):: dashboard { - tags: ['grafana-agent-mixin'], - refresh: '30s', - addMultiTemplateWithAll(name, metric_name, label_name, all='.*', hide=0):: self { - templating+: { - list+: [{ - allValue: all, - current: { - selected: true, - text: 'All', - value: '$__all', - }, - datasource: '$datasource', - hide: hide, - includeAll: true, - label: name, - multi: true, - name: name, - options: [], - query: 'label_values(%s, %s)' % [metric_name, label_name], - refresh: 1, - regex: '', - sort: 2, - tagValuesQuery: '', - tags: [], - tagsQuery: '', - type: 'query', - useTags: false, - }], - }, - }, - }, -} diff --git a/production/kubernetes/README.md b/production/kubernetes/README.md deleted file mode 100644 index 6a98bd3057b6..000000000000 --- a/production/kubernetes/README.md +++ /dev/null @@ -1,50 +0,0 @@ -# Kubernetes Config - -This directory contains Kubernetes manifest templates for rolling out the Agent. - -Manifests: - -- Metric collection (StatefulSet): [`agent-bare.yaml`](./agent-bare.yaml) -- Log collection (DaemonSet): [`agent-loki.yaml`](./agent-loki.yaml) -- Trace collection (Deployment): [`agent-traces.yaml`](./agent-traces.yaml) - -⚠️ **These manifests do not include the Agent's configuration (ConfigMaps)**, -which are necessary to run the Agent. - -For sample configurations and detailed installation instructions, please head to: - -- [Grafana Agent Metrics Kubernetes Quickstart](https://grafana.com/docs/grafana-cloud/quickstart/agent-k8s/k8s_agent_metrics/) -- [Grafana Agent Logs Kubernetes Quickstart](https://grafana.com/docs/grafana-cloud/quickstart/agent-k8s/k8s_agent_logs/) -- [Grafana Agent Traces Kubernetes Quickstart](https://grafana.com/docs/grafana-cloud/quickstart/agent-k8s/k8s_agent_traces/) - -## Manually Applying - -Since the manifest files are just templates, note that they are *not* ready for -applying out of the box and you will have to manually perform the following steps: - -1. Download the manifest as `manifest.yaml` - -2. Modify your copy of the manifest, replacing relevant variables with the appropriate values - -3. Apply the modified manifest file: `kubectl -n default apply -f manifest.yaml`. - -This directory also contains an `install-bare.sh` script that is used inside of -Grafana Cloud instructions. If using the Grafana Agent outside of Grafana Cloud, -it is recommended to follow the steps above instead of calling this script -directly. - -## Rebuilding the manifests - -The manifests provided are created using Grafana Labs' production -[Tanka configs](../tanka/grafana-agent) with some default values. If you want to -build the YAML file with some custom values, you will need the following pieces -of software installed: - -1. [Tanka](https://github.com/grafana/tanka) >= v0.8 -2. [`jsonnet-bundler`](https://github.com/jsonnet-bundler/jsonnet-bundler) >= v0.2.1 - -See the [`template` Tanka environment](./build/templates) for the current -settings that initialize the Grafana Agent Tanka configs. - -To build the YAML files, execute the `./build/build.sh` script or run `make example-kubernetes` -from the project's root directory. diff --git a/production/kubernetes/agent-bare.yaml b/production/kubernetes/agent-bare.yaml deleted file mode 100644 index ccf5d13439ce..000000000000 --- a/production/kubernetes/agent-bare.yaml +++ /dev/null @@ -1,115 +0,0 @@ -apiVersion: v1 -kind: ServiceAccount -metadata: - name: grafana-agent - namespace: ${NAMESPACE} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: grafana-agent -rules: -- apiGroups: - - "" - resources: - - nodes - - nodes/proxy - - services - - endpoints - - pods - - events - verbs: - - get - - list - - watch -- nonResourceURLs: - - /metrics - verbs: - - get ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: grafana-agent -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: grafana-agent -subjects: -- kind: ServiceAccount - name: grafana-agent - namespace: ${NAMESPACE} ---- -apiVersion: v1 -kind: Service -metadata: - labels: - name: grafana-agent - name: grafana-agent - namespace: ${NAMESPACE} -spec: - clusterIP: None - ports: - - name: grafana-agent-http-metrics - port: 80 - targetPort: 80 - selector: - name: grafana-agent ---- -apiVersion: apps/v1 -kind: StatefulSet -metadata: - name: grafana-agent - namespace: ${NAMESPACE} -spec: - replicas: 1 - selector: - matchLabels: - name: grafana-agent - serviceName: grafana-agent - template: - metadata: - labels: - name: grafana-agent - spec: - containers: - - args: - - -config.expand-env=true - - -config.file=/etc/agent/agent.yaml - - -enable-features=integrations-next - - -server.http.address=0.0.0.0:80 - env: - - name: HOSTNAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - image: grafana/agent:v0.39.0 - imagePullPolicy: IfNotPresent - name: grafana-agent - ports: - - containerPort: 80 - name: http-metrics - volumeMounts: - - mountPath: /var/lib/agent - name: agent-wal - - mountPath: /etc/agent - name: grafana-agent - serviceAccountName: grafana-agent - volumes: - - configMap: - name: grafana-agent - name: grafana-agent - updateStrategy: - type: RollingUpdate - volumeClaimTemplates: - - apiVersion: v1 - kind: PersistentVolumeClaim - metadata: - name: agent-wal - namespace: ${NAMESPACE} - spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 5Gi diff --git a/production/kubernetes/agent-loki.yaml b/production/kubernetes/agent-loki.yaml deleted file mode 100644 index 497462d3efcb..000000000000 --- a/production/kubernetes/agent-loki.yaml +++ /dev/null @@ -1,100 +0,0 @@ -apiVersion: v1 -kind: ServiceAccount -metadata: - name: grafana-agent-logs - namespace: ${NAMESPACE} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: grafana-agent-logs -rules: -- apiGroups: - - "" - resources: - - nodes - - nodes/proxy - - services - - endpoints - - pods - - events - verbs: - - get - - list - - watch -- nonResourceURLs: - - /metrics - verbs: - - get ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: grafana-agent-logs -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: grafana-agent-logs -subjects: -- kind: ServiceAccount - name: grafana-agent-logs - namespace: ${NAMESPACE} ---- -apiVersion: apps/v1 -kind: DaemonSet -metadata: - name: grafana-agent-logs - namespace: ${NAMESPACE} -spec: - minReadySeconds: 10 - selector: - matchLabels: - name: grafana-agent-logs - template: - metadata: - labels: - name: grafana-agent-logs - spec: - containers: - - args: - - -config.expand-env=true - - -config.file=/etc/agent/agent.yaml - - -server.http.address=0.0.0.0:80 - env: - - name: HOSTNAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - image: grafana/agent:v0.39.0 - imagePullPolicy: IfNotPresent - name: grafana-agent-logs - ports: - - containerPort: 80 - name: http-metrics - securityContext: - privileged: true - runAsUser: 0 - volumeMounts: - - mountPath: /etc/agent - name: grafana-agent-logs - - mountPath: /var/log - name: varlog - - mountPath: /var/lib/docker/containers - name: varlibdockercontainers - readOnly: true - serviceAccountName: grafana-agent-logs - tolerations: - - effect: NoSchedule - operator: Exists - volumes: - - configMap: - name: grafana-agent-logs - name: grafana-agent-logs - - hostPath: - path: /var/log - name: varlog - - hostPath: - path: /var/lib/docker/containers - name: varlibdockercontainers - updateStrategy: - type: RollingUpdate diff --git a/production/kubernetes/agent-traces.yaml b/production/kubernetes/agent-traces.yaml deleted file mode 100644 index c42cec6125e3..000000000000 --- a/production/kubernetes/agent-traces.yaml +++ /dev/null @@ -1,154 +0,0 @@ -apiVersion: v1 -kind: ServiceAccount -metadata: - name: grafana-agent-traces - namespace: ${NAMESPACE} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: grafana-agent-traces -rules: -- apiGroups: - - "" - resources: - - nodes - - nodes/proxy - - services - - endpoints - - pods - - events - verbs: - - get - - list - - watch -- nonResourceURLs: - - /metrics - verbs: - - get ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: grafana-agent-traces -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: grafana-agent-traces -subjects: -- kind: ServiceAccount - name: grafana-agent-traces - namespace: ${NAMESPACE} ---- -apiVersion: v1 -kind: Service -metadata: - labels: - name: grafana-agent-traces - name: grafana-agent-traces - namespace: ${NAMESPACE} -spec: - ports: - - name: grafana-agent-traces-http-metrics - port: 80 - targetPort: 80 - - name: grafana-agent-traces-thrift-compact - port: 6831 - protocol: UDP - targetPort: 6831 - - name: grafana-agent-traces-thrift-binary - port: 6832 - protocol: UDP - targetPort: 6832 - - name: grafana-agent-traces-thrift-http - port: 14268 - protocol: TCP - targetPort: 14268 - - name: grafana-agent-traces-thrift-grpc - port: 14250 - protocol: TCP - targetPort: 14250 - - name: grafana-agent-traces-zipkin - port: 9411 - protocol: TCP - targetPort: 9411 - - name: grafana-agent-traces-otlp-grpc - port: 4317 - protocol: TCP - targetPort: 4317 - - name: grafana-agent-traces-otlp-http - port: 4318 - protocol: TCP - targetPort: 4318 - - name: grafana-agent-traces-opencensus - port: 55678 - protocol: TCP - targetPort: 55678 - selector: - name: grafana-agent-traces ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: grafana-agent-traces - namespace: ${NAMESPACE} -spec: - minReadySeconds: 10 - replicas: 1 - revisionHistoryLimit: 10 - selector: - matchLabels: - name: grafana-agent-traces - template: - metadata: - labels: - name: grafana-agent-traces - spec: - containers: - - args: - - -config.expand-env=true - - -config.file=/etc/agent/agent.yaml - - -server.http.address=0.0.0.0:80 - env: - - name: HOSTNAME - valueFrom: - fieldRef: - fieldPath: spec.nodeName - image: grafana/agent:v0.39.0 - imagePullPolicy: IfNotPresent - name: grafana-agent-traces - ports: - - containerPort: 80 - name: http-metrics - - containerPort: 6831 - name: thrift-compact - protocol: UDP - - containerPort: 6832 - name: thrift-binary - protocol: UDP - - containerPort: 14268 - name: thrift-http - protocol: TCP - - containerPort: 14250 - name: thrift-grpc - protocol: TCP - - containerPort: 9411 - name: zipkin - protocol: TCP - - containerPort: 4317 - name: otlp-grpc - protocol: TCP - - containerPort: 4318 - name: otlp-http - protocol: TCP - - containerPort: 55678 - name: opencensus - protocol: TCP - volumeMounts: - - mountPath: /etc/agent - name: grafana-agent-traces - serviceAccountName: grafana-agent-traces - volumes: - - configMap: - name: grafana-agent-traces - name: grafana-agent-traces diff --git a/production/kubernetes/build/build.sh b/production/kubernetes/build/build.sh deleted file mode 100755 index 474afb2f1235..000000000000 --- a/production/kubernetes/build/build.sh +++ /dev/null @@ -1,15 +0,0 @@ -#!/usr/bin/env bash -# shellcheck shell=bash - -set +e - -DIRNAME=$(dirname "$0") - -pushd "${DIRNAME}" || exit 1 -# Make sure dependencies are up to date -jb install -tk show --dangerous-allow-redirect ./templates/bare > "${PWD}/../agent-bare.yaml" -tk show --dangerous-allow-redirect ./templates/loki > "${PWD}/../agent-loki.yaml" -tk show --dangerous-allow-redirect ./templates/traces > "${PWD}/../agent-traces.yaml" -tk show --dangerous-allow-redirect ./templates/operator > "${PWD}/../../operator/templates/agent-operator.yaml" -popd || exit 1 diff --git a/production/kubernetes/build/jsonnetfile.json b/production/kubernetes/build/jsonnetfile.json deleted file mode 100644 index 392936f6804d..000000000000 --- a/production/kubernetes/build/jsonnetfile.json +++ /dev/null @@ -1,49 +0,0 @@ -{ - "version": 1, - "dependencies": [ - { - "source": { - "git": { - "remote": "https://github.com/grafana/jsonnet-libs.git", - "subdir": "ksonnet-util" - } - }, - "version": "master" - }, - { - "source": { - "git": { - "remote": "https://github.com/jsonnet-libs/k8s-libsonnet.git", - "subdir": "1.21" - } - }, - "version": "main" - }, - { - "source": { - "git": { - "remote": "https://github.com/kubernetes/kube-state-metrics.git", - "subdir": "jsonnet/kube-state-metrics" - } - }, - "version": "v2.5.0" - }, - { - "source": { - "local": { - "directory": "../../tanka/grafana-agent" - } - }, - "version": "" - }, - { - "source": { - "local": { - "directory": "../../tanka/grafana-agent-operator" - } - }, - "version": "" - } - ], - "legacyImports": true -} diff --git a/production/kubernetes/build/jsonnetfile.lock.json b/production/kubernetes/build/jsonnetfile.lock.json deleted file mode 100644 index 3ed712040c13..000000000000 --- a/production/kubernetes/build/jsonnetfile.lock.json +++ /dev/null @@ -1,74 +0,0 @@ -{ - "version": 1, - "dependencies": [ - { - "source": { - "git": { - "remote": "https://github.com/grafana/jsonnet-libs.git", - "subdir": "ksonnet-util" - } - }, - "version": "28a9c400acbc02994ea8b08494571c7b476096b6", - "sum": "OxgtIWL4hjvG0xkMwUzZ7Yjs52zUhLhaVQpwHCbqf8A=" - }, - { - "source": { - "git": { - "remote": "https://github.com/jsonnet-libs/grafana-agent-libsonnet.git", - "subdir": "0.26" - } - }, - "version": "4763fb9dd69acd7c32ea34a708328ad7d1984100", - "sum": "AcBuxWZhGRgcfHFUxYRUOhAnQ9FnEP37fVl68jAQNc8=", - "name": "agent-operator-gen" - }, - { - "source": { - "git": { - "remote": "https://github.com/jsonnet-libs/k8s-libsonnet.git", - "subdir": "1.21" - } - }, - "version": "f8efa81cf15257bd151b97e31599e20b2ba5311b", - "sum": "FYub7WxElJkqjjXA++DemsKHwsPqUFW945BTgpVop6Q=" - }, - { - "source": { - "git": { - "remote": "https://github.com/jsonnet-libs/prometheus-operator-libsonnet.git", - "subdir": "0.57" - } - }, - "version": "daddbdd13374107f78a2489301f7c23ae1eb0b16", - "sum": "8+yZ7FalORuq5ZGpqSnSa+/4YQcPa7x9rClXcjgGCq0=", - "name": "prom-operator-gen" - }, - { - "source": { - "git": { - "remote": "https://github.com/kubernetes/kube-state-metrics.git", - "subdir": "jsonnet/kube-state-metrics" - } - }, - "version": "0567e1e1b981755e563d2244fa1659563f2cddbc", - "sum": "P0dCnbzyPScQGNXwXRcwiPkMLeTq0IPNbSTysDbySnM=" - }, - { - "source": { - "local": { - "directory": "../../tanka/grafana-agent" - } - }, - "version": "" - }, - { - "source": { - "local": { - "directory": "../../tanka/grafana-agent-operator" - } - }, - "version": "" - } - ], - "legacyImports": false -} diff --git a/production/kubernetes/build/lib/k.libsonnet b/production/kubernetes/build/lib/k.libsonnet deleted file mode 100644 index 3004bc3cf935..000000000000 --- a/production/kubernetes/build/lib/k.libsonnet +++ /dev/null @@ -1 +0,0 @@ -(import 'github.com/jsonnet-libs/k8s-libsonnet/1.21/main.libsonnet') diff --git a/production/kubernetes/build/lib/version.libsonnet b/production/kubernetes/build/lib/version.libsonnet deleted file mode 100644 index 70fb0ff0cffe..000000000000 --- a/production/kubernetes/build/lib/version.libsonnet +++ /dev/null @@ -1 +0,0 @@ -'grafana/agent:v0.39.0' diff --git a/production/kubernetes/build/templates/bare/main.jsonnet b/production/kubernetes/build/templates/bare/main.jsonnet deleted file mode 100644 index fda8512f0291..000000000000 --- a/production/kubernetes/build/templates/bare/main.jsonnet +++ /dev/null @@ -1,41 +0,0 @@ -local agent = import 'grafana-agent/v2/main.libsonnet'; -local k = import 'ksonnet-util/kausal.libsonnet'; - -local pvc = k.core.v1.persistentVolumeClaim; -local volumeMount = k.core.v1.volumeMount; -local containerPort = k.core.v1.containerPort; - -{ - agent: - agent.new(name='grafana-agent', namespace='${NAMESPACE}') + - agent.withStatefulSetController( - replicas=1, - volumeClaims=[ - pvc.new() + - pvc.mixin.metadata.withName('agent-wal') + - pvc.mixin.metadata.withNamespace('${NAMESPACE}') + - pvc.mixin.spec.withAccessModes('ReadWriteOnce') + - pvc.mixin.spec.resources.withRequests({ storage: '5Gi' }), - ], - ) + - agent.withConfigHash(false) + - agent.withArgsMixin({ - 'enable-features': 'integrations-next' - },) + - // add dummy config or else will fail - agent.withAgentConfig({ - server: { log_level: 'error' }, - }) + - agent.withVolumeMountsMixin([volumeMount.new('agent-wal', '/var/lib/agent')]) + - // headless svc needed by statefulset - agent.withService() + - { - controller_service+: { - spec+: { - clusterIP: 'None', - }, - }, - } + - // hack to disable ConfigMap - { configMap:: super.configMap }, -} diff --git a/production/kubernetes/build/templates/bare/spec.json b/production/kubernetes/build/templates/bare/spec.json deleted file mode 100644 index d97d07154983..000000000000 --- a/production/kubernetes/build/templates/bare/spec.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "apiVersion": "tanka.dev/v1alpha1", - "kind": "Environment", - "metadata": { - "name": "template" - }, - "spec": { - "apiServer": "", - "namespace": "" - } -} diff --git a/production/kubernetes/build/templates/base-sigv4/main.jsonnet b/production/kubernetes/build/templates/base-sigv4/main.jsonnet deleted file mode 100644 index 5297475e61d9..000000000000 --- a/production/kubernetes/build/templates/base-sigv4/main.jsonnet +++ /dev/null @@ -1,31 +0,0 @@ -local agent = import 'grafana-agent/grafana-agent.libsonnet'; - -local k = import 'ksonnet-util/kausal.libsonnet'; -local serviceAccount = k.core.v1.serviceAccount; - -agent { - _images+:: { - agent: (import 'version.libsonnet'), - }, - - _config+:: { - namespace: '${NAMESPACE}', - agent_remote_write: [{ - url: '${REMOTE_WRITE_URL}', - sigv4: { - region: '${REGION}', - }, - }], - - // Since the config map isn't managed by Tanka, we don't want to - // add the configmap's hash as an annotation for the Kubernetes - // YAML manifest. - agent_config_hash_annotation: false, - }, - - agent_rbac+: { - service_account+: serviceAccount.mixin.metadata.withAnnotationsMixin({ - 'eks.amazonaws.com/role-arn': '${ROLE_ARN}', - }), - }, -} diff --git a/production/kubernetes/build/templates/base-sigv4/spec.json b/production/kubernetes/build/templates/base-sigv4/spec.json deleted file mode 100644 index d97d07154983..000000000000 --- a/production/kubernetes/build/templates/base-sigv4/spec.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "apiVersion": "tanka.dev/v1alpha1", - "kind": "Environment", - "metadata": { - "name": "template" - }, - "spec": { - "apiServer": "", - "namespace": "" - } -} diff --git a/production/kubernetes/build/templates/base/main.jsonnet b/production/kubernetes/build/templates/base/main.jsonnet deleted file mode 100644 index 687b6ad74ddd..000000000000 --- a/production/kubernetes/build/templates/base/main.jsonnet +++ /dev/null @@ -1,23 +0,0 @@ -local agent = import 'grafana-agent/grafana-agent.libsonnet'; - -agent { - _images+:: { - agent: (import 'version.libsonnet'), - }, - - _config+:: { - namespace: '${NAMESPACE}', - agent_remote_write: [{ - url: '${REMOTE_WRITE_URL}', - basic_auth: { - username: '${REMOTE_WRITE_USERNAME}', - password: '${REMOTE_WRITE_PASSWORD}', - }, - }], - - // Since the config map isn't managed by Tanka, we don't want to - // add the configmap's hash as an annotation for the Kubernetes - // YAML manifest. - agent_config_hash_annotation: false, - }, -} diff --git a/production/kubernetes/build/templates/base/spec.json b/production/kubernetes/build/templates/base/spec.json deleted file mode 100644 index d97d07154983..000000000000 --- a/production/kubernetes/build/templates/base/spec.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "apiVersion": "tanka.dev/v1alpha1", - "kind": "Environment", - "metadata": { - "name": "template" - }, - "spec": { - "apiServer": "", - "namespace": "" - } -} diff --git a/production/kubernetes/build/templates/loki/main.jsonnet b/production/kubernetes/build/templates/loki/main.jsonnet deleted file mode 100644 index 1ec9540e62e8..000000000000 --- a/production/kubernetes/build/templates/loki/main.jsonnet +++ /dev/null @@ -1,17 +0,0 @@ -local agent = import 'grafana-agent/v2/main.libsonnet'; -local k = import 'ksonnet-util/kausal.libsonnet'; - -{ - agent: - agent.new(name='grafana-agent-logs', namespace='${NAMESPACE}') + - agent.withDaemonSetController() + - agent.withConfigHash(false) + - // add dummy config or else will fail - agent.withAgentConfig({ - server: { log_level: 'error' }, - }) + - agent.withLogVolumeMounts() + - agent.withLogPermissions() + - // hack to disable configmap - { configMap:: super.configMap } -} diff --git a/production/kubernetes/build/templates/loki/spec.json b/production/kubernetes/build/templates/loki/spec.json deleted file mode 100644 index d97d07154983..000000000000 --- a/production/kubernetes/build/templates/loki/spec.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "apiVersion": "tanka.dev/v1alpha1", - "kind": "Environment", - "metadata": { - "name": "template" - }, - "spec": { - "apiServer": "", - "namespace": "" - } -} diff --git a/production/kubernetes/build/templates/operator/main.jsonnet b/production/kubernetes/build/templates/operator/main.jsonnet deleted file mode 100644 index efc5b6e9df9f..000000000000 --- a/production/kubernetes/build/templates/operator/main.jsonnet +++ /dev/null @@ -1,160 +0,0 @@ -local k = import 'ksonnet-util/kausal.libsonnet'; -local secret = k.core.v1.secret; -local pvc = k.core.v1.persistentVolumeClaim; - -local gen = import 'agent-operator-gen/main.libsonnet'; -local ga = gen.monitoring.v1alpha1.grafanaAgent; -local mi = gen.monitoring.v1alpha1.metricsInstance; -local li = gen.monitoring.v1alpha1.logsInstance; -local pl = gen.monitoring.v1alpha1.podLogs; -local int = gen.monitoring.v1alpha1.integration; - -local op = import 'grafana-agent-operator/operator.libsonnet'; -local ga_util = import 'grafana-agent-operator/util/grafana-agent.libsonnet'; -local mi_util = import 'grafana-agent-operator/util/metricsinstance.libsonnet'; -local li_util = import 'grafana-agent-operator/util/logsinstance.libsonnet'; -local pl_util = import 'grafana-agent-operator/util/k8slogs.libsonnet'; -local mon_util = import 'grafana-agent-operator/util/k8smonitors.libsonnet'; -local int_util = import 'grafana-agent-operator/util/integrations.libsonnet'; - -local ksm = import 'kube-state-metrics/kube-state-metrics.libsonnet'; - -{ - local this = self, - - _images:: { - agent: 'grafana/agent:v0.39.0', - agent_operator: 'grafana/agent-operator:v0.39.0', - ksm: 'registry.k8s.io/kube-state-metrics/kube-state-metrics:v2.5.0', - }, - - _config:: { - namespace: '${NAMESPACE}', - metrics_url: '${METRICS_URL}', - metrics_user: '${METRICS_USER}', - metrics_key: '${METRICS_KEY}', - logs_url: '${LOGS_URL}', - logs_user: '${LOGS_USER}', - logs_key: '${LOGS_KEY}', - cluster_label: { cluster: '${CLUSTER}' }, - kubelet_job: 'kubelet', - cadvisor_job: 'cadvisor', - ksm_job: 'kube-state-metrics', - ksm_version: '2.5.0', - }, - - operator: - op.new(name='grafana-agent-operator', namespace=this._config.namespace, image=this._images.agent_operator, serviceAccount='grafana-agent-operator') + - op.withRbac(name='grafana-agent-operator', namespace=this._config.namespace), - - grafana_agent: - ga.new(name='grafana-agent') + - ga.metadata.withNamespace(this._config.namespace) + - ga.spec.withServiceAccountName('grafana-agent') + - ga.spec.withImage(this._images.agent) + - ga.spec.metrics.instanceSelector.withMatchLabels({ agent: 'grafana-agent' }) + - ga.spec.logs.instanceSelector.withMatchLabels({ agent: 'grafana-agent' }) + - ga.spec.integrations.selector.withMatchLabels({ agent: 'grafana-agent' }) + - ga.spec.metrics.withExternalLabels(this._config.cluster_label), - rbac: - ga_util.withRbac(name='grafana-agent', namespace=this._config.namespace), - - metrics_instance: - mi.new(name='grafana-agent-metrics') + - mi.metadata.withNamespace(this._config.namespace) + - mi.metadata.withLabels({ agent: 'grafana-agent' }) + - mi.spec.serviceMonitorSelector.withMatchLabels({ instance: 'primary' }) + - mi_util.withRemoteWrite(secretName='metrics-secret', metricsUrl=this._config.metrics_url) + - mi_util.withNilServiceMonitorNamespace(), - metrics_secret: - secret.new('metrics-secret', {}) + - secret.withStringData({ - username: this._config.metrics_user, - password: this._config.metrics_key, - }) + secret.mixin.metadata.withNamespace(this._config.namespace), - - logs_instance: - li.new(name='grafana-agent-logs') + - li.metadata.withNamespace(this._config.namespace) + - li.metadata.withLabels({ agent: 'grafana-agent' }) + - li.spec.podLogsSelector.withMatchLabels({ instance: 'primary' }) + - li_util.withLogsClient(secretName='logs-secret', logsUrl=this._config.logs_url, externalLabels=this._config.cluster_label) + - li_util.withNilPodLogsNamespace(), - logs_secret: - secret.new('logs-secret', {}) + - secret.withStringData({ - username: this._config.logs_user, - password: this._config.logs_key, - }) + secret.mixin.metadata.withNamespace(this._config.namespace), - - pod_logs: - pl.new('kubernetes-logs') + - pl.metadata.withNamespace(this._config.namespace) + - pl.metadata.withLabels({ instance: 'primary' }) + - pl.spec.withPipelineStages(pl.spec.pipelineStages.withCri({})) + - pl.spec.namespaceSelector.withAny(true) + - pl.spec.selector.withMatchLabels({}) + - pl.spec.withRelabelings(pl_util.withK8sLogsRelabeling()), - - k8s_monitors: [ - mon_util.newKubernetesMonitor( - name='kubelet-monitor', - namespace=this._config.namespace, - monitorLabels={ instance: 'primary' }, - targetNamespace='default', - targetLabels={ 'app.kubernetes.io/name': 'kubelet' }, - jobLabel=this._config.kubelet_job, - metricsPath='/metrics', - allowlist=false, - allowlistMetrics=[] - ), - mon_util.newKubernetesMonitor( - name='cadvisor-monitor', - namespace=this._config.namespace, - monitorLabels={ instance: 'primary' }, - targetNamespace='default', - targetLabels={ 'app.kubernetes.io/name': 'kubelet' }, - jobLabel=this._config.cadvisor_job, - metricsPath='/metrics/cadvisor', - allowlist=false, - allowlistMetrics=[] - ), - mon_util.newServiceMonitor( - name='ksm-monitor', - namespace=this._config.namespace, - monitorLabels={ instance: 'primary' }, - targetNamespace=this._config.namespace, - targetLabels={ 'app.kubernetes.io/name': 'kube-state-metrics' }, - jobLabel=this._config.ksm_job, - metricsPath='/metrics', - allowlist=false, - allowlistMetrics=[] - ), - ], - - kube_state_metrics: - ksm { - name:: 'kube-state-metrics', - namespace:: this._config.namespace, - version:: this._config.ksm_version, - image:: this._images.ksm, - }, - - events: - int.new('agent-eventhandler') + - int.metadata.withNamespace(this._config.namespace) + - int.metadata.withLabels({ agent: 'grafana-agent' }) + - int.spec.withName('eventhandler') + - int.spec.type.withUnique(true) + - int.spec.withConfig({ - logs_instance: this._config.namespace + '/' + 'grafana-agent-logs', - cache_path: '/etc/eventhandler/eventhandler.cache', - }) + - int_util.withPVC('agent-eventhandler'), - pvc: - pvc.new('agent-eventhandler') + - pvc.mixin.metadata.withNamespace(this._config.namespace) + - pvc.mixin.spec.withAccessModes('ReadWriteOnce') + - pvc.mixin.spec.resources.withRequests({ storage: '1Gi' }), - -} diff --git a/production/kubernetes/build/templates/operator/spec.json b/production/kubernetes/build/templates/operator/spec.json deleted file mode 100644 index d97d07154983..000000000000 --- a/production/kubernetes/build/templates/operator/spec.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "apiVersion": "tanka.dev/v1alpha1", - "kind": "Environment", - "metadata": { - "name": "template" - }, - "spec": { - "apiServer": "", - "namespace": "" - } -} diff --git a/production/kubernetes/build/templates/traces/main.jsonnet b/production/kubernetes/build/templates/traces/main.jsonnet deleted file mode 100644 index 4868b6829aaf..000000000000 --- a/production/kubernetes/build/templates/traces/main.jsonnet +++ /dev/null @@ -1,41 +0,0 @@ -local agent = import 'grafana-agent/v2/main.libsonnet'; -local k = import 'ksonnet-util/kausal.libsonnet'; - -local containerPort = k.core.v1.containerPort; - -local newPort(name, portNumber, protocol='TCP') = - // Port names for pods cannot be longer than 15 characters. - if std.length(name) > 15 then - error 'port name cannot be longer than 15 characters' - else containerPort.new(name, portNumber) + containerPort.withProtocol(protocol); - -{ - agent: - agent.new(name='grafana-agent-traces', namespace='${NAMESPACE}') + - agent.withDeploymentController(replicas=1) + - agent.withConfigHash(false) + - agent.withPortsMixin([ - // Jaeger receiver - newPort('thrift-compact', 6831, 'UDP'), - newPort('thrift-binary', 6832, 'UDP'), - newPort('thrift-http', 14268, 'TCP'), - newPort('thrift-grpc', 14250, 'TCP'), - - // Zipkin - newPort('zipkin', 9411, 'TCP'), - - // OTLP - newPort('otlp-grpc', 4317, 'TCP'), - newPort('otlp-http', 4318, 'TCP'), - - // Opencensus - newPort('opencensus', 55678, 'TCP'), - ]) + - agent.withService() + - // add dummy config or will fail - agent.withAgentConfig({ - server: { log_level: 'error' }, - }) + - // remove configMap for generated manifests - { configMap:: super.configMap } -} diff --git a/production/kubernetes/build/templates/traces/spec.json b/production/kubernetes/build/templates/traces/spec.json deleted file mode 100644 index d97d07154983..000000000000 --- a/production/kubernetes/build/templates/traces/spec.json +++ /dev/null @@ -1,11 +0,0 @@ -{ - "apiVersion": "tanka.dev/v1alpha1", - "kind": "Environment", - "metadata": { - "name": "template" - }, - "spec": { - "apiServer": "", - "namespace": "" - } -} diff --git a/production/kubernetes/install-bare.sh b/production/kubernetes/install-bare.sh deleted file mode 100644 index 32127903a224..000000000000 --- a/production/kubernetes/install-bare.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/usr/bin/env bash -# shellcheck shell=bash - -# -# install-bare.sh is an installer for the Agent without a ConfigMap. It is -# used during the Grafana Cloud integrations wizard and is not recommended -# to be used directly. Instead of calling this script directly, please -# make a copy of ./agent-bare.yaml and modify it for your needs. -# -# Note that agent-bare.yaml does not have a ConfigMap, so the Grafana Agent -# will not launch until one is created. For more information on setting up -# a ConfigMap, please refer to: -# -# Metrics quickstart: https://grafana.com/docs/grafana-cloud/quickstart/agent-k8s/k8s_agent_metrics/ -# Logs quickstart: https://grafana.com/docs/grafana-cloud/quickstart/agent-k8s/k8s_agent_logs/ -# - -check_installed() { - if ! type "$1" >/dev/null 2>&1; then - echo "error: $1 not installed" >&2 - exit 1 - fi -} - -check_installed curl -check_installed envsubst - -MANIFEST_BRANCH=v0.39.0 -MANIFEST_URL=${MANIFEST_URL:-https://raw.githubusercontent.com/grafana/agent/${MANIFEST_BRANCH}/production/kubernetes/agent-bare.yaml} -NAMESPACE=${NAMESPACE:-default} - -export NAMESPACE - -curl -fsSL "$MANIFEST_URL" | envsubst diff --git a/production/operator/crds/monitoring.coreos.com_podmonitors.yaml b/production/operator/crds/monitoring.coreos.com_podmonitors.yaml deleted file mode 100644 index 3e1fae0fc527..000000000000 --- a/production/operator/crds/monitoring.coreos.com_podmonitors.yaml +++ /dev/null @@ -1,679 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.9.2 - creationTimestamp: null - name: podmonitors.monitoring.coreos.com -spec: - group: monitoring.coreos.com - names: - categories: - - prometheus-operator - kind: PodMonitor - listKind: PodMonitorList - plural: podmonitors - shortNames: - - pmon - singular: podmonitor - scope: Namespaced - versions: - - name: v1 - schema: - openAPIV3Schema: - description: PodMonitor defines monitoring for a set of pods. - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: Specification of desired Pod selection for target discovery - by Prometheus. - properties: - attachMetadata: - description: Attaches node metadata to discovered targets. Requires - Prometheus v2.35.0 and above. - properties: - node: - description: When set to true, Prometheus must have permissions - to get Nodes. - type: boolean - type: object - jobLabel: - description: The label to use to retrieve the job name from. - type: string - labelLimit: - description: Per-scrape limit on number of labels that will be accepted - for a sample. Only valid in Prometheus versions 2.27.0 and newer. - format: int64 - type: integer - labelNameLengthLimit: - description: Per-scrape limit on length of labels name that will be - accepted for a sample. Only valid in Prometheus versions 2.27.0 - and newer. - format: int64 - type: integer - labelValueLengthLimit: - description: Per-scrape limit on length of labels value that will - be accepted for a sample. Only valid in Prometheus versions 2.27.0 - and newer. - format: int64 - type: integer - namespaceSelector: - description: Selector to select which namespaces the Endpoints objects - are discovered from. - properties: - any: - description: Boolean describing whether all namespaces are selected - in contrast to a list restricting them. - type: boolean - matchNames: - description: List of namespace names to select from. - items: - type: string - type: array - type: object - podMetricsEndpoints: - description: A list of endpoints allowed as part of this PodMonitor. - items: - description: PodMetricsEndpoint defines a scrapeable endpoint of - a Kubernetes Pod serving Prometheus metrics. - properties: - authorization: - description: Authorization section for this endpoint - properties: - credentials: - description: The secret's key that contains the credentials - of the request - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must - be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: - description: Set the authentication type. Defaults to Bearer, - Basic will cause an error - type: string - type: object - basicAuth: - description: 'BasicAuth allow an endpoint to authenticate over - basic authentication. More info: https://prometheus.io/docs/operating/configuration/#endpoint' - properties: - password: - description: The secret in the service monitor namespace - that contains the password for authentication. - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must - be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - username: - description: The secret in the service monitor namespace - that contains the username for authentication. - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must - be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - bearerTokenSecret: - description: Secret to mount to read bearer token for scraping - targets. The secret needs to be in the same namespace as the - pod monitor and accessible by the Prometheus Operator. - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must - be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - enableHttp2: - description: Whether to enable HTTP2. - type: boolean - filterRunning: - description: 'Drop pods that are not running. (Failed, Succeeded). - Enabled by default. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase' - type: boolean - followRedirects: - description: FollowRedirects configures whether scrape requests - follow HTTP 3xx redirects. - type: boolean - honorLabels: - description: HonorLabels chooses the metric's labels on collisions - with target labels. - type: boolean - honorTimestamps: - description: HonorTimestamps controls whether Prometheus respects - the timestamps present in scraped data. - type: boolean - interval: - description: Interval at which metrics should be scraped If - not specified Prometheus' global scrape interval is used. - pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ - type: string - metricRelabelings: - description: MetricRelabelConfigs to apply to samples before - ingestion. - items: - description: 'RelabelConfig allows dynamic rewriting of the - label set, being applied to samples before ingestion. It - defines ``-section of Prometheus - configuration. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs' - properties: - action: - default: replace - description: Action to perform based on regex matching. - Default is 'replace'. uppercase and lowercase actions - require Prometheus >= 2.36. - enum: - - replace - - Replace - - keep - - Keep - - drop - - Drop - - hashmod - - HashMod - - labelmap - - LabelMap - - labeldrop - - LabelDrop - - labelkeep - - LabelKeep - - lowercase - - Lowercase - - uppercase - - Uppercase - - keepequal - - KeepEqual - - dropequal - - DropEqual - type: string - modulus: - description: Modulus to take of the hash of the source - label values. - format: int64 - type: integer - regex: - description: Regular expression against which the extracted - value is matched. Default is '(.*)' - type: string - replacement: - description: Replacement value against which a regex replace - is performed if the regular expression matches. Regex - capture groups are available. Default is '$1' - type: string - separator: - description: Separator placed between concatenated source - label values. default is ';'. - type: string - sourceLabels: - description: The source labels select values from existing - labels. Their content is concatenated using the configured - separator and matched against the configured regular - expression for the replace, keep, and drop actions. - items: - description: LabelName is a valid Prometheus label name - which may only contain ASCII letters, numbers, as - well as underscores. - pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ - type: string - type: array - targetLabel: - description: Label to which the resulting value is written - in a replace action. It is mandatory for replace actions. - Regex capture groups are available. - type: string - type: object - type: array - oauth2: - description: OAuth2 for the URL. Only valid in Prometheus versions - 2.27.0 and newer. - properties: - clientId: - description: The secret or configmap containing the OAuth2 - client id - properties: - configMap: - description: ConfigMap containing data to use for the - targets. - properties: - key: - description: The key to select. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the ConfigMap or its - key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - secret: - description: Secret containing data to use for the targets. - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the Secret or its key - must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - clientSecret: - description: The secret containing the OAuth2 client secret - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must - be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - endpointParams: - additionalProperties: - type: string - description: Parameters to append to the token URL - type: object - scopes: - description: OAuth2 scopes used for the token request - items: - type: string - type: array - tokenUrl: - description: The URL to fetch the token from - minLength: 1 - type: string - required: - - clientId - - clientSecret - - tokenUrl - type: object - params: - additionalProperties: - items: - type: string - type: array - description: Optional HTTP URL parameters - type: object - path: - description: HTTP path to scrape for metrics. If empty, Prometheus - uses the default value (e.g. `/metrics`). - type: string - port: - description: Name of the pod port this endpoint refers to. Mutually - exclusive with targetPort. - type: string - proxyUrl: - description: ProxyURL eg http://proxyserver:2195 Directs scrapes - to proxy through this endpoint. - type: string - relabelings: - description: 'RelabelConfigs to apply to samples before scraping. - Prometheus Operator automatically adds relabelings for a few - standard Kubernetes fields. The original scrape job''s name - is available via the `__tmp_prometheus_job_name` label. More - info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config' - items: - description: 'RelabelConfig allows dynamic rewriting of the - label set, being applied to samples before ingestion. It - defines ``-section of Prometheus - configuration. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs' - properties: - action: - default: replace - description: Action to perform based on regex matching. - Default is 'replace'. uppercase and lowercase actions - require Prometheus >= 2.36. - enum: - - replace - - Replace - - keep - - Keep - - drop - - Drop - - hashmod - - HashMod - - labelmap - - LabelMap - - labeldrop - - LabelDrop - - labelkeep - - LabelKeep - - lowercase - - Lowercase - - uppercase - - Uppercase - - keepequal - - KeepEqual - - dropequal - - DropEqual - type: string - modulus: - description: Modulus to take of the hash of the source - label values. - format: int64 - type: integer - regex: - description: Regular expression against which the extracted - value is matched. Default is '(.*)' - type: string - replacement: - description: Replacement value against which a regex replace - is performed if the regular expression matches. Regex - capture groups are available. Default is '$1' - type: string - separator: - description: Separator placed between concatenated source - label values. default is ';'. - type: string - sourceLabels: - description: The source labels select values from existing - labels. Their content is concatenated using the configured - separator and matched against the configured regular - expression for the replace, keep, and drop actions. - items: - description: LabelName is a valid Prometheus label name - which may only contain ASCII letters, numbers, as - well as underscores. - pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ - type: string - type: array - targetLabel: - description: Label to which the resulting value is written - in a replace action. It is mandatory for replace actions. - Regex capture groups are available. - type: string - type: object - type: array - scheme: - description: HTTP scheme to use for scraping. `http` and `https` - are the expected values unless you rewrite the `__scheme__` - label via relabeling. If empty, Prometheus uses the default - value `http`. - enum: - - http - - https - type: string - scrapeTimeout: - description: Timeout after which the scrape is ended If not - specified, the Prometheus global scrape interval is used. - pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ - type: string - targetPort: - anyOf: - - type: integer - - type: string - description: 'Deprecated: Use ''port'' instead.' - x-kubernetes-int-or-string: true - tlsConfig: - description: TLS configuration to use when scraping the endpoint. - properties: - ca: - description: Certificate authority used when verifying server - certificates. - properties: - configMap: - description: ConfigMap containing data to use for the - targets. - properties: - key: - description: The key to select. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the ConfigMap or its - key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - secret: - description: Secret containing data to use for the targets. - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the Secret or its key - must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - cert: - description: Client certificate to present when doing client-authentication. - properties: - configMap: - description: ConfigMap containing data to use for the - targets. - properties: - key: - description: The key to select. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the ConfigMap or its - key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - secret: - description: Secret containing data to use for the targets. - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the Secret or its key - must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - insecureSkipVerify: - description: Disable target certificate validation. - type: boolean - keySecret: - description: Secret containing the client key file for the - targets. - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must - be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - serverName: - description: Used to verify the hostname for the targets. - type: string - type: object - type: object - type: array - podTargetLabels: - description: PodTargetLabels transfers labels on the Kubernetes Pod - onto the target. - items: - type: string - type: array - sampleLimit: - description: SampleLimit defines per-scrape limit on number of scraped - samples that will be accepted. - format: int64 - type: integer - selector: - description: Selector to select Pod objects. - properties: - matchExpressions: - description: matchExpressions is a list of label selector requirements. - The requirements are ANDed. - items: - description: A label selector requirement is a selector that - contains values, a key, and an operator that relates the key - and values. - properties: - key: - description: key is the label key that the selector applies - to. - type: string - operator: - description: operator represents a key's relationship to - a set of values. Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of string values. If the - operator is In or NotIn, the values array must be non-empty. - If the operator is Exists or DoesNotExist, the values - array must be empty. This array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. A single - {key,value} in the matchLabels map is equivalent to an element - of matchExpressions, whose key field is "key", the operator - is "In", and the values array contains only "value". The requirements - are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - targetLimit: - description: TargetLimit defines a limit on the number of scraped - targets that will be accepted. - format: int64 - type: integer - required: - - podMetricsEndpoints - - selector - type: object - required: - - spec - type: object - served: true - storage: true diff --git a/production/operator/crds/monitoring.coreos.com_probes.yaml b/production/operator/crds/monitoring.coreos.com_probes.yaml deleted file mode 100644 index 7ece55d2ac5e..000000000000 --- a/production/operator/crds/monitoring.coreos.com_probes.yaml +++ /dev/null @@ -1,722 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.9.2 - creationTimestamp: null - name: probes.monitoring.coreos.com -spec: - group: monitoring.coreos.com - names: - categories: - - prometheus-operator - kind: Probe - listKind: ProbeList - plural: probes - shortNames: - - prb - singular: probe - scope: Namespaced - versions: - - name: v1 - schema: - openAPIV3Schema: - description: Probe defines monitoring for a set of static targets or ingresses. - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: Specification of desired Ingress selection for target discovery - by Prometheus. - properties: - authorization: - description: Authorization section for this endpoint - properties: - credentials: - description: The secret's key that contains the credentials of - the request - properties: - key: - description: The key of the secret to select from. Must be - a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must be - defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: - description: Set the authentication type. Defaults to Bearer, - Basic will cause an error - type: string - type: object - basicAuth: - description: 'BasicAuth allow an endpoint to authenticate over basic - authentication. More info: https://prometheus.io/docs/operating/configuration/#endpoint' - properties: - password: - description: The secret in the service monitor namespace that - contains the password for authentication. - properties: - key: - description: The key of the secret to select from. Must be - a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must be - defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - username: - description: The secret in the service monitor namespace that - contains the username for authentication. - properties: - key: - description: The key of the secret to select from. Must be - a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must be - defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - bearerTokenSecret: - description: Secret to mount to read bearer token for scraping targets. - The secret needs to be in the same namespace as the probe and accessible - by the Prometheus Operator. - properties: - key: - description: The key of the secret to select from. Must be a - valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - interval: - description: Interval at which targets are probed using the configured - prober. If not specified Prometheus' global scrape interval is used. - pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ - type: string - jobName: - description: The job name assigned to scraped metrics by default. - type: string - labelLimit: - description: Per-scrape limit on number of labels that will be accepted - for a sample. Only valid in Prometheus versions 2.27.0 and newer. - format: int64 - type: integer - labelNameLengthLimit: - description: Per-scrape limit on length of labels name that will be - accepted for a sample. Only valid in Prometheus versions 2.27.0 - and newer. - format: int64 - type: integer - labelValueLengthLimit: - description: Per-scrape limit on length of labels value that will - be accepted for a sample. Only valid in Prometheus versions 2.27.0 - and newer. - format: int64 - type: integer - metricRelabelings: - description: MetricRelabelConfigs to apply to samples before ingestion. - items: - description: 'RelabelConfig allows dynamic rewriting of the label - set, being applied to samples before ingestion. It defines ``-section - of Prometheus configuration. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs' - properties: - action: - default: replace - description: Action to perform based on regex matching. Default - is 'replace'. uppercase and lowercase actions require Prometheus - >= 2.36. - enum: - - replace - - Replace - - keep - - Keep - - drop - - Drop - - hashmod - - HashMod - - labelmap - - LabelMap - - labeldrop - - LabelDrop - - labelkeep - - LabelKeep - - lowercase - - Lowercase - - uppercase - - Uppercase - - keepequal - - KeepEqual - - dropequal - - DropEqual - type: string - modulus: - description: Modulus to take of the hash of the source label - values. - format: int64 - type: integer - regex: - description: Regular expression against which the extracted - value is matched. Default is '(.*)' - type: string - replacement: - description: Replacement value against which a regex replace - is performed if the regular expression matches. Regex capture - groups are available. Default is '$1' - type: string - separator: - description: Separator placed between concatenated source label - values. default is ';'. - type: string - sourceLabels: - description: The source labels select values from existing labels. - Their content is concatenated using the configured separator - and matched against the configured regular expression for - the replace, keep, and drop actions. - items: - description: LabelName is a valid Prometheus label name which - may only contain ASCII letters, numbers, as well as underscores. - pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ - type: string - type: array - targetLabel: - description: Label to which the resulting value is written in - a replace action. It is mandatory for replace actions. Regex - capture groups are available. - type: string - type: object - type: array - module: - description: 'The module to use for probing specifying how to probe - the target. Example module configuring in the blackbox exporter: - https://github.com/prometheus/blackbox_exporter/blob/master/example.yml' - type: string - oauth2: - description: OAuth2 for the URL. Only valid in Prometheus versions - 2.27.0 and newer. - properties: - clientId: - description: The secret or configmap containing the OAuth2 client - id - properties: - configMap: - description: ConfigMap containing data to use for the targets. - properties: - key: - description: The key to select. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the ConfigMap or its key - must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - secret: - description: Secret containing data to use for the targets. - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must - be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - clientSecret: - description: The secret containing the OAuth2 client secret - properties: - key: - description: The key of the secret to select from. Must be - a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must be - defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - endpointParams: - additionalProperties: - type: string - description: Parameters to append to the token URL - type: object - scopes: - description: OAuth2 scopes used for the token request - items: - type: string - type: array - tokenUrl: - description: The URL to fetch the token from - minLength: 1 - type: string - required: - - clientId - - clientSecret - - tokenUrl - type: object - prober: - description: Specification for the prober to use for probing targets. - The prober.URL parameter is required. Targets cannot be probed if - left empty. - properties: - path: - default: /probe - description: Path to collect metrics from. Defaults to `/probe`. - type: string - proxyUrl: - description: Optional ProxyURL. - type: string - scheme: - description: HTTP scheme to use for scraping. `http` and `https` - are the expected values unless you rewrite the `__scheme__` - label via relabeling. If empty, Prometheus uses the default - value `http`. - enum: - - http - - https - type: string - url: - description: Mandatory URL of the prober. - type: string - required: - - url - type: object - sampleLimit: - description: SampleLimit defines per-scrape limit on number of scraped - samples that will be accepted. - format: int64 - type: integer - scrapeTimeout: - description: Timeout for scraping metrics from the Prometheus exporter. - If not specified, the Prometheus global scrape timeout is used. - pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ - type: string - targetLimit: - description: TargetLimit defines a limit on the number of scraped - targets that will be accepted. - format: int64 - type: integer - targets: - description: Targets defines a set of static or dynamically discovered - targets to probe. - properties: - ingress: - description: ingress defines the Ingress objects to probe and - the relabeling configuration. If `staticConfig` is also defined, - `staticConfig` takes precedence. - properties: - namespaceSelector: - description: From which namespaces to select Ingress objects. - properties: - any: - description: Boolean describing whether all namespaces - are selected in contrast to a list restricting them. - type: boolean - matchNames: - description: List of namespace names to select from. - items: - type: string - type: array - type: object - relabelingConfigs: - description: 'RelabelConfigs to apply to the label set of - the target before it gets scraped. The original ingress - address is available via the `__tmp_prometheus_ingress_address` - label. It can be used to customize the probed URL. The original - scrape job''s name is available via the `__tmp_prometheus_job_name` - label. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config' - items: - description: 'RelabelConfig allows dynamic rewriting of - the label set, being applied to samples before ingestion. - It defines ``-section of Prometheus - configuration. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs' - properties: - action: - default: replace - description: Action to perform based on regex matching. - Default is 'replace'. uppercase and lowercase actions - require Prometheus >= 2.36. - enum: - - replace - - Replace - - keep - - Keep - - drop - - Drop - - hashmod - - HashMod - - labelmap - - LabelMap - - labeldrop - - LabelDrop - - labelkeep - - LabelKeep - - lowercase - - Lowercase - - uppercase - - Uppercase - - keepequal - - KeepEqual - - dropequal - - DropEqual - type: string - modulus: - description: Modulus to take of the hash of the source - label values. - format: int64 - type: integer - regex: - description: Regular expression against which the extracted - value is matched. Default is '(.*)' - type: string - replacement: - description: Replacement value against which a regex - replace is performed if the regular expression matches. - Regex capture groups are available. Default is '$1' - type: string - separator: - description: Separator placed between concatenated source - label values. default is ';'. - type: string - sourceLabels: - description: The source labels select values from existing - labels. Their content is concatenated using the configured - separator and matched against the configured regular - expression for the replace, keep, and drop actions. - items: - description: LabelName is a valid Prometheus label - name which may only contain ASCII letters, numbers, - as well as underscores. - pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ - type: string - type: array - targetLabel: - description: Label to which the resulting value is written - in a replace action. It is mandatory for replace actions. - Regex capture groups are available. - type: string - type: object - type: array - selector: - description: Selector to select the Ingress objects. - properties: - matchExpressions: - description: matchExpressions is a list of label selector - requirements. The requirements are ANDed. - items: - description: A label selector requirement is a selector - that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label key that the selector - applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, NotIn, - Exists and DoesNotExist. - type: string - values: - description: values is an array of string values. - If the operator is In or NotIn, the values array - must be non-empty. If the operator is Exists or - DoesNotExist, the values array must be empty. - This array is replaced during a strategic merge - patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. - A single {key,value} in the matchLabels map is equivalent - to an element of matchExpressions, whose key field is - "key", the operator is "In", and the values array contains - only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - type: object - staticConfig: - description: 'staticConfig defines the static list of targets - to probe and the relabeling configuration. If `ingress` is also - defined, `staticConfig` takes precedence. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#static_config.' - properties: - labels: - additionalProperties: - type: string - description: Labels assigned to all metrics scraped from the - targets. - type: object - relabelingConfigs: - description: 'RelabelConfigs to apply to the label set of - the targets before it gets scraped. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config' - items: - description: 'RelabelConfig allows dynamic rewriting of - the label set, being applied to samples before ingestion. - It defines ``-section of Prometheus - configuration. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs' - properties: - action: - default: replace - description: Action to perform based on regex matching. - Default is 'replace'. uppercase and lowercase actions - require Prometheus >= 2.36. - enum: - - replace - - Replace - - keep - - Keep - - drop - - Drop - - hashmod - - HashMod - - labelmap - - LabelMap - - labeldrop - - LabelDrop - - labelkeep - - LabelKeep - - lowercase - - Lowercase - - uppercase - - Uppercase - - keepequal - - KeepEqual - - dropequal - - DropEqual - type: string - modulus: - description: Modulus to take of the hash of the source - label values. - format: int64 - type: integer - regex: - description: Regular expression against which the extracted - value is matched. Default is '(.*)' - type: string - replacement: - description: Replacement value against which a regex - replace is performed if the regular expression matches. - Regex capture groups are available. Default is '$1' - type: string - separator: - description: Separator placed between concatenated source - label values. default is ';'. - type: string - sourceLabels: - description: The source labels select values from existing - labels. Their content is concatenated using the configured - separator and matched against the configured regular - expression for the replace, keep, and drop actions. - items: - description: LabelName is a valid Prometheus label - name which may only contain ASCII letters, numbers, - as well as underscores. - pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ - type: string - type: array - targetLabel: - description: Label to which the resulting value is written - in a replace action. It is mandatory for replace actions. - Regex capture groups are available. - type: string - type: object - type: array - static: - description: The list of hosts to probe. - items: - type: string - type: array - type: object - type: object - tlsConfig: - description: TLS configuration to use when scraping the endpoint. - properties: - ca: - description: Certificate authority used when verifying server - certificates. - properties: - configMap: - description: ConfigMap containing data to use for the targets. - properties: - key: - description: The key to select. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the ConfigMap or its key - must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - secret: - description: Secret containing data to use for the targets. - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must - be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - cert: - description: Client certificate to present when doing client-authentication. - properties: - configMap: - description: ConfigMap containing data to use for the targets. - properties: - key: - description: The key to select. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the ConfigMap or its key - must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - secret: - description: Secret containing data to use for the targets. - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must - be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - insecureSkipVerify: - description: Disable target certificate validation. - type: boolean - keySecret: - description: Secret containing the client key file for the targets. - properties: - key: - description: The key of the secret to select from. Must be - a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must be - defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - serverName: - description: Used to verify the hostname for the targets. - type: string - type: object - type: object - required: - - spec - type: object - served: true - storage: true diff --git a/production/operator/crds/monitoring.coreos.com_servicemonitors.yaml b/production/operator/crds/monitoring.coreos.com_servicemonitors.yaml deleted file mode 100644 index 5d661184cfb4..000000000000 --- a/production/operator/crds/monitoring.coreos.com_servicemonitors.yaml +++ /dev/null @@ -1,709 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.9.2 - creationTimestamp: null - name: servicemonitors.monitoring.coreos.com -spec: - group: monitoring.coreos.com - names: - categories: - - prometheus-operator - kind: ServiceMonitor - listKind: ServiceMonitorList - plural: servicemonitors - shortNames: - - smon - singular: servicemonitor - scope: Namespaced - versions: - - name: v1 - schema: - openAPIV3Schema: - description: ServiceMonitor defines monitoring for a set of services. - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: Specification of desired Service selection for target discovery - by Prometheus. - properties: - attachMetadata: - description: Attaches node metadata to discovered targets. Requires - Prometheus v2.37.0 and above. - properties: - node: - description: When set to true, Prometheus must have permissions - to get Nodes. - type: boolean - type: object - endpoints: - description: A list of endpoints allowed as part of this ServiceMonitor. - items: - description: Endpoint defines a scrapeable endpoint serving Prometheus - metrics. - properties: - authorization: - description: Authorization section for this endpoint - properties: - credentials: - description: The secret's key that contains the credentials - of the request - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must - be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: - description: Set the authentication type. Defaults to Bearer, - Basic will cause an error - type: string - type: object - basicAuth: - description: 'BasicAuth allow an endpoint to authenticate over - basic authentication More info: https://prometheus.io/docs/operating/configuration/#endpoints' - properties: - password: - description: The secret in the service monitor namespace - that contains the password for authentication. - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must - be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - username: - description: The secret in the service monitor namespace - that contains the username for authentication. - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must - be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - bearerTokenFile: - description: File to read bearer token for scraping targets. - type: string - bearerTokenSecret: - description: Secret to mount to read bearer token for scraping - targets. The secret needs to be in the same namespace as the - service monitor and accessible by the Prometheus Operator. - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must - be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - enableHttp2: - description: Whether to enable HTTP2. - type: boolean - filterRunning: - description: 'Drop pods that are not running. (Failed, Succeeded). - Enabled by default. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase' - type: boolean - followRedirects: - description: FollowRedirects configures whether scrape requests - follow HTTP 3xx redirects. - type: boolean - honorLabels: - description: HonorLabels chooses the metric's labels on collisions - with target labels. - type: boolean - honorTimestamps: - description: HonorTimestamps controls whether Prometheus respects - the timestamps present in scraped data. - type: boolean - interval: - description: Interval at which metrics should be scraped If - not specified Prometheus' global scrape interval is used. - pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ - type: string - metricRelabelings: - description: MetricRelabelConfigs to apply to samples before - ingestion. - items: - description: 'RelabelConfig allows dynamic rewriting of the - label set, being applied to samples before ingestion. It - defines ``-section of Prometheus - configuration. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs' - properties: - action: - default: replace - description: Action to perform based on regex matching. - Default is 'replace'. uppercase and lowercase actions - require Prometheus >= 2.36. - enum: - - replace - - Replace - - keep - - Keep - - drop - - Drop - - hashmod - - HashMod - - labelmap - - LabelMap - - labeldrop - - LabelDrop - - labelkeep - - LabelKeep - - lowercase - - Lowercase - - uppercase - - Uppercase - - keepequal - - KeepEqual - - dropequal - - DropEqual - type: string - modulus: - description: Modulus to take of the hash of the source - label values. - format: int64 - type: integer - regex: - description: Regular expression against which the extracted - value is matched. Default is '(.*)' - type: string - replacement: - description: Replacement value against which a regex replace - is performed if the regular expression matches. Regex - capture groups are available. Default is '$1' - type: string - separator: - description: Separator placed between concatenated source - label values. default is ';'. - type: string - sourceLabels: - description: The source labels select values from existing - labels. Their content is concatenated using the configured - separator and matched against the configured regular - expression for the replace, keep, and drop actions. - items: - description: LabelName is a valid Prometheus label name - which may only contain ASCII letters, numbers, as - well as underscores. - pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ - type: string - type: array - targetLabel: - description: Label to which the resulting value is written - in a replace action. It is mandatory for replace actions. - Regex capture groups are available. - type: string - type: object - type: array - oauth2: - description: OAuth2 for the URL. Only valid in Prometheus versions - 2.27.0 and newer. - properties: - clientId: - description: The secret or configmap containing the OAuth2 - client id - properties: - configMap: - description: ConfigMap containing data to use for the - targets. - properties: - key: - description: The key to select. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the ConfigMap or its - key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - secret: - description: Secret containing data to use for the targets. - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the Secret or its key - must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - clientSecret: - description: The secret containing the OAuth2 client secret - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must - be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - endpointParams: - additionalProperties: - type: string - description: Parameters to append to the token URL - type: object - scopes: - description: OAuth2 scopes used for the token request - items: - type: string - type: array - tokenUrl: - description: The URL to fetch the token from - minLength: 1 - type: string - required: - - clientId - - clientSecret - - tokenUrl - type: object - params: - additionalProperties: - items: - type: string - type: array - description: Optional HTTP URL parameters - type: object - path: - description: HTTP path to scrape for metrics. If empty, Prometheus - uses the default value (e.g. `/metrics`). - type: string - port: - description: Name of the service port this endpoint refers to. - Mutually exclusive with targetPort. - type: string - proxyUrl: - description: ProxyURL eg http://proxyserver:2195 Directs scrapes - to proxy through this endpoint. - type: string - relabelings: - description: 'RelabelConfigs to apply to samples before scraping. - Prometheus Operator automatically adds relabelings for a few - standard Kubernetes fields. The original scrape job''s name - is available via the `__tmp_prometheus_job_name` label. More - info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#relabel_config' - items: - description: 'RelabelConfig allows dynamic rewriting of the - label set, being applied to samples before ingestion. It - defines ``-section of Prometheus - configuration. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs' - properties: - action: - default: replace - description: Action to perform based on regex matching. - Default is 'replace'. uppercase and lowercase actions - require Prometheus >= 2.36. - enum: - - replace - - Replace - - keep - - Keep - - drop - - Drop - - hashmod - - HashMod - - labelmap - - LabelMap - - labeldrop - - LabelDrop - - labelkeep - - LabelKeep - - lowercase - - Lowercase - - uppercase - - Uppercase - - keepequal - - KeepEqual - - dropequal - - DropEqual - type: string - modulus: - description: Modulus to take of the hash of the source - label values. - format: int64 - type: integer - regex: - description: Regular expression against which the extracted - value is matched. Default is '(.*)' - type: string - replacement: - description: Replacement value against which a regex replace - is performed if the regular expression matches. Regex - capture groups are available. Default is '$1' - type: string - separator: - description: Separator placed between concatenated source - label values. default is ';'. - type: string - sourceLabels: - description: The source labels select values from existing - labels. Their content is concatenated using the configured - separator and matched against the configured regular - expression for the replace, keep, and drop actions. - items: - description: LabelName is a valid Prometheus label name - which may only contain ASCII letters, numbers, as - well as underscores. - pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ - type: string - type: array - targetLabel: - description: Label to which the resulting value is written - in a replace action. It is mandatory for replace actions. - Regex capture groups are available. - type: string - type: object - type: array - scheme: - description: HTTP scheme to use for scraping. `http` and `https` - are the expected values unless you rewrite the `__scheme__` - label via relabeling. If empty, Prometheus uses the default - value `http`. - enum: - - http - - https - type: string - scrapeTimeout: - description: Timeout after which the scrape is ended If not - specified, the Prometheus global scrape timeout is used unless - it is less than `Interval` in which the latter is used. - pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ - type: string - targetPort: - anyOf: - - type: integer - - type: string - description: Name or number of the target port of the Pod behind - the Service, the port must be specified with container port - property. Mutually exclusive with port. - x-kubernetes-int-or-string: true - tlsConfig: - description: TLS configuration to use when scraping the endpoint - properties: - ca: - description: Certificate authority used when verifying server - certificates. - properties: - configMap: - description: ConfigMap containing data to use for the - targets. - properties: - key: - description: The key to select. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the ConfigMap or its - key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - secret: - description: Secret containing data to use for the targets. - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the Secret or its key - must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - caFile: - description: Path to the CA cert in the Prometheus container - to use for the targets. - type: string - cert: - description: Client certificate to present when doing client-authentication. - properties: - configMap: - description: ConfigMap containing data to use for the - targets. - properties: - key: - description: The key to select. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the ConfigMap or its - key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - secret: - description: Secret containing data to use for the targets. - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the Secret or its key - must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - certFile: - description: Path to the client cert file in the Prometheus - container for the targets. - type: string - insecureSkipVerify: - description: Disable target certificate validation. - type: boolean - keyFile: - description: Path to the client key file in the Prometheus - container for the targets. - type: string - keySecret: - description: Secret containing the client key file for the - targets. - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must - be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - serverName: - description: Used to verify the hostname for the targets. - type: string - type: object - type: object - type: array - jobLabel: - description: "JobLabel selects the label from the associated Kubernetes - service which will be used as the `job` label for all metrics. \n - For example: If in `ServiceMonitor.spec.jobLabel: foo` and in `Service.metadata.labels.foo: - bar`, then the `job=\"bar\"` label is added to all metrics. \n If - the value of this field is empty or if the label doesn't exist for - the given Service, the `job` label of the metrics defaults to the - name of the Kubernetes Service." - type: string - labelLimit: - description: Per-scrape limit on number of labels that will be accepted - for a sample. Only valid in Prometheus versions 2.27.0 and newer. - format: int64 - type: integer - labelNameLengthLimit: - description: Per-scrape limit on length of labels name that will be - accepted for a sample. Only valid in Prometheus versions 2.27.0 - and newer. - format: int64 - type: integer - labelValueLengthLimit: - description: Per-scrape limit on length of labels value that will - be accepted for a sample. Only valid in Prometheus versions 2.27.0 - and newer. - format: int64 - type: integer - namespaceSelector: - description: Selector to select which namespaces the Kubernetes Endpoints - objects are discovered from. - properties: - any: - description: Boolean describing whether all namespaces are selected - in contrast to a list restricting them. - type: boolean - matchNames: - description: List of namespace names to select from. - items: - type: string - type: array - type: object - podTargetLabels: - description: PodTargetLabels transfers labels on the Kubernetes `Pod` - onto the created metrics. - items: - type: string - type: array - sampleLimit: - description: SampleLimit defines per-scrape limit on number of scraped - samples that will be accepted. - format: int64 - type: integer - selector: - description: Selector to select Endpoints objects. - properties: - matchExpressions: - description: matchExpressions is a list of label selector requirements. - The requirements are ANDed. - items: - description: A label selector requirement is a selector that - contains values, a key, and an operator that relates the key - and values. - properties: - key: - description: key is the label key that the selector applies - to. - type: string - operator: - description: operator represents a key's relationship to - a set of values. Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of string values. If the - operator is In or NotIn, the values array must be non-empty. - If the operator is Exists or DoesNotExist, the values - array must be empty. This array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. A single - {key,value} in the matchLabels map is equivalent to an element - of matchExpressions, whose key field is "key", the operator - is "In", and the values array contains only "value". The requirements - are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - targetLabels: - description: TargetLabels transfers labels from the Kubernetes `Service` - onto the created metrics. - items: - type: string - type: array - targetLimit: - description: TargetLimit defines a limit on the number of scraped - targets that will be accepted. - format: int64 - type: integer - required: - - endpoints - - selector - type: object - required: - - spec - type: object - served: true - storage: true diff --git a/production/operator/crds/monitoring.grafana.com_grafanaagents.yaml b/production/operator/crds/monitoring.grafana.com_grafanaagents.yaml deleted file mode 100644 index fab68b18e6f6..000000000000 --- a/production/operator/crds/monitoring.grafana.com_grafanaagents.yaml +++ /dev/null @@ -1,7795 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.9.2 - creationTimestamp: null - name: grafanaagents.monitoring.grafana.com -spec: - group: monitoring.grafana.com - names: - categories: - - agent-operator - kind: GrafanaAgent - listKind: GrafanaAgentList - plural: grafanaagents - singular: grafanaagent - scope: Namespaced - versions: - - name: v1alpha1 - schema: - openAPIV3Schema: - description: GrafanaAgent defines a Grafana Agent deployment. - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: Spec holds the specification of the desired behavior for - the Grafana Agent cluster. - properties: - affinity: - description: Affinity, if specified, controls pod scheduling constraints. - properties: - nodeAffinity: - description: Describes node affinity scheduling rules for the - pod. - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods to - nodes that satisfy the affinity expressions specified by - this field, but it may choose a node that violates one or - more of the expressions. The node that is most preferred - is the one with the greatest sum of weights, i.e. for each - node that meets all of the scheduling requirements (resource - request, requiredDuringScheduling affinity expressions, - etc.), compute a sum by iterating through the elements of - this field and adding "weight" to the sum if the node matches - the corresponding matchExpressions; the node(s) with the - highest sum are the most preferred. - items: - description: An empty preferred scheduling term matches - all objects with implicit weight 0 (i.e. it's a no-op). - A null preferred scheduling term matches no objects (i.e. - is also a no-op). - properties: - preference: - description: A node selector term, associated with the - corresponding weight. - properties: - matchExpressions: - description: A list of node selector requirements - by node's labels. - items: - description: A node selector requirement is a - selector that contains values, a key, and an - operator that relates the key and values. - properties: - key: - description: The label key that the selector - applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators are - In, NotIn, Exists, DoesNotExist. Gt, and - Lt. - type: string - values: - description: An array of string values. If - the operator is In or NotIn, the values - array must be non-empty. If the operator - is Exists or DoesNotExist, the values array - must be empty. If the operator is Gt or - Lt, the values array must have a single - element, which will be interpreted as an - integer. This array is replaced during a - strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchFields: - description: A list of node selector requirements - by node's fields. - items: - description: A node selector requirement is a - selector that contains values, a key, and an - operator that relates the key and values. - properties: - key: - description: The label key that the selector - applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators are - In, NotIn, Exists, DoesNotExist. Gt, and - Lt. - type: string - values: - description: An array of string values. If - the operator is In or NotIn, the values - array must be non-empty. If the operator - is Exists or DoesNotExist, the values array - must be empty. If the operator is Gt or - Lt, the values array must have a single - element, which will be interpreted as an - integer. This array is replaced during a - strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - type: object - x-kubernetes-map-type: atomic - weight: - description: Weight associated with matching the corresponding - nodeSelectorTerm, in the range 1-100. - format: int32 - type: integer - required: - - preference - - weight - type: object - type: array - requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements specified by this - field are not met at scheduling time, the pod will not be - scheduled onto the node. If the affinity requirements specified - by this field cease to be met at some point during pod execution - (e.g. due to an update), the system may or may not try to - eventually evict the pod from its node. - properties: - nodeSelectorTerms: - description: Required. A list of node selector terms. - The terms are ORed. - items: - description: A null or empty node selector term matches - no objects. The requirements of them are ANDed. The - TopologySelectorTerm type implements a subset of the - NodeSelectorTerm. - properties: - matchExpressions: - description: A list of node selector requirements - by node's labels. - items: - description: A node selector requirement is a - selector that contains values, a key, and an - operator that relates the key and values. - properties: - key: - description: The label key that the selector - applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators are - In, NotIn, Exists, DoesNotExist. Gt, and - Lt. - type: string - values: - description: An array of string values. If - the operator is In or NotIn, the values - array must be non-empty. If the operator - is Exists or DoesNotExist, the values array - must be empty. If the operator is Gt or - Lt, the values array must have a single - element, which will be interpreted as an - integer. This array is replaced during a - strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchFields: - description: A list of node selector requirements - by node's fields. - items: - description: A node selector requirement is a - selector that contains values, a key, and an - operator that relates the key and values. - properties: - key: - description: The label key that the selector - applies to. - type: string - operator: - description: Represents a key's relationship - to a set of values. Valid operators are - In, NotIn, Exists, DoesNotExist. Gt, and - Lt. - type: string - values: - description: An array of string values. If - the operator is In or NotIn, the values - array must be non-empty. If the operator - is Exists or DoesNotExist, the values array - must be empty. If the operator is Gt or - Lt, the values array must have a single - element, which will be interpreted as an - integer. This array is replaced during a - strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - type: object - x-kubernetes-map-type: atomic - type: array - required: - - nodeSelectorTerms - type: object - x-kubernetes-map-type: atomic - type: object - podAffinity: - description: Describes pod affinity scheduling rules (e.g. co-locate - this pod in the same node, zone, etc. as some other pod(s)). - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods to - nodes that satisfy the affinity expressions specified by - this field, but it may choose a node that violates one or - more of the expressions. The node that is most preferred - is the one with the greatest sum of weights, i.e. for each - node that meets all of the scheduling requirements (resource - request, requiredDuringScheduling affinity expressions, - etc.), compute a sum by iterating through the elements of - this field and adding "weight" to the sum if the node has - pods which matches the corresponding podAffinityTerm; the - node(s) with the highest sum are the most preferred. - items: - description: The weights of all of the matched WeightedPodAffinityTerm - fields are added per-node to find the most preferred node(s) - properties: - podAffinityTerm: - description: Required. A pod affinity term, associated - with the corresponding weight. - properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are - ANDed. - items: - description: A label selector requirement - is a selector that contains values, a key, - and an operator that relates the key and - values. - properties: - key: - description: key is the label key that - the selector applies to. - type: string - operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. - type: string - values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only "value". - The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - namespaceSelector: - description: A label query over the set of namespaces - that the term applies to. The term is applied - to the union of the namespaces selected by this - field and the ones listed in the namespaces field. - null selector and null or empty namespaces list - means "this pod's namespace". An empty selector - ({}) matches all namespaces. - properties: - matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are - ANDed. - items: - description: A label selector requirement - is a selector that contains values, a key, - and an operator that relates the key and - values. - properties: - key: - description: key is the label key that - the selector applies to. - type: string - operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. - type: string - values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only "value". - The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - description: namespaces specifies a static list - of namespace names that the term applies to. The - term is applied to the union of the namespaces - listed in this field and the ones selected by - namespaceSelector. null or empty namespaces list - and null namespaceSelector means "this pod's namespace". - items: - type: string - type: array - topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the pods - matching the labelSelector in the specified namespaces, - where co-located is defined as running on a node - whose value of the label with key topologyKey - matches that of any node on which any of the selected - pods is running. Empty topologyKey is not allowed. - type: string - required: - - topologyKey - type: object - weight: - description: weight associated with matching the corresponding - podAffinityTerm, in the range 1-100. - format: int32 - type: integer - required: - - podAffinityTerm - - weight - type: object - type: array - requiredDuringSchedulingIgnoredDuringExecution: - description: If the affinity requirements specified by this - field are not met at scheduling time, the pod will not be - scheduled onto the node. If the affinity requirements specified - by this field cease to be met at some point during pod execution - (e.g. due to a pod label update), the system may or may - not try to eventually evict the pod from its node. When - there are multiple elements, the lists of nodes corresponding - to each podAffinityTerm are intersected, i.e. all terms - must be satisfied. - items: - description: Defines a set of pods (namely those matching - the labelSelector relative to the given namespace(s)) - that this pod should be co-located (affinity) or not co-located - (anti-affinity) with, where co-located is defined as running - on a node whose value of the label with key - matches that of any node on which a pod of the set of - pods is running - properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are ANDed. - items: - description: A label selector requirement is a - selector that contains values, a key, and an - operator that relates the key and values. - properties: - key: - description: key is the label key that the - selector applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are - In, NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. If the - operator is Exists or DoesNotExist, the - values array must be empty. This array is - replaced during a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is "In", - and the values array contains only "value". The - requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - namespaceSelector: - description: A label query over the set of namespaces - that the term applies to. The term is applied to the - union of the namespaces selected by this field and - the ones listed in the namespaces field. null selector - and null or empty namespaces list means "this pod's - namespace". An empty selector ({}) matches all namespaces. - properties: - matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are ANDed. - items: - description: A label selector requirement is a - selector that contains values, a key, and an - operator that relates the key and values. - properties: - key: - description: key is the label key that the - selector applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are - In, NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. If the - operator is Exists or DoesNotExist, the - values array must be empty. This array is - replaced during a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is "In", - and the values array contains only "value". The - requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - description: namespaces specifies a static list of namespace - names that the term applies to. The term is applied - to the union of the namespaces listed in this field - and the ones selected by namespaceSelector. null or - empty namespaces list and null namespaceSelector means - "this pod's namespace". - items: - type: string - type: array - topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the pods matching - the labelSelector in the specified namespaces, where - co-located is defined as running on a node whose value - of the label with key topologyKey matches that of - any node on which any of the selected pods is running. - Empty topologyKey is not allowed. - type: string - required: - - topologyKey - type: object - type: array - type: object - podAntiAffinity: - description: Describes pod anti-affinity scheduling rules (e.g. - avoid putting this pod in the same node, zone, etc. as some - other pod(s)). - properties: - preferredDuringSchedulingIgnoredDuringExecution: - description: The scheduler will prefer to schedule pods to - nodes that satisfy the anti-affinity expressions specified - by this field, but it may choose a node that violates one - or more of the expressions. The node that is most preferred - is the one with the greatest sum of weights, i.e. for each - node that meets all of the scheduling requirements (resource - request, requiredDuringScheduling anti-affinity expressions, - etc.), compute a sum by iterating through the elements of - this field and adding "weight" to the sum if the node has - pods which matches the corresponding podAffinityTerm; the - node(s) with the highest sum are the most preferred. - items: - description: The weights of all of the matched WeightedPodAffinityTerm - fields are added per-node to find the most preferred node(s) - properties: - podAffinityTerm: - description: Required. A pod affinity term, associated - with the corresponding weight. - properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are - ANDed. - items: - description: A label selector requirement - is a selector that contains values, a key, - and an operator that relates the key and - values. - properties: - key: - description: key is the label key that - the selector applies to. - type: string - operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. - type: string - values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only "value". - The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - namespaceSelector: - description: A label query over the set of namespaces - that the term applies to. The term is applied - to the union of the namespaces selected by this - field and the ones listed in the namespaces field. - null selector and null or empty namespaces list - means "this pod's namespace". An empty selector - ({}) matches all namespaces. - properties: - matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are - ANDed. - items: - description: A label selector requirement - is a selector that contains values, a key, - and an operator that relates the key and - values. - properties: - key: - description: key is the label key that - the selector applies to. - type: string - operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. - type: string - values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only "value". - The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - description: namespaces specifies a static list - of namespace names that the term applies to. The - term is applied to the union of the namespaces - listed in this field and the ones selected by - namespaceSelector. null or empty namespaces list - and null namespaceSelector means "this pod's namespace". - items: - type: string - type: array - topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the pods - matching the labelSelector in the specified namespaces, - where co-located is defined as running on a node - whose value of the label with key topologyKey - matches that of any node on which any of the selected - pods is running. Empty topologyKey is not allowed. - type: string - required: - - topologyKey - type: object - weight: - description: weight associated with matching the corresponding - podAffinityTerm, in the range 1-100. - format: int32 - type: integer - required: - - podAffinityTerm - - weight - type: object - type: array - requiredDuringSchedulingIgnoredDuringExecution: - description: If the anti-affinity requirements specified by - this field are not met at scheduling time, the pod will - not be scheduled onto the node. If the anti-affinity requirements - specified by this field cease to be met at some point during - pod execution (e.g. due to a pod label update), the system - may or may not try to eventually evict the pod from its - node. When there are multiple elements, the lists of nodes - corresponding to each podAffinityTerm are intersected, i.e. - all terms must be satisfied. - items: - description: Defines a set of pods (namely those matching - the labelSelector relative to the given namespace(s)) - that this pod should be co-located (affinity) or not co-located - (anti-affinity) with, where co-located is defined as running - on a node whose value of the label with key - matches that of any node on which a pod of the set of - pods is running - properties: - labelSelector: - description: A label query over a set of resources, - in this case pods. - properties: - matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are ANDed. - items: - description: A label selector requirement is a - selector that contains values, a key, and an - operator that relates the key and values. - properties: - key: - description: key is the label key that the - selector applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are - In, NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. If the - operator is Exists or DoesNotExist, the - values array must be empty. This array is - replaced during a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is "In", - and the values array contains only "value". The - requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - namespaceSelector: - description: A label query over the set of namespaces - that the term applies to. The term is applied to the - union of the namespaces selected by this field and - the ones listed in the namespaces field. null selector - and null or empty namespaces list means "this pod's - namespace". An empty selector ({}) matches all namespaces. - properties: - matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are ANDed. - items: - description: A label selector requirement is a - selector that contains values, a key, and an - operator that relates the key and values. - properties: - key: - description: key is the label key that the - selector applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are - In, NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. If the - operator is Exists or DoesNotExist, the - values array must be empty. This array is - replaced during a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is "In", - and the values array contains only "value". The - requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - namespaces: - description: namespaces specifies a static list of namespace - names that the term applies to. The term is applied - to the union of the namespaces listed in this field - and the ones selected by namespaceSelector. null or - empty namespaces list and null namespaceSelector means - "this pod's namespace". - items: - type: string - type: array - topologyKey: - description: This pod should be co-located (affinity) - or not co-located (anti-affinity) with the pods matching - the labelSelector in the specified namespaces, where - co-located is defined as running on a node whose value - of the label with key topologyKey matches that of - any node on which any of the selected pods is running. - Empty topologyKey is not allowed. - type: string - required: - - topologyKey - type: object - type: array - type: object - type: object - apiServer: - description: APIServerConfig lets you specify a host and auth methods - to access the Kubernetes API server. If left empty, the Agent assumes - that it is running inside of the cluster and will discover API servers - automatically and use the pod's CA certificate and bearer token - file at /var/run/secrets/kubernetes.io/serviceaccount. - properties: - authorization: - description: Authorization section for accessing apiserver - properties: - credentials: - description: The secret's key that contains the credentials - of the request - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must - be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - credentialsFile: - description: File to read a secret from, mutually exclusive - with Credentials (from SafeAuthorization) - type: string - type: - description: Set the authentication type. Defaults to Bearer, - Basic will cause an error - type: string - type: object - basicAuth: - description: BasicAuth allow an endpoint to authenticate over - basic authentication - properties: - password: - description: The secret in the service monitor namespace that - contains the password for authentication. - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must - be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - username: - description: The secret in the service monitor namespace that - contains the username for authentication. - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must - be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - bearerToken: - description: Bearer token for accessing apiserver. - type: string - bearerTokenFile: - description: File to read bearer token for accessing apiserver. - type: string - host: - description: Host of apiserver. A valid string consisting of a - hostname or IP followed by an optional port number - type: string - tlsConfig: - description: TLS Config to use for accessing apiserver. - properties: - ca: - description: Certificate authority used when verifying server - certificates. - properties: - configMap: - description: ConfigMap containing data to use for the - targets. - properties: - key: - description: The key to select. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the ConfigMap or its - key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - secret: - description: Secret containing data to use for the targets. - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the Secret or its key - must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - caFile: - description: Path to the CA cert in the Prometheus container - to use for the targets. - type: string - cert: - description: Client certificate to present when doing client-authentication. - properties: - configMap: - description: ConfigMap containing data to use for the - targets. - properties: - key: - description: The key to select. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the ConfigMap or its - key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - secret: - description: Secret containing data to use for the targets. - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the Secret or its key - must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - certFile: - description: Path to the client cert file in the Prometheus - container for the targets. - type: string - insecureSkipVerify: - description: Disable target certificate validation. - type: boolean - keyFile: - description: Path to the client key file in the Prometheus - container for the targets. - type: string - keySecret: - description: Secret containing the client key file for the - targets. - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must - be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - serverName: - description: Used to verify the hostname for the targets. - type: string - type: object - required: - - host - type: object - configMaps: - description: ConfigMaps is a list of config maps in the same namespace - as the GrafanaAgent object which will be mounted into each running - Grafana Agent pod. The ConfigMaps are mounted into /var/lib/grafana-agent/extra-configmaps/. - items: - type: string - type: array - configReloaderImage: - description: Image, when specified, overrides the image used to run - Config Reloader. Specify the image along with a tag. You still need - to set the version to ensure Grafana Agent Operator knows which - version of Grafana Agent is being configured. - type: string - configReloaderVersion: - description: Version of Config Reloader to be deployed. - type: string - containers: - description: 'Containers lets you inject additional containers or - modify operator-generated containers. This can be used to add an - authentication proxy to a Grafana Agent pod or to change the behavior - of an operator-generated container. Containers described here modify - an operator-generated container if they share the same name and - if modifications are done via a strategic merge patch. The current - container names are: `grafana-agent` and `config-reloader`. Overriding - containers is entirely outside the scope of what the Grafana Agent - team supports and by doing so, you accept that this behavior may - break at any time without notice.' - items: - description: A single application container that you want to run - within a pod. - properties: - args: - description: 'Arguments to the entrypoint. The container image''s - CMD is used if this is not provided. Variable references $(VAR_NAME) - are expanded using the container''s environment. If a variable - cannot be resolved, the reference in the input string will - be unchanged. Double $$ are reduced to a single $, which allows - for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will - produce the string literal "$(VAR_NAME)". Escaped references - will never be expanded, regardless of whether the variable - exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' - items: - type: string - type: array - command: - description: 'Entrypoint array. Not executed within a shell. - The container image''s ENTRYPOINT is used if this is not provided. - Variable references $(VAR_NAME) are expanded using the container''s - environment. If a variable cannot be resolved, the reference - in the input string will be unchanged. Double $$ are reduced - to a single $, which allows for escaping the $(VAR_NAME) syntax: - i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". - Escaped references will never be expanded, regardless of whether - the variable exists or not. Cannot be updated. More info: - https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' - items: - type: string - type: array - env: - description: List of environment variables to set in the container. - Cannot be updated. - items: - description: EnvVar represents an environment variable present - in a Container. - properties: - name: - description: Name of the environment variable. Must be - a C_IDENTIFIER. - type: string - value: - description: 'Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in - the container and any service environment variables. - If a variable cannot be resolved, the reference in the - input string will be unchanged. Double $$ are reduced - to a single $, which allows for escaping the $(VAR_NAME) - syntax: i.e. "$$(VAR_NAME)" will produce the string - literal "$(VAR_NAME)". Escaped references will never - be expanded, regardless of whether the variable exists - or not. Defaults to "".' - type: string - valueFrom: - description: Source for the environment variable's value. - Cannot be used if value is not empty. - properties: - configMapKeyRef: - description: Selects a key of a ConfigMap. - properties: - key: - description: The key to select. - type: string - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the ConfigMap or - its key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - fieldRef: - description: 'Selects a field of the pod: supports - metadata.name, metadata.namespace, `metadata.labels['''']`, - `metadata.annotations['''']`, spec.nodeName, - spec.serviceAccountName, status.hostIP, status.podIP, - status.podIPs.' - properties: - apiVersion: - description: Version of the schema the FieldPath - is written in terms of, defaults to "v1". - type: string - fieldPath: - description: Path of the field to select in the - specified API version. - type: string - required: - - fieldPath - type: object - x-kubernetes-map-type: atomic - resourceFieldRef: - description: 'Selects a resource of the container: - only resources limits and requests (limits.cpu, - limits.memory, limits.ephemeral-storage, requests.cpu, - requests.memory and requests.ephemeral-storage) - are currently supported.' - properties: - containerName: - description: 'Container name: required for volumes, - optional for env vars' - type: string - divisor: - anyOf: - - type: integer - - type: string - description: Specifies the output format of the - exposed resources, defaults to "1" - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - description: 'Required: resource to select' - type: string - required: - - resource - type: object - x-kubernetes-map-type: atomic - secretKeyRef: - description: Selects a key of a secret in the pod's - namespace - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the Secret or its - key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - required: - - name - type: object - type: array - envFrom: - description: List of sources to populate environment variables - in the container. The keys defined within a source must be - a C_IDENTIFIER. All invalid keys will be reported as an event - when the container is starting. When a key exists in multiple - sources, the value associated with the last source will take - precedence. Values defined by an Env with a duplicate key - will take precedence. Cannot be updated. - items: - description: EnvFromSource represents the source of a set - of ConfigMaps - properties: - configMapRef: - description: The ConfigMap to select from - properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the ConfigMap must be - defined - type: boolean - type: object - x-kubernetes-map-type: atomic - prefix: - description: An optional identifier to prepend to each - key in the ConfigMap. Must be a C_IDENTIFIER. - type: string - secretRef: - description: The Secret to select from - properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the Secret must be defined - type: boolean - type: object - x-kubernetes-map-type: atomic - type: object - type: array - image: - description: 'Container image name. More info: https://kubernetes.io/docs/concepts/containers/images - This field is optional to allow higher level config management - to default or override container images in workload controllers - like Deployments and StatefulSets.' - type: string - imagePullPolicy: - description: 'Image pull policy. One of Always, Never, IfNotPresent. - Defaults to Always if :latest tag is specified, or IfNotPresent - otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images' - type: string - lifecycle: - description: Actions that the management system should take - in response to container lifecycle events. Cannot be updated. - properties: - postStart: - description: 'PostStart is called immediately after a container - is created. If the handler fails, the container is terminated - and restarted according to its restart policy. Other management - of the container blocks until the hook completes. More - info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' - properties: - exec: - description: Exec specifies the action to take. - properties: - command: - description: Command is the command line to execute - inside the container, the working directory for - the command is root ('/') in the container's - filesystem. The command is simply exec'd, it is - not run inside a shell, so traditional shell instructions - ('|', etc) won't work. To use a shell, you need - to explicitly call out to that shell. Exit status - of 0 is treated as live/healthy and non-zero is - unhealthy. - items: - type: string - type: array - type: object - httpGet: - description: HTTPGet specifies the http request to perform. - properties: - host: - description: Host name to connect to, defaults to - the pod IP. You probably want to set "Host" in - httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom header - to be used in HTTP probes - properties: - name: - description: The header field name. This will - be canonicalized upon output, so case-variant - names will be understood as the same header. - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: Name or number of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: Scheme to use for connecting to the - host. Defaults to HTTP. - type: string - required: - - port - type: object - tcpSocket: - description: Deprecated. TCPSocket is NOT supported - as a LifecycleHandler and kept for the backward compatibility. - There are no validation of this field and lifecycle - hooks will fail in runtime when tcp handler is specified. - properties: - host: - description: 'Optional: Host name to connect to, - defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: Number or name of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - preStop: - description: 'PreStop is called immediately before a container - is terminated due to an API request or management event - such as liveness/startup probe failure, preemption, resource - contention, etc. The handler is not called if the container - crashes or exits. The Pod''s termination grace period - countdown begins before the PreStop hook is executed. - Regardless of the outcome of the handler, the container - will eventually terminate within the Pod''s termination - grace period (unless delayed by finalizers). Other management - of the container blocks until the hook completes or until - the termination grace period is reached. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' - properties: - exec: - description: Exec specifies the action to take. - properties: - command: - description: Command is the command line to execute - inside the container, the working directory for - the command is root ('/') in the container's - filesystem. The command is simply exec'd, it is - not run inside a shell, so traditional shell instructions - ('|', etc) won't work. To use a shell, you need - to explicitly call out to that shell. Exit status - of 0 is treated as live/healthy and non-zero is - unhealthy. - items: - type: string - type: array - type: object - httpGet: - description: HTTPGet specifies the http request to perform. - properties: - host: - description: Host name to connect to, defaults to - the pod IP. You probably want to set "Host" in - httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom header - to be used in HTTP probes - properties: - name: - description: The header field name. This will - be canonicalized upon output, so case-variant - names will be understood as the same header. - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: Name or number of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: Scheme to use for connecting to the - host. Defaults to HTTP. - type: string - required: - - port - type: object - tcpSocket: - description: Deprecated. TCPSocket is NOT supported - as a LifecycleHandler and kept for the backward compatibility. - There are no validation of this field and lifecycle - hooks will fail in runtime when tcp handler is specified. - properties: - host: - description: 'Optional: Host name to connect to, - defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: Number or name of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - type: object - livenessProbe: - description: 'Periodic probe of container liveness. Container - will be restarted if the probe fails. Cannot be updated. More - info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - properties: - exec: - description: Exec specifies the action to take. - properties: - command: - description: Command is the command line to execute - inside the container, the working directory for the - command is root ('/') in the container's filesystem. - The command is simply exec'd, it is not run inside - a shell, so traditional shell instructions ('|', etc) - won't work. To use a shell, you need to explicitly - call out to that shell. Exit status of 0 is treated - as live/healthy and non-zero is unhealthy. - items: - type: string - type: array - type: object - failureThreshold: - description: Minimum consecutive failures for the probe - to be considered failed after having succeeded. Defaults - to 3. Minimum value is 1. - format: int32 - type: integer - grpc: - description: GRPC specifies an action involving a GRPC port. - properties: - port: - description: Port number of the gRPC service. Number - must be in the range 1 to 65535. - format: int32 - type: integer - service: - description: "Service is the name of the service to - place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). - \n If this is not specified, the default behavior - is defined by gRPC." - type: string - required: - - port - type: object - httpGet: - description: HTTPGet specifies the http request to perform. - properties: - host: - description: Host name to connect to, defaults to the - pod IP. You probably want to set "Host" in httpHeaders - instead. - type: string - httpHeaders: - description: Custom headers to set in the request. HTTP - allows repeated headers. - items: - description: HTTPHeader describes a custom header - to be used in HTTP probes - properties: - name: - description: The header field name. This will - be canonicalized upon output, so case-variant - names will be understood as the same header. - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: Name or number of the port to access on - the container. Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: Scheme to use for connecting to the host. - Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: 'Number of seconds after the container has - started before liveness probes are initiated. More info: - https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - periodSeconds: - description: How often (in seconds) to perform the probe. - Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: Minimum consecutive successes for the probe - to be considered successful after having failed. Defaults - to 1. Must be 1 for liveness and startup. Minimum value - is 1. - format: int32 - type: integer - tcpSocket: - description: TCPSocket specifies an action involving a TCP - port. - properties: - host: - description: 'Optional: Host name to connect to, defaults - to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: Number or name of the port to access on - the container. Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - description: Optional duration in seconds the pod needs - to terminate gracefully upon probe failure. The grace - period is the duration in seconds after the processes - running in the pod are sent a termination signal and the - time when the processes are forcibly halted with a kill - signal. Set this value longer than the expected cleanup - time for your process. If this value is nil, the pod's - terminationGracePeriodSeconds will be used. Otherwise, - this value overrides the value provided by the pod spec. - Value must be non-negative integer. The value zero indicates - stop immediately via the kill signal (no opportunity to - shut down). This is a beta field and requires enabling - ProbeTerminationGracePeriod feature gate. Minimum value - is 1. spec.terminationGracePeriodSeconds is used if unset. - format: int64 - type: integer - timeoutSeconds: - description: 'Number of seconds after which the probe times - out. Defaults to 1 second. Minimum value is 1. More info: - https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - type: object - name: - description: Name of the container specified as a DNS_LABEL. - Each container in a pod must have a unique name (DNS_LABEL). - Cannot be updated. - type: string - ports: - description: List of ports to expose from the container. Not - specifying a port here DOES NOT prevent that port from being - exposed. Any port which is listening on the default "0.0.0.0" - address inside a container will be accessible from the network. - Modifying this array with strategic merge patch may corrupt - the data. For more information See https://github.com/kubernetes/kubernetes/issues/108255. - Cannot be updated. - items: - description: ContainerPort represents a network port in a - single container. - properties: - containerPort: - description: Number of port to expose on the pod's IP - address. This must be a valid port number, 0 < x < 65536. - format: int32 - type: integer - hostIP: - description: What host IP to bind the external port to. - type: string - hostPort: - description: Number of port to expose on the host. If - specified, this must be a valid port number, 0 < x < - 65536. If HostNetwork is specified, this must match - ContainerPort. Most containers do not need this. - format: int32 - type: integer - name: - description: If specified, this must be an IANA_SVC_NAME - and unique within the pod. Each named port in a pod - must have a unique name. Name for the port that can - be referred to by services. - type: string - protocol: - default: TCP - description: Protocol for port. Must be UDP, TCP, or SCTP. - Defaults to "TCP". - type: string - required: - - containerPort - type: object - type: array - x-kubernetes-list-map-keys: - - containerPort - - protocol - x-kubernetes-list-type: map - readinessProbe: - description: 'Periodic probe of container service readiness. - Container will be removed from service endpoints if the probe - fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - properties: - exec: - description: Exec specifies the action to take. - properties: - command: - description: Command is the command line to execute - inside the container, the working directory for the - command is root ('/') in the container's filesystem. - The command is simply exec'd, it is not run inside - a shell, so traditional shell instructions ('|', etc) - won't work. To use a shell, you need to explicitly - call out to that shell. Exit status of 0 is treated - as live/healthy and non-zero is unhealthy. - items: - type: string - type: array - type: object - failureThreshold: - description: Minimum consecutive failures for the probe - to be considered failed after having succeeded. Defaults - to 3. Minimum value is 1. - format: int32 - type: integer - grpc: - description: GRPC specifies an action involving a GRPC port. - properties: - port: - description: Port number of the gRPC service. Number - must be in the range 1 to 65535. - format: int32 - type: integer - service: - description: "Service is the name of the service to - place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). - \n If this is not specified, the default behavior - is defined by gRPC." - type: string - required: - - port - type: object - httpGet: - description: HTTPGet specifies the http request to perform. - properties: - host: - description: Host name to connect to, defaults to the - pod IP. You probably want to set "Host" in httpHeaders - instead. - type: string - httpHeaders: - description: Custom headers to set in the request. HTTP - allows repeated headers. - items: - description: HTTPHeader describes a custom header - to be used in HTTP probes - properties: - name: - description: The header field name. This will - be canonicalized upon output, so case-variant - names will be understood as the same header. - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: Name or number of the port to access on - the container. Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: Scheme to use for connecting to the host. - Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: 'Number of seconds after the container has - started before liveness probes are initiated. More info: - https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - periodSeconds: - description: How often (in seconds) to perform the probe. - Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: Minimum consecutive successes for the probe - to be considered successful after having failed. Defaults - to 1. Must be 1 for liveness and startup. Minimum value - is 1. - format: int32 - type: integer - tcpSocket: - description: TCPSocket specifies an action involving a TCP - port. - properties: - host: - description: 'Optional: Host name to connect to, defaults - to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: Number or name of the port to access on - the container. Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - description: Optional duration in seconds the pod needs - to terminate gracefully upon probe failure. The grace - period is the duration in seconds after the processes - running in the pod are sent a termination signal and the - time when the processes are forcibly halted with a kill - signal. Set this value longer than the expected cleanup - time for your process. If this value is nil, the pod's - terminationGracePeriodSeconds will be used. Otherwise, - this value overrides the value provided by the pod spec. - Value must be non-negative integer. The value zero indicates - stop immediately via the kill signal (no opportunity to - shut down). This is a beta field and requires enabling - ProbeTerminationGracePeriod feature gate. Minimum value - is 1. spec.terminationGracePeriodSeconds is used if unset. - format: int64 - type: integer - timeoutSeconds: - description: 'Number of seconds after which the probe times - out. Defaults to 1 second. Minimum value is 1. More info: - https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - type: object - resizePolicy: - description: Resources resize policy for the container. - items: - description: ContainerResizePolicy represents resource resize - policy for the container. - properties: - resourceName: - description: 'Name of the resource to which this resource - resize policy applies. Supported values: cpu, memory.' - type: string - restartPolicy: - description: Restart policy to apply when specified resource - is resized. If not specified, it defaults to NotRequired. - type: string - required: - - resourceName - - restartPolicy - type: object - type: array - x-kubernetes-list-type: atomic - resources: - description: 'Compute Resources required by this container. - Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - properties: - claims: - description: "Claims lists the names of resources, defined - in spec.resourceClaims, that are used by this container. - \n This is an alpha field and requires enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. It can only - be set for containers." - items: - description: ResourceClaim references one entry in PodSpec.ResourceClaims. - properties: - name: - description: Name must match the name of one entry - in pod.spec.resourceClaims of the Pod where this - field is used. It makes that resource available - inside a container. - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, - otherwise to an implementation-defined value. Requests - cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - type: object - restartPolicy: - description: 'RestartPolicy defines the restart behavior of - individual containers in a pod. This field may only be set - for init containers, and the only allowed value is "Always". - For non-init containers or when this field is not specified, - the restart behavior is defined by the Pod''s restart policy - and the container type. Setting the RestartPolicy as "Always" - for the init container will have the following effect: this - init container will be continually restarted on exit until - all regular containers have terminated. Once all regular containers - have completed, all init containers with restartPolicy "Always" - will be shut down. This lifecycle differs from normal init - containers and is often referred to as a "sidecar" container. - Although this init container still starts in the init container - sequence, it does not wait for the container to complete before - proceeding to the next init container. Instead, the next init - container starts immediately after this init container is - started, or after any startupProbe has successfully completed.' - type: string - securityContext: - description: 'SecurityContext defines the security options the - container should be run with. If set, the fields of SecurityContext - override the equivalent fields of PodSecurityContext. More - info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/' - properties: - allowPrivilegeEscalation: - description: 'AllowPrivilegeEscalation controls whether - a process can gain more privileges than its parent process. - This bool directly controls if the no_new_privs flag will - be set on the container process. AllowPrivilegeEscalation - is true always when the container is: 1) run as Privileged - 2) has CAP_SYS_ADMIN Note that this field cannot be set - when spec.os.name is windows.' - type: boolean - capabilities: - description: The capabilities to add/drop when running containers. - Defaults to the default set of capabilities granted by - the container runtime. Note that this field cannot be - set when spec.os.name is windows. - properties: - add: - description: Added capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - drop: - description: Removed capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - type: object - privileged: - description: Run container in privileged mode. Processes - in privileged containers are essentially equivalent to - root on the host. Defaults to false. Note that this field - cannot be set when spec.os.name is windows. - type: boolean - procMount: - description: procMount denotes the type of proc mount to - use for the containers. The default is DefaultProcMount - which uses the container runtime defaults for readonly - paths and masked paths. This requires the ProcMountType - feature flag to be enabled. Note that this field cannot - be set when spec.os.name is windows. - type: string - readOnlyRootFilesystem: - description: Whether this container has a read-only root - filesystem. Default is false. Note that this field cannot - be set when spec.os.name is windows. - type: boolean - runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be set - in PodSecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. - format: int64 - type: integer - runAsNonRoot: - description: Indicates that the container must run as a - non-root user. If true, the Kubelet will validate the - image at runtime to ensure that it does not run as UID - 0 (root) and fail to start the container if it does. If - unset or false, no such validation will be performed. - May also be set in PodSecurityContext. If set in both - SecurityContext and PodSecurityContext, the value specified - in SecurityContext takes precedence. - type: boolean - runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata - if unspecified. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. Note - that this field cannot be set when spec.os.name is windows. - format: int64 - type: integer - seLinuxOptions: - description: The SELinux context to be applied to the container. - If unspecified, the container runtime will allocate a - random SELinux context for each container. May also be - set in PodSecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. - properties: - level: - description: Level is SELinux level label that applies - to the container. - type: string - role: - description: Role is a SELinux role label that applies - to the container. - type: string - type: - description: Type is a SELinux type label that applies - to the container. - type: string - user: - description: User is a SELinux user label that applies - to the container. - type: string - type: object - seccompProfile: - description: The seccomp options to use by this container. - If seccomp options are provided at both the pod & container - level, the container options override the pod options. - Note that this field cannot be set when spec.os.name is - windows. - properties: - localhostProfile: - description: localhostProfile indicates a profile defined - in a file on the node should be used. The profile - must be preconfigured on the node to work. Must be - a descending path, relative to the kubelet's configured - seccomp profile location. Must be set if type is "Localhost". - Must NOT be set for any other type. - type: string - type: - description: "type indicates which kind of seccomp profile - will be applied. Valid options are: \n Localhost - - a profile defined in a file on the node should be - used. RuntimeDefault - the container runtime default - profile should be used. Unconfined - no profile should - be applied." - type: string - required: - - type - type: object - windowsOptions: - description: The Windows specific settings applied to all - containers. If unspecified, the options from the PodSecurityContext - will be used. If set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is - linux. - properties: - gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA admission - webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec named - by the GMSACredentialSpecName field. - type: string - gmsaCredentialSpecName: - description: GMSACredentialSpecName is the name of the - GMSA credential spec to use. - type: string - hostProcess: - description: HostProcess determines if a container should - be run as a 'Host Process' container. All of a Pod's - containers must have the same effective HostProcess - value (it is not allowed to have a mix of HostProcess - containers and non-HostProcess containers). In addition, - if HostProcess is true then HostNetwork must also - be set to true. - type: boolean - runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set - in PodSecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. - type: string - type: object - type: object - startupProbe: - description: 'StartupProbe indicates that the Pod has successfully - initialized. If specified, no other probes are executed until - this completes successfully. If this probe fails, the Pod - will be restarted, just as if the livenessProbe failed. This - can be used to provide different probe parameters at the beginning - of a Pod''s lifecycle, when it might take a long time to load - data or warm a cache, than during steady-state operation. - This cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - properties: - exec: - description: Exec specifies the action to take. - properties: - command: - description: Command is the command line to execute - inside the container, the working directory for the - command is root ('/') in the container's filesystem. - The command is simply exec'd, it is not run inside - a shell, so traditional shell instructions ('|', etc) - won't work. To use a shell, you need to explicitly - call out to that shell. Exit status of 0 is treated - as live/healthy and non-zero is unhealthy. - items: - type: string - type: array - type: object - failureThreshold: - description: Minimum consecutive failures for the probe - to be considered failed after having succeeded. Defaults - to 3. Minimum value is 1. - format: int32 - type: integer - grpc: - description: GRPC specifies an action involving a GRPC port. - properties: - port: - description: Port number of the gRPC service. Number - must be in the range 1 to 65535. - format: int32 - type: integer - service: - description: "Service is the name of the service to - place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). - \n If this is not specified, the default behavior - is defined by gRPC." - type: string - required: - - port - type: object - httpGet: - description: HTTPGet specifies the http request to perform. - properties: - host: - description: Host name to connect to, defaults to the - pod IP. You probably want to set "Host" in httpHeaders - instead. - type: string - httpHeaders: - description: Custom headers to set in the request. HTTP - allows repeated headers. - items: - description: HTTPHeader describes a custom header - to be used in HTTP probes - properties: - name: - description: The header field name. This will - be canonicalized upon output, so case-variant - names will be understood as the same header. - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: Name or number of the port to access on - the container. Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: Scheme to use for connecting to the host. - Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: 'Number of seconds after the container has - started before liveness probes are initiated. More info: - https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - periodSeconds: - description: How often (in seconds) to perform the probe. - Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: Minimum consecutive successes for the probe - to be considered successful after having failed. Defaults - to 1. Must be 1 for liveness and startup. Minimum value - is 1. - format: int32 - type: integer - tcpSocket: - description: TCPSocket specifies an action involving a TCP - port. - properties: - host: - description: 'Optional: Host name to connect to, defaults - to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: Number or name of the port to access on - the container. Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - description: Optional duration in seconds the pod needs - to terminate gracefully upon probe failure. The grace - period is the duration in seconds after the processes - running in the pod are sent a termination signal and the - time when the processes are forcibly halted with a kill - signal. Set this value longer than the expected cleanup - time for your process. If this value is nil, the pod's - terminationGracePeriodSeconds will be used. Otherwise, - this value overrides the value provided by the pod spec. - Value must be non-negative integer. The value zero indicates - stop immediately via the kill signal (no opportunity to - shut down). This is a beta field and requires enabling - ProbeTerminationGracePeriod feature gate. Minimum value - is 1. spec.terminationGracePeriodSeconds is used if unset. - format: int64 - type: integer - timeoutSeconds: - description: 'Number of seconds after which the probe times - out. Defaults to 1 second. Minimum value is 1. More info: - https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - type: object - stdin: - description: Whether this container should allocate a buffer - for stdin in the container runtime. If this is not set, reads - from stdin in the container will always result in EOF. Default - is false. - type: boolean - stdinOnce: - description: Whether the container runtime should close the - stdin channel after it has been opened by a single attach. - When stdin is true the stdin stream will remain open across - multiple attach sessions. If stdinOnce is set to true, stdin - is opened on container start, is empty until the first client - attaches to stdin, and then remains open and accepts data - until the client disconnects, at which time stdin is closed - and remains closed until the container is restarted. If this - flag is false, a container processes that reads from stdin - will never receive an EOF. Default is false - type: boolean - terminationMessagePath: - description: 'Optional: Path at which the file to which the - container''s termination message will be written is mounted - into the container''s filesystem. Message written is intended - to be brief final status, such as an assertion failure message. - Will be truncated by the node if greater than 4096 bytes. - The total message length across all containers will be limited - to 12kb. Defaults to /dev/termination-log. Cannot be updated.' - type: string - terminationMessagePolicy: - description: Indicate how the termination message should be - populated. File will use the contents of terminationMessagePath - to populate the container status message on both success and - failure. FallbackToLogsOnError will use the last chunk of - container log output if the termination message file is empty - and the container exited with an error. The log output is - limited to 2048 bytes or 80 lines, whichever is smaller. Defaults - to File. Cannot be updated. - type: string - tty: - description: Whether this container should allocate a TTY for - itself, also requires 'stdin' to be true. Default is false. - type: boolean - volumeDevices: - description: volumeDevices is the list of block devices to be - used by the container. - items: - description: volumeDevice describes a mapping of a raw block - device within a container. - properties: - devicePath: - description: devicePath is the path inside of the container - that the device will be mapped to. - type: string - name: - description: name must match the name of a persistentVolumeClaim - in the pod - type: string - required: - - devicePath - - name - type: object - type: array - volumeMounts: - description: Pod volumes to mount into the container's filesystem. - Cannot be updated. - items: - description: VolumeMount describes a mounting of a Volume - within a container. - properties: - mountPath: - description: Path within the container at which the volume - should be mounted. Must not contain ':'. - type: string - mountPropagation: - description: mountPropagation determines how mounts are - propagated from the host to container and the other - way around. When not set, MountPropagationNone is used. - This field is beta in 1.10. - type: string - name: - description: This must match the Name of a Volume. - type: string - readOnly: - description: Mounted read-only if true, read-write otherwise - (false or unspecified). Defaults to false. - type: boolean - subPath: - description: Path within the volume from which the container's - volume should be mounted. Defaults to "" (volume's root). - type: string - subPathExpr: - description: Expanded path within the volume from which - the container's volume should be mounted. Behaves similarly - to SubPath but environment variable references $(VAR_NAME) - are expanded using the container's environment. Defaults - to "" (volume's root). SubPathExpr and SubPath are mutually - exclusive. - type: string - required: - - mountPath - - name - type: object - type: array - workingDir: - description: Container's working directory. If not specified, - the container runtime's default will be used, which might - be configured in the container image. Cannot be updated. - type: string - required: - - name - type: object - type: array - disableReporting: - default: false - description: disableReporting disables reporting of enabled feature - flags to Grafana. - type: boolean - disableSupportBundle: - default: false - description: disableSupportBundle disables the generation of support - bundles. - type: boolean - enableConfigReadAPI: - default: false - description: enableConfigReadAPI enables the read API for viewing - the currently running config port 8080 on the agent. - type: boolean - image: - description: Image, when specified, overrides the image used to run - Agent. Specify the image along with a tag. You still need to set - the version to ensure Grafana Agent Operator knows which version - of Grafana Agent is being configured. - type: string - imagePullSecrets: - description: 'ImagePullSecrets holds an optional list of references - to Secrets within the same namespace used for pulling the Grafana - Agent image from registries. More info: https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod' - items: - description: LocalObjectReference contains enough information to - let you locate the referenced object inside the same namespace. - properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - type: object - x-kubernetes-map-type: atomic - type: array - initContainers: - description: 'InitContainers let you add initContainers to the pod - definition. These can be used to, for example, fetch secrets for - injection into the Grafana Agent configuration from external sources. - Errors during the execution of an initContainer cause the pod to - restart. More info: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/ - Using initContainers for any use case other than secret fetching - is entirely outside the scope of what the Grafana Agent maintainers - support and by doing so, you accept that this behavior may break - at any time without notice.' - items: - description: A single application container that you want to run - within a pod. - properties: - args: - description: 'Arguments to the entrypoint. The container image''s - CMD is used if this is not provided. Variable references $(VAR_NAME) - are expanded using the container''s environment. If a variable - cannot be resolved, the reference in the input string will - be unchanged. Double $$ are reduced to a single $, which allows - for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will - produce the string literal "$(VAR_NAME)". Escaped references - will never be expanded, regardless of whether the variable - exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' - items: - type: string - type: array - command: - description: 'Entrypoint array. Not executed within a shell. - The container image''s ENTRYPOINT is used if this is not provided. - Variable references $(VAR_NAME) are expanded using the container''s - environment. If a variable cannot be resolved, the reference - in the input string will be unchanged. Double $$ are reduced - to a single $, which allows for escaping the $(VAR_NAME) syntax: - i.e. "$$(VAR_NAME)" will produce the string literal "$(VAR_NAME)". - Escaped references will never be expanded, regardless of whether - the variable exists or not. Cannot be updated. More info: - https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell' - items: - type: string - type: array - env: - description: List of environment variables to set in the container. - Cannot be updated. - items: - description: EnvVar represents an environment variable present - in a Container. - properties: - name: - description: Name of the environment variable. Must be - a C_IDENTIFIER. - type: string - value: - description: 'Variable references $(VAR_NAME) are expanded - using the previously defined environment variables in - the container and any service environment variables. - If a variable cannot be resolved, the reference in the - input string will be unchanged. Double $$ are reduced - to a single $, which allows for escaping the $(VAR_NAME) - syntax: i.e. "$$(VAR_NAME)" will produce the string - literal "$(VAR_NAME)". Escaped references will never - be expanded, regardless of whether the variable exists - or not. Defaults to "".' - type: string - valueFrom: - description: Source for the environment variable's value. - Cannot be used if value is not empty. - properties: - configMapKeyRef: - description: Selects a key of a ConfigMap. - properties: - key: - description: The key to select. - type: string - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the ConfigMap or - its key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - fieldRef: - description: 'Selects a field of the pod: supports - metadata.name, metadata.namespace, `metadata.labels['''']`, - `metadata.annotations['''']`, spec.nodeName, - spec.serviceAccountName, status.hostIP, status.podIP, - status.podIPs.' - properties: - apiVersion: - description: Version of the schema the FieldPath - is written in terms of, defaults to "v1". - type: string - fieldPath: - description: Path of the field to select in the - specified API version. - type: string - required: - - fieldPath - type: object - x-kubernetes-map-type: atomic - resourceFieldRef: - description: 'Selects a resource of the container: - only resources limits and requests (limits.cpu, - limits.memory, limits.ephemeral-storage, requests.cpu, - requests.memory and requests.ephemeral-storage) - are currently supported.' - properties: - containerName: - description: 'Container name: required for volumes, - optional for env vars' - type: string - divisor: - anyOf: - - type: integer - - type: string - description: Specifies the output format of the - exposed resources, defaults to "1" - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - description: 'Required: resource to select' - type: string - required: - - resource - type: object - x-kubernetes-map-type: atomic - secretKeyRef: - description: Selects a key of a secret in the pod's - namespace - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the Secret or its - key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - required: - - name - type: object - type: array - envFrom: - description: List of sources to populate environment variables - in the container. The keys defined within a source must be - a C_IDENTIFIER. All invalid keys will be reported as an event - when the container is starting. When a key exists in multiple - sources, the value associated with the last source will take - precedence. Values defined by an Env with a duplicate key - will take precedence. Cannot be updated. - items: - description: EnvFromSource represents the source of a set - of ConfigMaps - properties: - configMapRef: - description: The ConfigMap to select from - properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the ConfigMap must be - defined - type: boolean - type: object - x-kubernetes-map-type: atomic - prefix: - description: An optional identifier to prepend to each - key in the ConfigMap. Must be a C_IDENTIFIER. - type: string - secretRef: - description: The Secret to select from - properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the Secret must be defined - type: boolean - type: object - x-kubernetes-map-type: atomic - type: object - type: array - image: - description: 'Container image name. More info: https://kubernetes.io/docs/concepts/containers/images - This field is optional to allow higher level config management - to default or override container images in workload controllers - like Deployments and StatefulSets.' - type: string - imagePullPolicy: - description: 'Image pull policy. One of Always, Never, IfNotPresent. - Defaults to Always if :latest tag is specified, or IfNotPresent - otherwise. Cannot be updated. More info: https://kubernetes.io/docs/concepts/containers/images#updating-images' - type: string - lifecycle: - description: Actions that the management system should take - in response to container lifecycle events. Cannot be updated. - properties: - postStart: - description: 'PostStart is called immediately after a container - is created. If the handler fails, the container is terminated - and restarted according to its restart policy. Other management - of the container blocks until the hook completes. More - info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' - properties: - exec: - description: Exec specifies the action to take. - properties: - command: - description: Command is the command line to execute - inside the container, the working directory for - the command is root ('/') in the container's - filesystem. The command is simply exec'd, it is - not run inside a shell, so traditional shell instructions - ('|', etc) won't work. To use a shell, you need - to explicitly call out to that shell. Exit status - of 0 is treated as live/healthy and non-zero is - unhealthy. - items: - type: string - type: array - type: object - httpGet: - description: HTTPGet specifies the http request to perform. - properties: - host: - description: Host name to connect to, defaults to - the pod IP. You probably want to set "Host" in - httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom header - to be used in HTTP probes - properties: - name: - description: The header field name. This will - be canonicalized upon output, so case-variant - names will be understood as the same header. - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: Name or number of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: Scheme to use for connecting to the - host. Defaults to HTTP. - type: string - required: - - port - type: object - tcpSocket: - description: Deprecated. TCPSocket is NOT supported - as a LifecycleHandler and kept for the backward compatibility. - There are no validation of this field and lifecycle - hooks will fail in runtime when tcp handler is specified. - properties: - host: - description: 'Optional: Host name to connect to, - defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: Number or name of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - preStop: - description: 'PreStop is called immediately before a container - is terminated due to an API request or management event - such as liveness/startup probe failure, preemption, resource - contention, etc. The handler is not called if the container - crashes or exits. The Pod''s termination grace period - countdown begins before the PreStop hook is executed. - Regardless of the outcome of the handler, the container - will eventually terminate within the Pod''s termination - grace period (unless delayed by finalizers). Other management - of the container blocks until the hook completes or until - the termination grace period is reached. More info: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/#container-hooks' - properties: - exec: - description: Exec specifies the action to take. - properties: - command: - description: Command is the command line to execute - inside the container, the working directory for - the command is root ('/') in the container's - filesystem. The command is simply exec'd, it is - not run inside a shell, so traditional shell instructions - ('|', etc) won't work. To use a shell, you need - to explicitly call out to that shell. Exit status - of 0 is treated as live/healthy and non-zero is - unhealthy. - items: - type: string - type: array - type: object - httpGet: - description: HTTPGet specifies the http request to perform. - properties: - host: - description: Host name to connect to, defaults to - the pod IP. You probably want to set "Host" in - httpHeaders instead. - type: string - httpHeaders: - description: Custom headers to set in the request. - HTTP allows repeated headers. - items: - description: HTTPHeader describes a custom header - to be used in HTTP probes - properties: - name: - description: The header field name. This will - be canonicalized upon output, so case-variant - names will be understood as the same header. - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: Name or number of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: Scheme to use for connecting to the - host. Defaults to HTTP. - type: string - required: - - port - type: object - tcpSocket: - description: Deprecated. TCPSocket is NOT supported - as a LifecycleHandler and kept for the backward compatibility. - There are no validation of this field and lifecycle - hooks will fail in runtime when tcp handler is specified. - properties: - host: - description: 'Optional: Host name to connect to, - defaults to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: Number or name of the port to access - on the container. Number must be in the range - 1 to 65535. Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - type: object - type: object - livenessProbe: - description: 'Periodic probe of container liveness. Container - will be restarted if the probe fails. Cannot be updated. More - info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - properties: - exec: - description: Exec specifies the action to take. - properties: - command: - description: Command is the command line to execute - inside the container, the working directory for the - command is root ('/') in the container's filesystem. - The command is simply exec'd, it is not run inside - a shell, so traditional shell instructions ('|', etc) - won't work. To use a shell, you need to explicitly - call out to that shell. Exit status of 0 is treated - as live/healthy and non-zero is unhealthy. - items: - type: string - type: array - type: object - failureThreshold: - description: Minimum consecutive failures for the probe - to be considered failed after having succeeded. Defaults - to 3. Minimum value is 1. - format: int32 - type: integer - grpc: - description: GRPC specifies an action involving a GRPC port. - properties: - port: - description: Port number of the gRPC service. Number - must be in the range 1 to 65535. - format: int32 - type: integer - service: - description: "Service is the name of the service to - place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). - \n If this is not specified, the default behavior - is defined by gRPC." - type: string - required: - - port - type: object - httpGet: - description: HTTPGet specifies the http request to perform. - properties: - host: - description: Host name to connect to, defaults to the - pod IP. You probably want to set "Host" in httpHeaders - instead. - type: string - httpHeaders: - description: Custom headers to set in the request. HTTP - allows repeated headers. - items: - description: HTTPHeader describes a custom header - to be used in HTTP probes - properties: - name: - description: The header field name. This will - be canonicalized upon output, so case-variant - names will be understood as the same header. - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: Name or number of the port to access on - the container. Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: Scheme to use for connecting to the host. - Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: 'Number of seconds after the container has - started before liveness probes are initiated. More info: - https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - periodSeconds: - description: How often (in seconds) to perform the probe. - Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: Minimum consecutive successes for the probe - to be considered successful after having failed. Defaults - to 1. Must be 1 for liveness and startup. Minimum value - is 1. - format: int32 - type: integer - tcpSocket: - description: TCPSocket specifies an action involving a TCP - port. - properties: - host: - description: 'Optional: Host name to connect to, defaults - to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: Number or name of the port to access on - the container. Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - description: Optional duration in seconds the pod needs - to terminate gracefully upon probe failure. The grace - period is the duration in seconds after the processes - running in the pod are sent a termination signal and the - time when the processes are forcibly halted with a kill - signal. Set this value longer than the expected cleanup - time for your process. If this value is nil, the pod's - terminationGracePeriodSeconds will be used. Otherwise, - this value overrides the value provided by the pod spec. - Value must be non-negative integer. The value zero indicates - stop immediately via the kill signal (no opportunity to - shut down). This is a beta field and requires enabling - ProbeTerminationGracePeriod feature gate. Minimum value - is 1. spec.terminationGracePeriodSeconds is used if unset. - format: int64 - type: integer - timeoutSeconds: - description: 'Number of seconds after which the probe times - out. Defaults to 1 second. Minimum value is 1. More info: - https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - type: object - name: - description: Name of the container specified as a DNS_LABEL. - Each container in a pod must have a unique name (DNS_LABEL). - Cannot be updated. - type: string - ports: - description: List of ports to expose from the container. Not - specifying a port here DOES NOT prevent that port from being - exposed. Any port which is listening on the default "0.0.0.0" - address inside a container will be accessible from the network. - Modifying this array with strategic merge patch may corrupt - the data. For more information See https://github.com/kubernetes/kubernetes/issues/108255. - Cannot be updated. - items: - description: ContainerPort represents a network port in a - single container. - properties: - containerPort: - description: Number of port to expose on the pod's IP - address. This must be a valid port number, 0 < x < 65536. - format: int32 - type: integer - hostIP: - description: What host IP to bind the external port to. - type: string - hostPort: - description: Number of port to expose on the host. If - specified, this must be a valid port number, 0 < x < - 65536. If HostNetwork is specified, this must match - ContainerPort. Most containers do not need this. - format: int32 - type: integer - name: - description: If specified, this must be an IANA_SVC_NAME - and unique within the pod. Each named port in a pod - must have a unique name. Name for the port that can - be referred to by services. - type: string - protocol: - default: TCP - description: Protocol for port. Must be UDP, TCP, or SCTP. - Defaults to "TCP". - type: string - required: - - containerPort - type: object - type: array - x-kubernetes-list-map-keys: - - containerPort - - protocol - x-kubernetes-list-type: map - readinessProbe: - description: 'Periodic probe of container service readiness. - Container will be removed from service endpoints if the probe - fails. Cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - properties: - exec: - description: Exec specifies the action to take. - properties: - command: - description: Command is the command line to execute - inside the container, the working directory for the - command is root ('/') in the container's filesystem. - The command is simply exec'd, it is not run inside - a shell, so traditional shell instructions ('|', etc) - won't work. To use a shell, you need to explicitly - call out to that shell. Exit status of 0 is treated - as live/healthy and non-zero is unhealthy. - items: - type: string - type: array - type: object - failureThreshold: - description: Minimum consecutive failures for the probe - to be considered failed after having succeeded. Defaults - to 3. Minimum value is 1. - format: int32 - type: integer - grpc: - description: GRPC specifies an action involving a GRPC port. - properties: - port: - description: Port number of the gRPC service. Number - must be in the range 1 to 65535. - format: int32 - type: integer - service: - description: "Service is the name of the service to - place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). - \n If this is not specified, the default behavior - is defined by gRPC." - type: string - required: - - port - type: object - httpGet: - description: HTTPGet specifies the http request to perform. - properties: - host: - description: Host name to connect to, defaults to the - pod IP. You probably want to set "Host" in httpHeaders - instead. - type: string - httpHeaders: - description: Custom headers to set in the request. HTTP - allows repeated headers. - items: - description: HTTPHeader describes a custom header - to be used in HTTP probes - properties: - name: - description: The header field name. This will - be canonicalized upon output, so case-variant - names will be understood as the same header. - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: Name or number of the port to access on - the container. Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: Scheme to use for connecting to the host. - Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: 'Number of seconds after the container has - started before liveness probes are initiated. More info: - https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - periodSeconds: - description: How often (in seconds) to perform the probe. - Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: Minimum consecutive successes for the probe - to be considered successful after having failed. Defaults - to 1. Must be 1 for liveness and startup. Minimum value - is 1. - format: int32 - type: integer - tcpSocket: - description: TCPSocket specifies an action involving a TCP - port. - properties: - host: - description: 'Optional: Host name to connect to, defaults - to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: Number or name of the port to access on - the container. Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - description: Optional duration in seconds the pod needs - to terminate gracefully upon probe failure. The grace - period is the duration in seconds after the processes - running in the pod are sent a termination signal and the - time when the processes are forcibly halted with a kill - signal. Set this value longer than the expected cleanup - time for your process. If this value is nil, the pod's - terminationGracePeriodSeconds will be used. Otherwise, - this value overrides the value provided by the pod spec. - Value must be non-negative integer. The value zero indicates - stop immediately via the kill signal (no opportunity to - shut down). This is a beta field and requires enabling - ProbeTerminationGracePeriod feature gate. Minimum value - is 1. spec.terminationGracePeriodSeconds is used if unset. - format: int64 - type: integer - timeoutSeconds: - description: 'Number of seconds after which the probe times - out. Defaults to 1 second. Minimum value is 1. More info: - https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - type: object - resizePolicy: - description: Resources resize policy for the container. - items: - description: ContainerResizePolicy represents resource resize - policy for the container. - properties: - resourceName: - description: 'Name of the resource to which this resource - resize policy applies. Supported values: cpu, memory.' - type: string - restartPolicy: - description: Restart policy to apply when specified resource - is resized. If not specified, it defaults to NotRequired. - type: string - required: - - resourceName - - restartPolicy - type: object - type: array - x-kubernetes-list-type: atomic - resources: - description: 'Compute Resources required by this container. - Cannot be updated. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - properties: - claims: - description: "Claims lists the names of resources, defined - in spec.resourceClaims, that are used by this container. - \n This is an alpha field and requires enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. It can only - be set for containers." - items: - description: ResourceClaim references one entry in PodSpec.ResourceClaims. - properties: - name: - description: Name must match the name of one entry - in pod.spec.resourceClaims of the Pod where this - field is used. It makes that resource available - inside a container. - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute - resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, - otherwise to an implementation-defined value. Requests - cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - type: object - restartPolicy: - description: 'RestartPolicy defines the restart behavior of - individual containers in a pod. This field may only be set - for init containers, and the only allowed value is "Always". - For non-init containers or when this field is not specified, - the restart behavior is defined by the Pod''s restart policy - and the container type. Setting the RestartPolicy as "Always" - for the init container will have the following effect: this - init container will be continually restarted on exit until - all regular containers have terminated. Once all regular containers - have completed, all init containers with restartPolicy "Always" - will be shut down. This lifecycle differs from normal init - containers and is often referred to as a "sidecar" container. - Although this init container still starts in the init container - sequence, it does not wait for the container to complete before - proceeding to the next init container. Instead, the next init - container starts immediately after this init container is - started, or after any startupProbe has successfully completed.' - type: string - securityContext: - description: 'SecurityContext defines the security options the - container should be run with. If set, the fields of SecurityContext - override the equivalent fields of PodSecurityContext. More - info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/' - properties: - allowPrivilegeEscalation: - description: 'AllowPrivilegeEscalation controls whether - a process can gain more privileges than its parent process. - This bool directly controls if the no_new_privs flag will - be set on the container process. AllowPrivilegeEscalation - is true always when the container is: 1) run as Privileged - 2) has CAP_SYS_ADMIN Note that this field cannot be set - when spec.os.name is windows.' - type: boolean - capabilities: - description: The capabilities to add/drop when running containers. - Defaults to the default set of capabilities granted by - the container runtime. Note that this field cannot be - set when spec.os.name is windows. - properties: - add: - description: Added capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - drop: - description: Removed capabilities - items: - description: Capability represent POSIX capabilities - type - type: string - type: array - type: object - privileged: - description: Run container in privileged mode. Processes - in privileged containers are essentially equivalent to - root on the host. Defaults to false. Note that this field - cannot be set when spec.os.name is windows. - type: boolean - procMount: - description: procMount denotes the type of proc mount to - use for the containers. The default is DefaultProcMount - which uses the container runtime defaults for readonly - paths and masked paths. This requires the ProcMountType - feature flag to be enabled. Note that this field cannot - be set when spec.os.name is windows. - type: string - readOnlyRootFilesystem: - description: Whether this container has a read-only root - filesystem. Default is false. Note that this field cannot - be set when spec.os.name is windows. - type: boolean - runAsGroup: - description: The GID to run the entrypoint of the container - process. Uses runtime default if unset. May also be set - in PodSecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. - format: int64 - type: integer - runAsNonRoot: - description: Indicates that the container must run as a - non-root user. If true, the Kubelet will validate the - image at runtime to ensure that it does not run as UID - 0 (root) and fail to start the container if it does. If - unset or false, no such validation will be performed. - May also be set in PodSecurityContext. If set in both - SecurityContext and PodSecurityContext, the value specified - in SecurityContext takes precedence. - type: boolean - runAsUser: - description: The UID to run the entrypoint of the container - process. Defaults to user specified in image metadata - if unspecified. May also be set in PodSecurityContext. If - set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. Note - that this field cannot be set when spec.os.name is windows. - format: int64 - type: integer - seLinuxOptions: - description: The SELinux context to be applied to the container. - If unspecified, the container runtime will allocate a - random SELinux context for each container. May also be - set in PodSecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. Note that this field cannot be set when - spec.os.name is windows. - properties: - level: - description: Level is SELinux level label that applies - to the container. - type: string - role: - description: Role is a SELinux role label that applies - to the container. - type: string - type: - description: Type is a SELinux type label that applies - to the container. - type: string - user: - description: User is a SELinux user label that applies - to the container. - type: string - type: object - seccompProfile: - description: The seccomp options to use by this container. - If seccomp options are provided at both the pod & container - level, the container options override the pod options. - Note that this field cannot be set when spec.os.name is - windows. - properties: - localhostProfile: - description: localhostProfile indicates a profile defined - in a file on the node should be used. The profile - must be preconfigured on the node to work. Must be - a descending path, relative to the kubelet's configured - seccomp profile location. Must be set if type is "Localhost". - Must NOT be set for any other type. - type: string - type: - description: "type indicates which kind of seccomp profile - will be applied. Valid options are: \n Localhost - - a profile defined in a file on the node should be - used. RuntimeDefault - the container runtime default - profile should be used. Unconfined - no profile should - be applied." - type: string - required: - - type - type: object - windowsOptions: - description: The Windows specific settings applied to all - containers. If unspecified, the options from the PodSecurityContext - will be used. If set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. - Note that this field cannot be set when spec.os.name is - linux. - properties: - gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA admission - webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec named - by the GMSACredentialSpecName field. - type: string - gmsaCredentialSpecName: - description: GMSACredentialSpecName is the name of the - GMSA credential spec to use. - type: string - hostProcess: - description: HostProcess determines if a container should - be run as a 'Host Process' container. All of a Pod's - containers must have the same effective HostProcess - value (it is not allowed to have a mix of HostProcess - containers and non-HostProcess containers). In addition, - if HostProcess is true then HostNetwork must also - be set to true. - type: boolean - runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set - in PodSecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence. - type: string - type: object - type: object - startupProbe: - description: 'StartupProbe indicates that the Pod has successfully - initialized. If specified, no other probes are executed until - this completes successfully. If this probe fails, the Pod - will be restarted, just as if the livenessProbe failed. This - can be used to provide different probe parameters at the beginning - of a Pod''s lifecycle, when it might take a long time to load - data or warm a cache, than during steady-state operation. - This cannot be updated. More info: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - properties: - exec: - description: Exec specifies the action to take. - properties: - command: - description: Command is the command line to execute - inside the container, the working directory for the - command is root ('/') in the container's filesystem. - The command is simply exec'd, it is not run inside - a shell, so traditional shell instructions ('|', etc) - won't work. To use a shell, you need to explicitly - call out to that shell. Exit status of 0 is treated - as live/healthy and non-zero is unhealthy. - items: - type: string - type: array - type: object - failureThreshold: - description: Minimum consecutive failures for the probe - to be considered failed after having succeeded. Defaults - to 3. Minimum value is 1. - format: int32 - type: integer - grpc: - description: GRPC specifies an action involving a GRPC port. - properties: - port: - description: Port number of the gRPC service. Number - must be in the range 1 to 65535. - format: int32 - type: integer - service: - description: "Service is the name of the service to - place in the gRPC HealthCheckRequest (see https://github.com/grpc/grpc/blob/master/doc/health-checking.md). - \n If this is not specified, the default behavior - is defined by gRPC." - type: string - required: - - port - type: object - httpGet: - description: HTTPGet specifies the http request to perform. - properties: - host: - description: Host name to connect to, defaults to the - pod IP. You probably want to set "Host" in httpHeaders - instead. - type: string - httpHeaders: - description: Custom headers to set in the request. HTTP - allows repeated headers. - items: - description: HTTPHeader describes a custom header - to be used in HTTP probes - properties: - name: - description: The header field name. This will - be canonicalized upon output, so case-variant - names will be understood as the same header. - type: string - value: - description: The header field value - type: string - required: - - name - - value - type: object - type: array - path: - description: Path to access on the HTTP server. - type: string - port: - anyOf: - - type: integer - - type: string - description: Name or number of the port to access on - the container. Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - scheme: - description: Scheme to use for connecting to the host. - Defaults to HTTP. - type: string - required: - - port - type: object - initialDelaySeconds: - description: 'Number of seconds after the container has - started before liveness probes are initiated. More info: - https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - periodSeconds: - description: How often (in seconds) to perform the probe. - Default to 10 seconds. Minimum value is 1. - format: int32 - type: integer - successThreshold: - description: Minimum consecutive successes for the probe - to be considered successful after having failed. Defaults - to 1. Must be 1 for liveness and startup. Minimum value - is 1. - format: int32 - type: integer - tcpSocket: - description: TCPSocket specifies an action involving a TCP - port. - properties: - host: - description: 'Optional: Host name to connect to, defaults - to the pod IP.' - type: string - port: - anyOf: - - type: integer - - type: string - description: Number or name of the port to access on - the container. Number must be in the range 1 to 65535. - Name must be an IANA_SVC_NAME. - x-kubernetes-int-or-string: true - required: - - port - type: object - terminationGracePeriodSeconds: - description: Optional duration in seconds the pod needs - to terminate gracefully upon probe failure. The grace - period is the duration in seconds after the processes - running in the pod are sent a termination signal and the - time when the processes are forcibly halted with a kill - signal. Set this value longer than the expected cleanup - time for your process. If this value is nil, the pod's - terminationGracePeriodSeconds will be used. Otherwise, - this value overrides the value provided by the pod spec. - Value must be non-negative integer. The value zero indicates - stop immediately via the kill signal (no opportunity to - shut down). This is a beta field and requires enabling - ProbeTerminationGracePeriod feature gate. Minimum value - is 1. spec.terminationGracePeriodSeconds is used if unset. - format: int64 - type: integer - timeoutSeconds: - description: 'Number of seconds after which the probe times - out. Defaults to 1 second. Minimum value is 1. More info: - https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#container-probes' - format: int32 - type: integer - type: object - stdin: - description: Whether this container should allocate a buffer - for stdin in the container runtime. If this is not set, reads - from stdin in the container will always result in EOF. Default - is false. - type: boolean - stdinOnce: - description: Whether the container runtime should close the - stdin channel after it has been opened by a single attach. - When stdin is true the stdin stream will remain open across - multiple attach sessions. If stdinOnce is set to true, stdin - is opened on container start, is empty until the first client - attaches to stdin, and then remains open and accepts data - until the client disconnects, at which time stdin is closed - and remains closed until the container is restarted. If this - flag is false, a container processes that reads from stdin - will never receive an EOF. Default is false - type: boolean - terminationMessagePath: - description: 'Optional: Path at which the file to which the - container''s termination message will be written is mounted - into the container''s filesystem. Message written is intended - to be brief final status, such as an assertion failure message. - Will be truncated by the node if greater than 4096 bytes. - The total message length across all containers will be limited - to 12kb. Defaults to /dev/termination-log. Cannot be updated.' - type: string - terminationMessagePolicy: - description: Indicate how the termination message should be - populated. File will use the contents of terminationMessagePath - to populate the container status message on both success and - failure. FallbackToLogsOnError will use the last chunk of - container log output if the termination message file is empty - and the container exited with an error. The log output is - limited to 2048 bytes or 80 lines, whichever is smaller. Defaults - to File. Cannot be updated. - type: string - tty: - description: Whether this container should allocate a TTY for - itself, also requires 'stdin' to be true. Default is false. - type: boolean - volumeDevices: - description: volumeDevices is the list of block devices to be - used by the container. - items: - description: volumeDevice describes a mapping of a raw block - device within a container. - properties: - devicePath: - description: devicePath is the path inside of the container - that the device will be mapped to. - type: string - name: - description: name must match the name of a persistentVolumeClaim - in the pod - type: string - required: - - devicePath - - name - type: object - type: array - volumeMounts: - description: Pod volumes to mount into the container's filesystem. - Cannot be updated. - items: - description: VolumeMount describes a mounting of a Volume - within a container. - properties: - mountPath: - description: Path within the container at which the volume - should be mounted. Must not contain ':'. - type: string - mountPropagation: - description: mountPropagation determines how mounts are - propagated from the host to container and the other - way around. When not set, MountPropagationNone is used. - This field is beta in 1.10. - type: string - name: - description: This must match the Name of a Volume. - type: string - readOnly: - description: Mounted read-only if true, read-write otherwise - (false or unspecified). Defaults to false. - type: boolean - subPath: - description: Path within the volume from which the container's - volume should be mounted. Defaults to "" (volume's root). - type: string - subPathExpr: - description: Expanded path within the volume from which - the container's volume should be mounted. Behaves similarly - to SubPath but environment variable references $(VAR_NAME) - are expanded using the container's environment. Defaults - to "" (volume's root). SubPathExpr and SubPath are mutually - exclusive. - type: string - required: - - mountPath - - name - type: object - type: array - workingDir: - description: Container's working directory. If not specified, - the container runtime's default will be used, which might - be configured in the container image. Cannot be updated. - type: string - required: - - name - type: object - type: array - integrations: - description: Integrations controls the integration subsystem of the - Agent and settings unique to deployed integration-specific pods. - properties: - namespaceSelector: - description: "Label selector for namespaces to search when discovering - integration resources. If nil, integration resources are only - discovered in the namespace of the GrafanaAgent resource. \n - Set to `{}` to search all namespaces." - properties: - matchExpressions: - description: matchExpressions is a list of label selector - requirements. The requirements are ANDed. - items: - description: A label selector requirement is a selector - that contains values, a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key that the selector - applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, NotIn, - Exists and DoesNotExist. - type: string - values: - description: values is an array of string values. If - the operator is In or NotIn, the values array must - be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. This array is replaced - during a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. A - single {key,value} in the matchLabels map is equivalent - to an element of matchExpressions, whose key field is "key", - the operator is "In", and the values array contains only - "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - selector: - description: Label selector to find Integration resources to run. - When nil, no integration resources will be defined. - properties: - matchExpressions: - description: matchExpressions is a list of label selector - requirements. The requirements are ANDed. - items: - description: A label selector requirement is a selector - that contains values, a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key that the selector - applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, NotIn, - Exists and DoesNotExist. - type: string - values: - description: values is an array of string values. If - the operator is In or NotIn, the values array must - be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. This array is replaced - during a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. A - single {key,value} in the matchLabels map is equivalent - to an element of matchExpressions, whose key field is "key", - the operator is "In", and the values array contains only - "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - type: object - logFormat: - description: LogFormat controls the logging format of the generated - pods. Defaults to "logfmt" if not set. - type: string - logLevel: - description: LogLevel controls the log level of the generated pods. - Defaults to "info" if not set. - type: string - logs: - description: Logs controls the logging subsystem of the Agent and - settings unique to logging-specific pods that are deployed. - properties: - clients: - description: A global set of clients to use when a discovered - LogsInstance does not have any clients defined. - items: - description: LogsClientSpec defines the client integration for - logs, indicating which Loki server to send logs to. - properties: - backoffConfig: - description: Configures how to retry requests to Loki when - a request fails. Defaults to a minPeriod of 500ms, maxPeriod - of 5m, and maxRetries of 10. - properties: - maxPeriod: - description: Maximum backoff time between retries. - type: string - maxRetries: - description: Maximum number of retries to perform before - giving up a request. - type: integer - minPeriod: - description: Initial backoff time between retries. Time - between retries is increased exponentially. - type: string - type: object - basicAuth: - description: BasicAuth for the Loki server. - properties: - password: - description: The secret in the service monitor namespace - that contains the password for authentication. - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the Secret or its key - must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - username: - description: The secret in the service monitor namespace - that contains the username for authentication. - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the Secret or its key - must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - batchSize: - description: Maximum batch size (in bytes) of logs to accumulate - before sending the batch to Loki. - type: integer - batchWait: - description: Maximum amount of time to wait before sending - a batch, even if that batch isn't full. - type: string - bearerToken: - description: BearerToken used for remote_write. - type: string - bearerTokenFile: - description: BearerTokenFile used to read bearer token. - type: string - externalLabels: - additionalProperties: - type: string - description: ExternalLabels are labels to add to any time - series when sending data to Loki. - type: object - oauth2: - description: Oauth2 for URL - properties: - clientId: - description: The secret or configmap containing the - OAuth2 client id - properties: - configMap: - description: ConfigMap containing data to use for - the targets. - properties: - key: - description: The key to select. - type: string - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the ConfigMap or - its key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - secret: - description: Secret containing data to use for the - targets. - properties: - key: - description: The key of the secret to select - from. Must be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the Secret or its - key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - clientSecret: - description: The secret containing the OAuth2 client - secret - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the Secret or its key - must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - endpointParams: - additionalProperties: - type: string - description: Parameters to append to the token URL - type: object - scopes: - description: OAuth2 scopes used for the token request - items: - type: string - type: array - tokenUrl: - description: The URL to fetch the token from - minLength: 1 - type: string - required: - - clientId - - clientSecret - - tokenUrl - type: object - proxyUrl: - description: ProxyURL to proxy requests through. Optional. - type: string - tenantId: - description: Tenant ID used by default to push logs to Loki. - If omitted assumes remote Loki is running in single-tenant - mode or an authentication layer is used to inject an X-Scope-OrgID - header. - type: string - timeout: - description: Maximum time to wait for a server to respond - to a request. - type: string - tlsConfig: - description: TLSConfig to use for the client. Only used - when the protocol of the URL is https. - properties: - ca: - description: Certificate authority used when verifying - server certificates. - properties: - configMap: - description: ConfigMap containing data to use for - the targets. - properties: - key: - description: The key to select. - type: string - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the ConfigMap or - its key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - secret: - description: Secret containing data to use for the - targets. - properties: - key: - description: The key of the secret to select - from. Must be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the Secret or its - key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - caFile: - description: Path to the CA cert in the Prometheus container - to use for the targets. - type: string - cert: - description: Client certificate to present when doing - client-authentication. - properties: - configMap: - description: ConfigMap containing data to use for - the targets. - properties: - key: - description: The key to select. - type: string - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the ConfigMap or - its key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - secret: - description: Secret containing data to use for the - targets. - properties: - key: - description: The key of the secret to select - from. Must be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the Secret or its - key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - certFile: - description: Path to the client cert file in the Prometheus - container for the targets. - type: string - insecureSkipVerify: - description: Disable target certificate validation. - type: boolean - keyFile: - description: Path to the client key file in the Prometheus - container for the targets. - type: string - keySecret: - description: Secret containing the client key file for - the targets. - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the Secret or its key - must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - serverName: - description: Used to verify the hostname for the targets. - type: string - type: object - url: - description: 'URL is the URL where Loki is listening. Must - be a full HTTP URL, including protocol. Required. Example: - https://logs-prod-us-central1.grafana.net/loki/api/v1/push.' - type: string - required: - - url - type: object - type: array - enforcedNamespaceLabel: - description: EnforcedNamespaceLabel enforces adding a namespace - label of origin for each metric that is user-created. The label - value will always be the namespace of the object that is being - created. - type: string - ignoreNamespaceSelectors: - description: IgnoreNamespaceSelectors, if true, will ignore NamespaceSelector - settings from the PodLogs configs, and they will only discover - endpoints within their current namespace. - type: boolean - instanceNamespaceSelector: - description: InstanceNamespaceSelector are the set of labels to - determine which namespaces to watch for LogInstances. If not - provided, only checks own namespace. - properties: - matchExpressions: - description: matchExpressions is a list of label selector - requirements. The requirements are ANDed. - items: - description: A label selector requirement is a selector - that contains values, a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key that the selector - applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, NotIn, - Exists and DoesNotExist. - type: string - values: - description: values is an array of string values. If - the operator is In or NotIn, the values array must - be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. This array is replaced - during a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. A - single {key,value} in the matchLabels map is equivalent - to an element of matchExpressions, whose key field is "key", - the operator is "In", and the values array contains only - "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - instanceSelector: - description: InstanceSelector determines which LogInstances should - be selected for running. Each instance runs its own set of Prometheus - components, including service discovery, scraping, and remote_write. - properties: - matchExpressions: - description: matchExpressions is a list of label selector - requirements. The requirements are ANDed. - items: - description: A label selector requirement is a selector - that contains values, a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key that the selector - applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, NotIn, - Exists and DoesNotExist. - type: string - values: - description: values is an array of string values. If - the operator is In or NotIn, the values array must - be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. This array is replaced - during a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. A - single {key,value} in the matchLabels map is equivalent - to an element of matchExpressions, whose key field is "key", - the operator is "In", and the values array contains only - "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - logsExternalLabelName: - description: LogsExternalLabelName is the name of the external - label used to denote Grafana Agent cluster. Defaults to "cluster." - External label will _not_ be added when value is set to the - empty string. - type: string - type: object - metrics: - description: Metrics controls the metrics subsystem of the Agent and - settings unique to metrics-specific pods that are deployed. - properties: - arbitraryFSAccessThroughSMs: - description: ArbitraryFSAccessThroughSMs configures whether configuration - based on a ServiceMonitor can access arbitrary files on the - file system of the Grafana Agent container, e.g., bearer token - files. - properties: - deny: - type: boolean - type: object - enforcedNamespaceLabel: - description: EnforcedNamespaceLabel enforces adding a namespace - label of origin for each metric that is user-created. The label - value is always the namespace of the object that is being created. - type: string - enforcedSampleLimit: - description: EnforcedSampleLimit defines a global limit on the - number of scraped samples that are accepted. This overrides - any SampleLimit set per ServiceMonitor and/or PodMonitor. It - is meant to be used by admins to enforce the SampleLimit to - keep the overall number of samples and series under the desired - limit. Note that if a SampleLimit from a ServiceMonitor or PodMonitor - is lower, that value is used instead. - format: int64 - type: integer - enforcedTargetLimit: - description: EnforcedTargetLimit defines a global limit on the - number of scraped targets. This overrides any TargetLimit set - per ServiceMonitor and/or PodMonitor. It is meant to be used - by admins to enforce the TargetLimit to keep the overall number - of targets under the desired limit. Note that if a TargetLimit - from a ServiceMonitor or PodMonitor is higher, that value is - used instead. - format: int64 - type: integer - externalLabels: - additionalProperties: - type: string - description: ExternalLabels are labels to add to any time series - when sending data over remote_write. - type: object - ignoreNamespaceSelectors: - description: IgnoreNamespaceSelectors, if true, ignores NamespaceSelector - settings from the PodMonitor and ServiceMonitor configs, so - that they only discover endpoints within their current namespace. - type: boolean - instanceNamespaceSelector: - description: InstanceNamespaceSelector is the set of labels that - determines which namespaces to watch for MetricsInstances. If - not provided, it only checks its own namespace. - properties: - matchExpressions: - description: matchExpressions is a list of label selector - requirements. The requirements are ANDed. - items: - description: A label selector requirement is a selector - that contains values, a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key that the selector - applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, NotIn, - Exists and DoesNotExist. - type: string - values: - description: values is an array of string values. If - the operator is In or NotIn, the values array must - be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. This array is replaced - during a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. A - single {key,value} in the matchLabels map is equivalent - to an element of matchExpressions, whose key field is "key", - the operator is "In", and the values array contains only - "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - instanceSelector: - description: InstanceSelector determines which MetricsInstances - should be selected for running. Each instance runs its own set - of Metrics components, including service discovery, scraping, - and remote_write. - properties: - matchExpressions: - description: matchExpressions is a list of label selector - requirements. The requirements are ANDed. - items: - description: A label selector requirement is a selector - that contains values, a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key that the selector - applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, NotIn, - Exists and DoesNotExist. - type: string - values: - description: values is an array of string values. If - the operator is In or NotIn, the values array must - be non-empty. If the operator is Exists or DoesNotExist, - the values array must be empty. This array is replaced - during a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. A - single {key,value} in the matchLabels map is equivalent - to an element of matchExpressions, whose key field is "key", - the operator is "In", and the values array contains only - "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - metricsExternalLabelName: - description: MetricsExternalLabelName is the name of the external - label used to denote Grafana Agent cluster. Defaults to "cluster." - The external label is _not_ added when the value is set to the - empty string. - type: string - overrideHonorLabels: - description: OverrideHonorLabels, if true, overrides all configured - honor_labels read from ServiceMonitor or PodMonitor and sets - them to false. - type: boolean - overrideHonorTimestamps: - description: OverrideHonorTimestamps allows global enforcement - for honoring timestamps in all scrape configs. - type: boolean - remoteWrite: - description: RemoteWrite controls default remote_write settings - for all instances. If an instance does not provide its own RemoteWrite - settings, these will be used instead. - items: - description: RemoteWriteSpec defines the remote_write configuration - for Prometheus. - properties: - basicAuth: - description: BasicAuth for the URL. - properties: - password: - description: The secret in the service monitor namespace - that contains the password for authentication. - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the Secret or its key - must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - username: - description: The secret in the service monitor namespace - that contains the username for authentication. - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the Secret or its key - must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - bearerToken: - description: BearerToken used for remote_write. - type: string - bearerTokenFile: - description: BearerTokenFile used to read bearer token. - type: string - headers: - additionalProperties: - type: string - description: Headers is a set of custom HTTP headers to - be sent along with each remote_write request. Be aware - that any headers set by Grafana Agent itself can't be - overwritten. - type: object - metadataConfig: - description: MetadataConfig configures the sending of series - metadata to remote storage. - properties: - send: - description: Send enables metric metadata to be sent - to remote storage. - type: boolean - sendInterval: - description: SendInterval controls how frequently metric - metadata is sent to remote storage. - type: string - type: object - name: - description: Name of the remote_write queue. Must be unique - if specified. The name is used in metrics and logging - in order to differentiate queues. - type: string - oauth2: - description: Oauth2 for URL - properties: - clientId: - description: The secret or configmap containing the - OAuth2 client id - properties: - configMap: - description: ConfigMap containing data to use for - the targets. - properties: - key: - description: The key to select. - type: string - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the ConfigMap or - its key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - secret: - description: Secret containing data to use for the - targets. - properties: - key: - description: The key of the secret to select - from. Must be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the Secret or its - key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - clientSecret: - description: The secret containing the OAuth2 client - secret - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the Secret or its key - must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - endpointParams: - additionalProperties: - type: string - description: Parameters to append to the token URL - type: object - scopes: - description: OAuth2 scopes used for the token request - items: - type: string - type: array - tokenUrl: - description: The URL to fetch the token from - minLength: 1 - type: string - required: - - clientId - - clientSecret - - tokenUrl - type: object - proxyUrl: - description: ProxyURL to proxy requests through. Optional. - type: string - queueConfig: - description: QueueConfig allows tuning of the remote_write - queue parameters. - properties: - batchSendDeadline: - description: BatchSendDeadline is the maximum time a - sample will wait in the buffer. - type: string - capacity: - description: Capacity is the number of samples to buffer - per shard before samples start being dropped. - type: integer - maxBackoff: - description: MaxBackoff is the maximum retry delay. - type: string - maxRetries: - description: MaxRetries is the maximum number of times - to retry a batch on recoverable errors. - type: integer - maxSamplesPerSend: - description: MaxSamplesPerSend is the maximum number - of samples per send. - type: integer - maxShards: - description: MaxShards is the maximum number of shards, - i.e., the amount of concurrency. - type: integer - minBackoff: - description: MinBackoff is the initial retry delay. - MinBackoff is doubled for every retry. - type: string - minShards: - description: MinShards is the minimum number of shards, - i.e., the amount of concurrency. - type: integer - retryOnRateLimit: - description: RetryOnRateLimit retries requests when - encountering rate limits. - type: boolean - type: object - remoteTimeout: - description: RemoteTimeout is the timeout for requests to - the remote_write endpoint. - type: string - sigv4: - description: SigV4 configures SigV4-based authentication - to the remote_write endpoint. SigV4-based authentication - is used if SigV4 is defined, even with an empty object. - properties: - accessKey: - description: AccessKey holds the secret of the AWS API - access key to use for signing. If not provided, the - environment variable AWS_ACCESS_KEY_ID is used. - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the Secret or its key - must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - profile: - description: Profile is the named AWS profile to use - for authentication. - type: string - region: - description: Region of the AWS endpoint. If blank, the - region from the default credentials chain is used. - type: string - roleARN: - description: RoleARN is the AWS Role ARN to use for - authentication, as an alternative for using the AWS - API keys. - type: string - secretKey: - description: SecretKey of the AWS API to use for signing. - If blank, the environment variable AWS_SECRET_ACCESS_KEY - is used. - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the Secret or its key - must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - tlsConfig: - description: TLSConfig to use for remote_write. - properties: - ca: - description: Certificate authority used when verifying - server certificates. - properties: - configMap: - description: ConfigMap containing data to use for - the targets. - properties: - key: - description: The key to select. - type: string - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the ConfigMap or - its key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - secret: - description: Secret containing data to use for the - targets. - properties: - key: - description: The key of the secret to select - from. Must be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the Secret or its - key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - caFile: - description: Path to the CA cert in the Prometheus container - to use for the targets. - type: string - cert: - description: Client certificate to present when doing - client-authentication. - properties: - configMap: - description: ConfigMap containing data to use for - the targets. - properties: - key: - description: The key to select. - type: string - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the ConfigMap or - its key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - secret: - description: Secret containing data to use for the - targets. - properties: - key: - description: The key of the secret to select - from. Must be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, - kind, uid?' - type: string - optional: - description: Specify whether the Secret or its - key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - certFile: - description: Path to the client cert file in the Prometheus - container for the targets. - type: string - insecureSkipVerify: - description: Disable target certificate validation. - type: boolean - keyFile: - description: Path to the client key file in the Prometheus - container for the targets. - type: string - keySecret: - description: Secret containing the client key file for - the targets. - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the Secret or its key - must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - serverName: - description: Used to verify the hostname for the targets. - type: string - type: object - url: - description: URL of the endpoint to send samples to. - type: string - writeRelabelConfigs: - description: WriteRelabelConfigs holds relabel_configs to - relabel samples before they are sent to the remote_write - endpoint. - items: - description: 'RelabelConfig allows dynamic rewriting of - the label set, being applied to samples before ingestion. - It defines ``-section of Prometheus - configuration. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs' - properties: - action: - default: replace - description: Action to perform based on regex matching. - Default is 'replace'. uppercase and lowercase actions - require Prometheus >= 2.36. - enum: - - replace - - Replace - - keep - - Keep - - drop - - Drop - - hashmod - - HashMod - - labelmap - - LabelMap - - labeldrop - - LabelDrop - - labelkeep - - LabelKeep - - lowercase - - Lowercase - - uppercase - - Uppercase - - keepequal - - KeepEqual - - dropequal - - DropEqual - type: string - modulus: - description: Modulus to take of the hash of the source - label values. - format: int64 - type: integer - regex: - description: Regular expression against which the - extracted value is matched. Default is '(.*)' - type: string - replacement: - description: Replacement value against which a regex - replace is performed if the regular expression matches. - Regex capture groups are available. Default is '$1' - type: string - separator: - description: Separator placed between concatenated - source label values. default is ';'. - type: string - sourceLabels: - description: The source labels select values from - existing labels. Their content is concatenated using - the configured separator and matched against the - configured regular expression for the replace, keep, - and drop actions. - items: - description: LabelName is a valid Prometheus label - name which may only contain ASCII letters, numbers, - as well as underscores. - pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ - type: string - type: array - targetLabel: - description: Label to which the resulting value is - written in a replace action. It is mandatory for - replace actions. Regex capture groups are available. - type: string - type: object - type: array - required: - - url - type: object - type: array - replicaExternalLabelName: - description: ReplicaExternalLabelName is the name of the metrics - external label used to denote the replica name. Defaults to - __replica__. The external label is _not_ added when the value - is set to the empty string. - type: string - replicas: - description: Replicas of each shard to deploy for metrics pods. - Number of replicas multiplied by the number of shards is the - total number of pods created. - format: int32 - type: integer - scrapeInterval: - description: ScrapeInterval is the time between consecutive scrapes. - type: string - scrapeTimeout: - description: ScrapeTimeout is the time to wait for a target to - respond before marking a scrape as failed. - type: string - shards: - description: Shards to distribute targets onto. Number of replicas - multiplied by the number of shards is the total number of pods - created. Note that scaling down shards does not reshard data - onto remaining instances; it must be manually moved. Increasing - shards does not reshard data either, but it will continue to - be available from the same instances. Sharding is performed - on the content of the __address__ target meta-label. - format: int32 - type: integer - type: object - nodeSelector: - additionalProperties: - type: string - description: NodeSelector defines which nodes pods should be scheduling - on. - type: object - paused: - description: Paused prevents actions except for deletion to be performed - on the underlying managed objects. - type: boolean - podMetadata: - description: PodMetadata configures Labels and Annotations which are - propagated to created Grafana Agent pods. - properties: - annotations: - additionalProperties: - type: string - description: 'Annotations is an unstructured key value map stored - with a resource that may be set by external tools to store and - retrieve arbitrary metadata. They are not queryable and should - be preserved when modifying objects. More info: http://kubernetes.io/docs/user-guide/annotations' - type: object - labels: - additionalProperties: - type: string - description: 'Map of string keys and values that can be used to - organize and categorize (scope and select) objects. May match - selectors of replication controllers and services. More info: - http://kubernetes.io/docs/user-guide/labels' - type: object - name: - description: 'Name must be unique within a namespace. Is required - when creating resources, although some resources may allow a - client to request the generation of an appropriate name automatically. - Name is primarily intended for creation idempotence and configuration - definition. Cannot be updated. More info: http://kubernetes.io/docs/user-guide/identifiers#names' - type: string - type: object - portName: - description: Port name used for the pods and governing service. This - defaults to agent-metrics. - type: string - priorityClassName: - description: PriorityClassName is the priority class assigned to pods. - type: string - resources: - description: Resources holds requests and limits for individual pods. - properties: - claims: - description: "Claims lists the names of resources, defined in - spec.resourceClaims, that are used by this container. \n This - is an alpha field and requires enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. It can only be set - for containers." - items: - description: ResourceClaim references one entry in PodSpec.ResourceClaims. - properties: - name: - description: Name must match the name of one entry in pod.spec.resourceClaims - of the Pod where this field is used. It makes that resource - available inside a container. - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount of compute resources - allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount of compute - resources required. If Requests is omitted for a container, - it defaults to Limits if that is explicitly specified, otherwise - to an implementation-defined value. Requests cannot exceed Limits. - More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - type: object - runtimeClassName: - description: RuntimeClassName is the runtime class assigned to pods. - type: string - secrets: - description: Secrets is a list of secrets in the same namespace as - the GrafanaAgent object which will be mounted into each running - Grafana Agent pod. The secrets are mounted into /var/lib/grafana-agent/extra-secrets/. - items: - type: string - type: array - securityContext: - description: SecurityContext holds pod-level security attributes and - common container settings. When unspecified, defaults to the default - PodSecurityContext. - properties: - fsGroup: - description: "A special supplemental group that applies to all - containers in a pod. Some volume types allow the Kubelet to - change the ownership of that volume to be owned by the pod: - \n 1. The owning GID will be the FSGroup 2. The setgid bit is - set (new files created in the volume will be owned by FSGroup) - 3. The permission bits are OR'd with rw-rw---- \n If unset, - the Kubelet will not modify the ownership and permissions of - any volume. Note that this field cannot be set when spec.os.name - is windows." - format: int64 - type: integer - fsGroupChangePolicy: - description: 'fsGroupChangePolicy defines behavior of changing - ownership and permission of the volume before being exposed - inside Pod. This field will only apply to volume types which - support fsGroup based ownership(and permissions). It will have - no effect on ephemeral volume types such as: secret, configmaps - and emptydir. Valid values are "OnRootMismatch" and "Always". - If not specified, "Always" is used. Note that this field cannot - be set when spec.os.name is windows.' - type: string - runAsGroup: - description: The GID to run the entrypoint of the container process. - Uses runtime default if unset. May also be set in SecurityContext. If - set in both SecurityContext and PodSecurityContext, the value - specified in SecurityContext takes precedence for that container. - Note that this field cannot be set when spec.os.name is windows. - format: int64 - type: integer - runAsNonRoot: - description: Indicates that the container must run as a non-root - user. If true, the Kubelet will validate the image at runtime - to ensure that it does not run as UID 0 (root) and fail to start - the container if it does. If unset or false, no such validation - will be performed. May also be set in SecurityContext. If set - in both SecurityContext and PodSecurityContext, the value specified - in SecurityContext takes precedence. - type: boolean - runAsUser: - description: The UID to run the entrypoint of the container process. - Defaults to user specified in image metadata if unspecified. - May also be set in SecurityContext. If set in both SecurityContext - and PodSecurityContext, the value specified in SecurityContext - takes precedence for that container. Note that this field cannot - be set when spec.os.name is windows. - format: int64 - type: integer - seLinuxOptions: - description: The SELinux context to be applied to all containers. - If unspecified, the container runtime will allocate a random - SELinux context for each container. May also be set in SecurityContext. If - set in both SecurityContext and PodSecurityContext, the value - specified in SecurityContext takes precedence for that container. - Note that this field cannot be set when spec.os.name is windows. - properties: - level: - description: Level is SELinux level label that applies to - the container. - type: string - role: - description: Role is a SELinux role label that applies to - the container. - type: string - type: - description: Type is a SELinux type label that applies to - the container. - type: string - user: - description: User is a SELinux user label that applies to - the container. - type: string - type: object - seccompProfile: - description: The seccomp options to use by the containers in this - pod. Note that this field cannot be set when spec.os.name is - windows. - properties: - localhostProfile: - description: localhostProfile indicates a profile defined - in a file on the node should be used. The profile must be - preconfigured on the node to work. Must be a descending - path, relative to the kubelet's configured seccomp profile - location. Must be set if type is "Localhost". Must NOT be - set for any other type. - type: string - type: - description: "type indicates which kind of seccomp profile - will be applied. Valid options are: \n Localhost - a profile - defined in a file on the node should be used. RuntimeDefault - - the container runtime default profile should be used. - Unconfined - no profile should be applied." - type: string - required: - - type - type: object - supplementalGroups: - description: A list of groups applied to the first process run - in each container, in addition to the container's primary GID, - the fsGroup (if specified), and group memberships defined in - the container image for the uid of the container process. If - unspecified, no additional groups are added to any container. - Note that group memberships defined in the container image for - the uid of the container process are still effective, even if - they are not included in this list. Note that this field cannot - be set when spec.os.name is windows. - items: - format: int64 - type: integer - type: array - sysctls: - description: Sysctls hold a list of namespaced sysctls used for - the pod. Pods with unsupported sysctls (by the container runtime) - might fail to launch. Note that this field cannot be set when - spec.os.name is windows. - items: - description: Sysctl defines a kernel parameter to be set - properties: - name: - description: Name of a property to set - type: string - value: - description: Value of a property to set - type: string - required: - - name - - value - type: object - type: array - windowsOptions: - description: The Windows specific settings applied to all containers. - If unspecified, the options within a container's SecurityContext - will be used. If set in both SecurityContext and PodSecurityContext, - the value specified in SecurityContext takes precedence. Note - that this field cannot be set when spec.os.name is linux. - properties: - gmsaCredentialSpec: - description: GMSACredentialSpec is where the GMSA admission - webhook (https://github.com/kubernetes-sigs/windows-gmsa) - inlines the contents of the GMSA credential spec named by - the GMSACredentialSpecName field. - type: string - gmsaCredentialSpecName: - description: GMSACredentialSpecName is the name of the GMSA - credential spec to use. - type: string - hostProcess: - description: HostProcess determines if a container should - be run as a 'Host Process' container. All of a Pod's containers - must have the same effective HostProcess value (it is not - allowed to have a mix of HostProcess containers and non-HostProcess - containers). In addition, if HostProcess is true then HostNetwork - must also be set to true. - type: boolean - runAsUserName: - description: The UserName in Windows to run the entrypoint - of the container process. Defaults to the user specified - in image metadata if unspecified. May also be set in PodSecurityContext. - If set in both SecurityContext and PodSecurityContext, the - value specified in SecurityContext takes precedence. - type: string - type: object - type: object - serviceAccountName: - description: ServiceAccountName is the name of the ServiceAccount - to use for running Grafana Agent pods. - type: string - storage: - description: Storage spec to specify how storage will be used. - properties: - disableMountSubPath: - description: '*Deprecated: subPath usage will be removed in a - future release.*' - type: boolean - emptyDir: - description: 'EmptyDirVolumeSource to be used by the StatefulSet. - If specified, it takes precedence over `ephemeral` and `volumeClaimTemplate`. - More info: https://kubernetes.io/docs/concepts/storage/volumes/#emptydir' - properties: - medium: - description: 'medium represents what type of storage medium - should back this directory. The default is "" which means - to use the node''s default medium. Must be an empty string - (default) or Memory. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' - type: string - sizeLimit: - anyOf: - - type: integer - - type: string - description: 'sizeLimit is the total amount of local storage - required for this EmptyDir volume. The size limit is also - applicable for memory medium. The maximum usage on memory - medium EmptyDir would be the minimum value between the SizeLimit - specified here and the sum of memory limits of all containers - in a pod. The default is nil which means that the limit - is undefined. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - ephemeral: - description: 'EphemeralVolumeSource to be used by the StatefulSet. - This is a beta field in k8s 1.21 and GA in 1.15. For lower versions, - starting with k8s 1.19, it requires enabling the GenericEphemeralVolume - feature gate. More info: https://kubernetes.io/docs/concepts/storage/ephemeral-volumes/#generic-ephemeral-volumes' - properties: - volumeClaimTemplate: - description: "Will be used to create a stand-alone PVC to - provision the volume. The pod in which this EphemeralVolumeSource - is embedded will be the owner of the PVC, i.e. the PVC will - be deleted together with the pod. The name of the PVC will - be `-` where `` is the - name from the `PodSpec.Volumes` array entry. Pod validation - will reject the pod if the concatenated name is not valid - for a PVC (for example, too long). \n An existing PVC with - that name that is not owned by the pod will *not* be used - for the pod to avoid using an unrelated volume by mistake. - Starting the pod is then blocked until the unrelated PVC - is removed. If such a pre-created PVC is meant to be used - by the pod, the PVC has to updated with an owner reference - to the pod once the pod exists. Normally this should not - be necessary, but it may be useful when manually reconstructing - a broken cluster. \n This field is read-only and no changes - will be made by Kubernetes to the PVC after it has been - created. \n Required, must not be nil." - properties: - metadata: - description: May contain labels and annotations that will - be copied into the PVC when creating it. No other fields - are allowed and will be rejected during validation. - type: object - spec: - description: The specification for the PersistentVolumeClaim. - The entire content is copied unchanged into the PVC - that gets created from this template. The same fields - as in a PersistentVolumeClaim are also valid here. - properties: - accessModes: - description: 'accessModes contains the desired access - modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' - items: - type: string - type: array - dataSource: - description: 'dataSource field can be used to specify - either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) - * An existing PVC (PersistentVolumeClaim) If the - provisioner or an external controller can support - the specified data source, it will create a new - volume based on the contents of the specified data - source. When the AnyVolumeDataSource feature gate - is enabled, dataSource contents will be copied to - dataSourceRef, and dataSourceRef contents will be - copied to dataSource when dataSourceRef.namespace - is not specified. If the namespace is specified, - then dataSourceRef will not be copied to dataSource.' - properties: - apiGroup: - description: APIGroup is the group for the resource - being referenced. If APIGroup is not specified, - the specified Kind must be in the core API group. - For any other third-party types, APIGroup is - required. - type: string - kind: - description: Kind is the type of resource being - referenced - type: string - name: - description: Name is the name of resource being - referenced - type: string - required: - - kind - - name - type: object - x-kubernetes-map-type: atomic - dataSourceRef: - description: 'dataSourceRef specifies the object from - which to populate the volume with data, if a non-empty - volume is desired. This may be any object from a - non-empty API group (non core object) or a PersistentVolumeClaim - object. When this field is specified, volume binding - will only succeed if the type of the specified object - matches some installed volume populator or dynamic - provisioner. This field will replace the functionality - of the dataSource field and as such if both fields - are non-empty, they must have the same value. For - backwards compatibility, when namespace isn''t specified - in dataSourceRef, both fields (dataSource and dataSourceRef) - will be set to the same value automatically if one - of them is empty and the other is non-empty. When - namespace is specified in dataSourceRef, dataSource - isn''t set to the same value and must be empty. - There are three important differences between dataSource - and dataSourceRef: * While dataSource only allows - two specific types of objects, dataSourceRef allows - any non-core object, as well as PersistentVolumeClaim - objects. * While dataSource ignores disallowed values - (dropping them), dataSourceRef preserves all values, - and generates an error if a disallowed value is - specified. * While dataSource only allows local - objects, dataSourceRef allows objects in any namespaces. - (Beta) Using this field requires the AnyVolumeDataSource - feature gate to be enabled. (Alpha) Using the namespace - field of dataSourceRef requires the CrossNamespaceVolumeDataSource - feature gate to be enabled.' - properties: - apiGroup: - description: APIGroup is the group for the resource - being referenced. If APIGroup is not specified, - the specified Kind must be in the core API group. - For any other third-party types, APIGroup is - required. - type: string - kind: - description: Kind is the type of resource being - referenced - type: string - name: - description: Name is the name of resource being - referenced - type: string - namespace: - description: Namespace is the namespace of resource - being referenced Note that when a namespace - is specified, a gateway.networking.k8s.io/ReferenceGrant - object is required in the referent namespace - to allow that namespace's owner to accept the - reference. See the ReferenceGrant documentation - for details. (Alpha) This field requires the - CrossNamespaceVolumeDataSource feature gate - to be enabled. - type: string - required: - - kind - - name - type: object - resources: - description: 'resources represents the minimum resources - the volume should have. If RecoverVolumeExpansionFailure - feature is enabled users are allowed to specify - resource requirements that are lower than previous - value but must still be higher than capacity recorded - in the status field of the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' - properties: - claims: - description: "Claims lists the names of resources, - defined in spec.resourceClaims, that are used - by this container. \n This is an alpha field - and requires enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. It - can only be set for containers." - items: - description: ResourceClaim references one entry - in PodSpec.ResourceClaims. - properties: - name: - description: Name must match the name of - one entry in pod.spec.resourceClaims of - the Pod where this field is used. It makes - that resource available inside a container. - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount - of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount - of compute resources required. If Requests is - omitted for a container, it defaults to Limits - if that is explicitly specified, otherwise to - an implementation-defined value. Requests cannot - exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - type: object - selector: - description: selector is a label query over volumes - to consider for binding. - properties: - matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are - ANDed. - items: - description: A label selector requirement is - a selector that contains values, a key, and - an operator that relates the key and values. - properties: - key: - description: key is the label key that the - selector applies to. - type: string - operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. If - the operator is Exists or DoesNotExist, - the values array must be empty. This array - is replaced during a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is "In", - and the values array contains only "value". - The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - storageClassName: - description: 'storageClassName is the name of the - StorageClass required by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' - type: string - volumeMode: - description: volumeMode defines what type of volume - is required by the claim. Value of Filesystem is - implied when not included in claim spec. - type: string - volumeName: - description: volumeName is the binding reference to - the PersistentVolume backing this claim. - type: string - type: object - required: - - spec - type: object - type: object - volumeClaimTemplate: - description: Defines the PVC spec to be used by the Prometheus - StatefulSets. The easiest way to use a volume that cannot be - automatically provisioned is to use a label selector alongside - manually created PersistentVolumes. - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this - representation of an object. Servers should convert recognized - schemas to the latest internal value, and may reject unrecognized - values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST - resource this object represents. Servers may infer this - from the endpoint the client submits requests to. Cannot - be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - description: EmbeddedMetadata contains metadata relevant to - an EmbeddedResource. - properties: - annotations: - additionalProperties: - type: string - description: 'Annotations is an unstructured key value - map stored with a resource that may be set by external - tools to store and retrieve arbitrary metadata. They - are not queryable and should be preserved when modifying - objects. More info: http://kubernetes.io/docs/user-guide/annotations' - type: object - labels: - additionalProperties: - type: string - description: 'Map of string keys and values that can be - used to organize and categorize (scope and select) objects. - May match selectors of replication controllers and services. - More info: http://kubernetes.io/docs/user-guide/labels' - type: object - name: - description: 'Name must be unique within a namespace. - Is required when creating resources, although some resources - may allow a client to request the generation of an appropriate - name automatically. Name is primarily intended for creation - idempotence and configuration definition. Cannot be - updated. More info: http://kubernetes.io/docs/user-guide/identifiers#names' - type: string - type: object - spec: - description: 'Defines the desired characteristics of a volume - requested by a pod author. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' - properties: - accessModes: - description: 'accessModes contains the desired access - modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' - items: - type: string - type: array - dataSource: - description: 'dataSource field can be used to specify - either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) - * An existing PVC (PersistentVolumeClaim) If the provisioner - or an external controller can support the specified - data source, it will create a new volume based on the - contents of the specified data source. When the AnyVolumeDataSource - feature gate is enabled, dataSource contents will be - copied to dataSourceRef, and dataSourceRef contents - will be copied to dataSource when dataSourceRef.namespace - is not specified. If the namespace is specified, then - dataSourceRef will not be copied to dataSource.' - properties: - apiGroup: - description: APIGroup is the group for the resource - being referenced. If APIGroup is not specified, - the specified Kind must be in the core API group. - For any other third-party types, APIGroup is required. - type: string - kind: - description: Kind is the type of resource being referenced - type: string - name: - description: Name is the name of resource being referenced - type: string - required: - - kind - - name - type: object - x-kubernetes-map-type: atomic - dataSourceRef: - description: 'dataSourceRef specifies the object from - which to populate the volume with data, if a non-empty - volume is desired. This may be any object from a non-empty - API group (non core object) or a PersistentVolumeClaim - object. When this field is specified, volume binding - will only succeed if the type of the specified object - matches some installed volume populator or dynamic provisioner. - This field will replace the functionality of the dataSource - field and as such if both fields are non-empty, they - must have the same value. For backwards compatibility, - when namespace isn''t specified in dataSourceRef, both - fields (dataSource and dataSourceRef) will be set to - the same value automatically if one of them is empty - and the other is non-empty. When namespace is specified - in dataSourceRef, dataSource isn''t set to the same - value and must be empty. There are three important differences - between dataSource and dataSourceRef: * While dataSource - only allows two specific types of objects, dataSourceRef - allows any non-core object, as well as PersistentVolumeClaim - objects. * While dataSource ignores disallowed values - (dropping them), dataSourceRef preserves all values, - and generates an error if a disallowed value is specified. - * While dataSource only allows local objects, dataSourceRef - allows objects in any namespaces. (Beta) Using this - field requires the AnyVolumeDataSource feature gate - to be enabled. (Alpha) Using the namespace field of - dataSourceRef requires the CrossNamespaceVolumeDataSource - feature gate to be enabled.' - properties: - apiGroup: - description: APIGroup is the group for the resource - being referenced. If APIGroup is not specified, - the specified Kind must be in the core API group. - For any other third-party types, APIGroup is required. - type: string - kind: - description: Kind is the type of resource being referenced - type: string - name: - description: Name is the name of resource being referenced - type: string - namespace: - description: Namespace is the namespace of resource - being referenced Note that when a namespace is specified, - a gateway.networking.k8s.io/ReferenceGrant object - is required in the referent namespace to allow that - namespace's owner to accept the reference. See the - ReferenceGrant documentation for details. (Alpha) - This field requires the CrossNamespaceVolumeDataSource - feature gate to be enabled. - type: string - required: - - kind - - name - type: object - resources: - description: 'resources represents the minimum resources - the volume should have. If RecoverVolumeExpansionFailure - feature is enabled users are allowed to specify resource - requirements that are lower than previous value but - must still be higher than capacity recorded in the status - field of the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' - properties: - claims: - description: "Claims lists the names of resources, - defined in spec.resourceClaims, that are used by - this container. \n This is an alpha field and requires - enabling the DynamicResourceAllocation feature gate. - \n This field is immutable. It can only be set for - containers." - items: - description: ResourceClaim references one entry - in PodSpec.ResourceClaims. - properties: - name: - description: Name must match the name of one - entry in pod.spec.resourceClaims of the Pod - where this field is used. It makes that resource - available inside a container. - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount - of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum amount - of compute resources required. If Requests is omitted - for a container, it defaults to Limits if that is - explicitly specified, otherwise to an implementation-defined - value. Requests cannot exceed Limits. More info: - https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - type: object - selector: - description: selector is a label query over volumes to - consider for binding. - properties: - matchExpressions: - description: matchExpressions is a list of label selector - requirements. The requirements are ANDed. - items: - description: A label selector requirement is a selector - that contains values, a key, and an operator that - relates the key and values. - properties: - key: - description: key is the label key that the selector - applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, - NotIn, Exists and DoesNotExist. - type: string - values: - description: values is an array of string values. - If the operator is In or NotIn, the values - array must be non-empty. If the operator is - Exists or DoesNotExist, the values array must - be empty. This array is replaced during a - strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. - A single {key,value} in the matchLabels map is equivalent - to an element of matchExpressions, whose key field - is "key", the operator is "In", and the values array - contains only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - storageClassName: - description: 'storageClassName is the name of the StorageClass - required by the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' - type: string - volumeMode: - description: volumeMode defines what type of volume is - required by the claim. Value of Filesystem is implied - when not included in claim spec. - type: string - volumeName: - description: volumeName is the binding reference to the - PersistentVolume backing this claim. - type: string - type: object - status: - description: '*Deprecated: this field is never set.*' - properties: - accessModes: - description: 'accessModes contains the actual access modes - the volume backing the PVC has. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' - items: - type: string - type: array - allocatedResourceStatuses: - additionalProperties: - description: When a controller receives persistentvolume - claim update with ClaimResourceStatus for a resource - that it does not recognizes, then it should ignore - that update and let other controllers handle it. - type: string - description: "allocatedResourceStatuses stores status - of resource being resized for the given PVC. Key names - follow standard Kubernetes label syntax. Valid values - are either: * Un-prefixed keys: - storage - the capacity - of the volume. * Custom resources must use implementation-defined - prefixed names such as \"example.com/my-custom-resource\" - Apart from above values - keys that are unprefixed or - have kubernetes.io prefix are considered reserved and - hence may not be used. \n ClaimResourceStatus can be - in any of following states: - ControllerResizeInProgress: - State set when resize controller starts resizing the - volume in control-plane. - ControllerResizeFailed: State - set when resize has failed in resize controller with - a terminal error. - NodeResizePending: State set when - resize controller has finished resizing the volume but - further resizing of volume is needed on the node. - - NodeResizeInProgress: State set when kubelet starts - resizing the volume. - NodeResizeFailed: State set when - resizing has failed in kubelet with a terminal error. - Transient errors don't set NodeResizeFailed. For example: - if expanding a PVC for more capacity - this field can - be one of the following states: - pvc.status.allocatedResourceStatus['storage'] - = \"ControllerResizeInProgress\" - pvc.status.allocatedResourceStatus['storage'] - = \"ControllerResizeFailed\" - pvc.status.allocatedResourceStatus['storage'] - = \"NodeResizePending\" - pvc.status.allocatedResourceStatus['storage'] - = \"NodeResizeInProgress\" - pvc.status.allocatedResourceStatus['storage'] - = \"NodeResizeFailed\" When this field is not set, it - means that no resize operation is in progress for the - given PVC. \n A controller that receives PVC update - with previously unknown resourceName or ClaimResourceStatus - should ignore the update for the purpose it was designed. - For example - a controller that only is responsible - for resizing capacity of the volume, should ignore PVC - updates that change other valid resources associated - with PVC. \n This is an alpha field and requires enabling - RecoverVolumeExpansionFailure feature." - type: object - x-kubernetes-map-type: granular - allocatedResources: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: "allocatedResources tracks the resources - allocated to a PVC including its capacity. Key names - follow standard Kubernetes label syntax. Valid values - are either: * Un-prefixed keys: - storage - the capacity - of the volume. * Custom resources must use implementation-defined - prefixed names such as \"example.com/my-custom-resource\" - Apart from above values - keys that are unprefixed or - have kubernetes.io prefix are considered reserved and - hence may not be used. \n Capacity reported here may - be larger than the actual capacity when a volume expansion - operation is requested. For storage quota, the larger - value from allocatedResources and PVC.spec.resources - is used. If allocatedResources is not set, PVC.spec.resources - alone is used for quota calculation. If a volume expansion - capacity request is lowered, allocatedResources is only - lowered if there are no expansion operations in progress - and if the actual volume capacity is equal or lower - than the requested capacity. \n A controller that receives - PVC update with previously unknown resourceName should - ignore the update for the purpose it was designed. For - example - a controller that only is responsible for - resizing capacity of the volume, should ignore PVC updates - that change other valid resources associated with PVC. - \n This is an alpha field and requires enabling RecoverVolumeExpansionFailure - feature." - type: object - capacity: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: capacity represents the actual resources - of the underlying volume. - type: object - conditions: - description: conditions is the current Condition of persistent - volume claim. If underlying persistent volume is being - resized then the Condition will be set to 'ResizeStarted'. - items: - description: PersistentVolumeClaimCondition contains - details about state of pvc - properties: - lastProbeTime: - description: lastProbeTime is the time we probed - the condition. - format: date-time - type: string - lastTransitionTime: - description: lastTransitionTime is the time the - condition transitioned from one status to another. - format: date-time - type: string - message: - description: message is the human-readable message - indicating details about last transition. - type: string - reason: - description: reason is a unique, this should be - a short, machine understandable string that gives - the reason for condition's last transition. If - it reports "ResizeStarted" that means the underlying - persistent volume is being resized. - type: string - status: - type: string - type: - description: PersistentVolumeClaimConditionType - is a valid value of PersistentVolumeClaimCondition.Type - type: string - required: - - status - - type - type: object - type: array - phase: - description: phase represents the current phase of PersistentVolumeClaim. - type: string - type: object - type: object - type: object - tolerations: - description: Tolerations, if specified, controls the pod's tolerations. - items: - description: The pod this Toleration is attached to tolerates any - taint that matches the triple using the matching - operator . - properties: - effect: - description: Effect indicates the taint effect to match. Empty - means match all taint effects. When specified, allowed values - are NoSchedule, PreferNoSchedule and NoExecute. - type: string - key: - description: Key is the taint key that the toleration applies - to. Empty means match all taint keys. If the key is empty, - operator must be Exists; this combination means to match all - values and all keys. - type: string - operator: - description: Operator represents a key's relationship to the - value. Valid operators are Exists and Equal. Defaults to Equal. - Exists is equivalent to wildcard for value, so that a pod - can tolerate all taints of a particular category. - type: string - tolerationSeconds: - description: TolerationSeconds represents the period of time - the toleration (which must be of effect NoExecute, otherwise - this field is ignored) tolerates the taint. By default, it - is not set, which means tolerate the taint forever (do not - evict). Zero and negative values will be treated as 0 (evict - immediately) by the system. - format: int64 - type: integer - value: - description: Value is the taint value the toleration matches - to. If the operator is Exists, the value should be empty, - otherwise just a regular string. - type: string - type: object - type: array - topologySpreadConstraints: - description: TopologySpreadConstraints, if specified, controls the - pod's topology spread constraints. - items: - description: TopologySpreadConstraint specifies how to spread matching - pods among the given topology. - properties: - labelSelector: - description: LabelSelector is used to find matching pods. Pods - that match this label selector are counted to determine the - number of pods in their corresponding topology domain. - properties: - matchExpressions: - description: matchExpressions is a list of label selector - requirements. The requirements are ANDed. - items: - description: A label selector requirement is a selector - that contains values, a key, and an operator that relates - the key and values. - properties: - key: - description: key is the label key that the selector - applies to. - type: string - operator: - description: operator represents a key's relationship - to a set of values. Valid operators are In, NotIn, - Exists and DoesNotExist. - type: string - values: - description: values is an array of string values. - If the operator is In or NotIn, the values array - must be non-empty. If the operator is Exists or - DoesNotExist, the values array must be empty. This - array is replaced during a strategic merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. - A single {key,value} in the matchLabels map is equivalent - to an element of matchExpressions, whose key field is - "key", the operator is "In", and the values array contains - only "value". The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - matchLabelKeys: - description: "MatchLabelKeys is a set of pod label keys to select - the pods over which spreading will be calculated. The keys - are used to lookup values from the incoming pod labels, those - key-value labels are ANDed with labelSelector to select the - group of existing pods over which spreading will be calculated - for the incoming pod. The same key is forbidden to exist in - both MatchLabelKeys and LabelSelector. MatchLabelKeys cannot - be set when LabelSelector isn't set. Keys that don't exist - in the incoming pod labels will be ignored. A null or empty - list means only match against labelSelector. \n This is a - beta field and requires the MatchLabelKeysInPodTopologySpread - feature gate to be enabled (enabled by default)." - items: - type: string - type: array - x-kubernetes-list-type: atomic - maxSkew: - description: 'MaxSkew describes the degree to which pods may - be unevenly distributed. When `whenUnsatisfiable=DoNotSchedule`, - it is the maximum permitted difference between the number - of matching pods in the target topology and the global minimum. - The global minimum is the minimum number of matching pods - in an eligible domain or zero if the number of eligible domains - is less than MinDomains. For example, in a 3-zone cluster, - MaxSkew is set to 1, and pods with the same labelSelector - spread as 2/2/1: In this case, the global minimum is 1. | - zone1 | zone2 | zone3 | | P P | P P | P | - if MaxSkew - is 1, incoming pod can only be scheduled to zone3 to become - 2/2/2; scheduling it onto zone1(zone2) would make the ActualSkew(3-1) - on zone1(zone2) violate MaxSkew(1). - if MaxSkew is 2, incoming - pod can be scheduled onto any zone. When `whenUnsatisfiable=ScheduleAnyway`, - it is used to give higher precedence to topologies that satisfy - it. It''s a required field. Default value is 1 and 0 is not - allowed.' - format: int32 - type: integer - minDomains: - description: "MinDomains indicates a minimum number of eligible - domains. When the number of eligible domains with matching - topology keys is less than minDomains, Pod Topology Spread - treats \"global minimum\" as 0, and then the calculation of - Skew is performed. And when the number of eligible domains - with matching topology keys equals or greater than minDomains, - this value has no effect on scheduling. As a result, when - the number of eligible domains is less than minDomains, scheduler - won't schedule more than maxSkew Pods to those domains. If - value is nil, the constraint behaves as if MinDomains is equal - to 1. Valid values are integers greater than 0. When value - is not nil, WhenUnsatisfiable must be DoNotSchedule. \n For - example, in a 3-zone cluster, MaxSkew is set to 2, MinDomains - is set to 5 and pods with the same labelSelector spread as - 2/2/2: | zone1 | zone2 | zone3 | | P P | P P | P P | - The number of domains is less than 5(MinDomains), so \"global - minimum\" is treated as 0. In this situation, new pod with - the same labelSelector cannot be scheduled, because computed - skew will be 3(3 - 0) if new Pod is scheduled to any of the - three zones, it will violate MaxSkew. \n This is a beta field - and requires the MinDomainsInPodTopologySpread feature gate - to be enabled (enabled by default)." - format: int32 - type: integer - nodeAffinityPolicy: - description: "NodeAffinityPolicy indicates how we will treat - Pod's nodeAffinity/nodeSelector when calculating pod topology - spread skew. Options are: - Honor: only nodes matching nodeAffinity/nodeSelector - are included in the calculations. - Ignore: nodeAffinity/nodeSelector - are ignored. All nodes are included in the calculations. \n - If this value is nil, the behavior is equivalent to the Honor - policy. This is a beta-level feature default enabled by the - NodeInclusionPolicyInPodTopologySpread feature flag." - type: string - nodeTaintsPolicy: - description: "NodeTaintsPolicy indicates how we will treat node - taints when calculating pod topology spread skew. Options - are: - Honor: nodes without taints, along with tainted nodes - for which the incoming pod has a toleration, are included. - - Ignore: node taints are ignored. All nodes are included. - \n If this value is nil, the behavior is equivalent to the - Ignore policy. This is a beta-level feature default enabled - by the NodeInclusionPolicyInPodTopologySpread feature flag." - type: string - topologyKey: - description: TopologyKey is the key of node labels. Nodes that - have a label with this key and identical values are considered - to be in the same topology. We consider each - as a "bucket", and try to put balanced number of pods into - each bucket. We define a domain as a particular instance of - a topology. Also, we define an eligible domain as a domain - whose nodes meet the requirements of nodeAffinityPolicy and - nodeTaintsPolicy. e.g. If TopologyKey is "kubernetes.io/hostname", - each Node is a domain of that topology. And, if TopologyKey - is "topology.kubernetes.io/zone", each zone is a domain of - that topology. It's a required field. - type: string - whenUnsatisfiable: - description: 'WhenUnsatisfiable indicates how to deal with a - pod if it doesn''t satisfy the spread constraint. - DoNotSchedule - (default) tells the scheduler not to schedule it. - ScheduleAnyway - tells the scheduler to schedule the pod in any location, but - giving higher precedence to topologies that would help reduce - the skew. A constraint is considered "Unsatisfiable" for an - incoming pod if and only if every possible node assignment - for that pod would violate "MaxSkew" on some topology. For - example, in a 3-zone cluster, MaxSkew is set to 1, and pods - with the same labelSelector spread as 3/1/1: | zone1 | zone2 - | zone3 | | P P P | P | P | If WhenUnsatisfiable is - set to DoNotSchedule, incoming pod can only be scheduled to - zone2(zone3) to become 3/2/1(3/1/2) as ActualSkew(2-1) on - zone2(zone3) satisfies MaxSkew(1). In other words, the cluster - can still be imbalanced, but scheduler won''t make it *more* - imbalanced. It''s a required field.' - type: string - required: - - maxSkew - - topologyKey - - whenUnsatisfiable - type: object - type: array - version: - description: Version of Grafana Agent to be deployed. - type: string - volumeMounts: - description: VolumeMounts lets you configure additional VolumeMounts - on the output StatefulSet definition. Specified VolumeMounts are - appended to other VolumeMounts generated as a result of StorageSpec - objects in the Grafana Agent container. - items: - description: VolumeMount describes a mounting of a Volume within - a container. - properties: - mountPath: - description: Path within the container at which the volume should - be mounted. Must not contain ':'. - type: string - mountPropagation: - description: mountPropagation determines how mounts are propagated - from the host to container and the other way around. When - not set, MountPropagationNone is used. This field is beta - in 1.10. - type: string - name: - description: This must match the Name of a Volume. - type: string - readOnly: - description: Mounted read-only if true, read-write otherwise - (false or unspecified). Defaults to false. - type: boolean - subPath: - description: Path within the volume from which the container's - volume should be mounted. Defaults to "" (volume's root). - type: string - subPathExpr: - description: Expanded path within the volume from which the - container's volume should be mounted. Behaves similarly to - SubPath but environment variable references $(VAR_NAME) are - expanded using the container's environment. Defaults to "" - (volume's root). SubPathExpr and SubPath are mutually exclusive. - type: string - required: - - mountPath - - name - type: object - type: array - volumes: - description: Volumes allows configuration of additional volumes on - the output StatefulSet definition. The volumes specified are appended - to other volumes that are generated as a result of StorageSpec objects. - items: - description: Volume represents a named volume in a pod that may - be accessed by any container in the pod. - properties: - awsElasticBlockStore: - description: 'awsElasticBlockStore represents an AWS Disk resource - that is attached to a kubelet''s host machine and then exposed - to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' - properties: - fsType: - description: 'fsType is the filesystem type of the volume - that you want to mount. Tip: Ensure that the filesystem - type is supported by the host operating system. Examples: - "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" - if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore - TODO: how do we prevent errors in the filesystem from - compromising the machine' - type: string - partition: - description: 'partition is the partition in the volume that - you want to mount. If omitted, the default is to mount - by volume name. Examples: For volume /dev/sda1, you specify - the partition as "1". Similarly, the volume partition - for /dev/sda is "0" (or you can leave the property empty).' - format: int32 - type: integer - readOnly: - description: 'readOnly value true will force the readOnly - setting in VolumeMounts. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' - type: boolean - volumeID: - description: 'volumeID is unique ID of the persistent disk - resource in AWS (Amazon EBS volume). More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' - type: string - required: - - volumeID - type: object - azureDisk: - description: azureDisk represents an Azure Data Disk mount on - the host and bind mount to the pod. - properties: - cachingMode: - description: 'cachingMode is the Host Caching mode: None, - Read Only, Read Write.' - type: string - diskName: - description: diskName is the Name of the data disk in the - blob storage - type: string - diskURI: - description: diskURI is the URI of data disk in the blob - storage - type: string - fsType: - description: fsType is Filesystem type to mount. Must be - a filesystem type supported by the host operating system. - Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" - if unspecified. - type: string - kind: - description: 'kind expected values are Shared: multiple - blob disks per storage account Dedicated: single blob - disk per storage account Managed: azure managed data - disk (only in managed availability set). defaults to shared' - type: string - readOnly: - description: readOnly Defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. - type: boolean - required: - - diskName - - diskURI - type: object - azureFile: - description: azureFile represents an Azure File Service mount - on the host and bind mount to the pod. - properties: - readOnly: - description: readOnly defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. - type: boolean - secretName: - description: secretName is the name of secret that contains - Azure Storage Account Name and Key - type: string - shareName: - description: shareName is the azure share Name - type: string - required: - - secretName - - shareName - type: object - cephfs: - description: cephFS represents a Ceph FS mount on the host that - shares a pod's lifetime - properties: - monitors: - description: 'monitors is Required: Monitors is a collection - of Ceph monitors More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' - items: - type: string - type: array - path: - description: 'path is Optional: Used as the mounted root, - rather than the full Ceph tree, default is /' - type: string - readOnly: - description: 'readOnly is Optional: Defaults to false (read/write). - ReadOnly here will force the ReadOnly setting in VolumeMounts. - More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' - type: boolean - secretFile: - description: 'secretFile is Optional: SecretFile is the - path to key ring for User, default is /etc/ceph/user.secret - More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' - type: string - secretRef: - description: 'secretRef is Optional: SecretRef is reference - to the authentication secret for User, default is empty. - More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' - properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - type: object - x-kubernetes-map-type: atomic - user: - description: 'user is optional: User is the rados user name, - default is admin More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' - type: string - required: - - monitors - type: object - cinder: - description: 'cinder represents a cinder volume attached and - mounted on kubelets host machine. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' - properties: - fsType: - description: 'fsType is the filesystem type to mount. Must - be a filesystem type supported by the host operating system. - Examples: "ext4", "xfs", "ntfs". Implicitly inferred to - be "ext4" if unspecified. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' - type: string - readOnly: - description: 'readOnly defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. - More info: https://examples.k8s.io/mysql-cinder-pd/README.md' - type: boolean - secretRef: - description: 'secretRef is optional: points to a secret - object containing parameters used to connect to OpenStack.' - properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - type: object - x-kubernetes-map-type: atomic - volumeID: - description: 'volumeID used to identify the volume in cinder. - More info: https://examples.k8s.io/mysql-cinder-pd/README.md' - type: string - required: - - volumeID - type: object - configMap: - description: configMap represents a configMap that should populate - this volume - properties: - defaultMode: - description: 'defaultMode is optional: mode bits used to - set permissions on created files by default. Must be an - octal value between 0000 and 0777 or a decimal value between - 0 and 511. YAML accepts both octal and decimal values, - JSON requires decimal values for mode bits. Defaults to - 0644. Directories within the path are not affected by - this setting. This might be in conflict with other options - that affect the file mode, like fsGroup, and the result - can be other mode bits set.' - format: int32 - type: integer - items: - description: items if unspecified, each key-value pair in - the Data field of the referenced ConfigMap will be projected - into the volume as a file whose name is the key and content - is the value. If specified, the listed keys will be projected - into the specified paths, and unlisted keys will not be - present. If a key is specified which is not present in - the ConfigMap, the volume setup will error unless it is - marked optional. Paths must be relative and may not contain - the '..' path or start with '..'. - items: - description: Maps a string key to a path within a volume. - properties: - key: - description: key is the key to project. - type: string - mode: - description: 'mode is Optional: mode bits used to - set permissions on this file. Must be an octal value - between 0000 and 0777 or a decimal value between - 0 and 511. YAML accepts both octal and decimal values, - JSON requires decimal values for mode bits. If not - specified, the volume defaultMode will be used. - This might be in conflict with other options that - affect the file mode, like fsGroup, and the result - can be other mode bits set.' - format: int32 - type: integer - path: - description: path is the relative path of the file - to map the key to. May not be an absolute path. - May not contain the path element '..'. May not start - with the string '..'. - type: string - required: - - key - - path - type: object - type: array - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: optional specify whether the ConfigMap or its - keys must be defined - type: boolean - type: object - x-kubernetes-map-type: atomic - csi: - description: csi (Container Storage Interface) represents ephemeral - storage that is handled by certain external CSI drivers (Beta - feature). - properties: - driver: - description: driver is the name of the CSI driver that handles - this volume. Consult with your admin for the correct name - as registered in the cluster. - type: string - fsType: - description: fsType to mount. Ex. "ext4", "xfs", "ntfs". - If not provided, the empty value is passed to the associated - CSI driver which will determine the default filesystem - to apply. - type: string - nodePublishSecretRef: - description: nodePublishSecretRef is a reference to the - secret object containing sensitive information to pass - to the CSI driver to complete the CSI NodePublishVolume - and NodeUnpublishVolume calls. This field is optional, - and may be empty if no secret is required. If the secret - object contains more than one secret, all secret references - are passed. - properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - type: object - x-kubernetes-map-type: atomic - readOnly: - description: readOnly specifies a read-only configuration - for the volume. Defaults to false (read/write). - type: boolean - volumeAttributes: - additionalProperties: - type: string - description: volumeAttributes stores driver-specific properties - that are passed to the CSI driver. Consult your driver's - documentation for supported values. - type: object - required: - - driver - type: object - downwardAPI: - description: downwardAPI represents downward API about the pod - that should populate this volume - properties: - defaultMode: - description: 'Optional: mode bits to use on created files - by default. Must be a Optional: mode bits used to set - permissions on created files by default. Must be an octal - value between 0000 and 0777 or a decimal value between - 0 and 511. YAML accepts both octal and decimal values, - JSON requires decimal values for mode bits. Defaults to - 0644. Directories within the path are not affected by - this setting. This might be in conflict with other options - that affect the file mode, like fsGroup, and the result - can be other mode bits set.' - format: int32 - type: integer - items: - description: Items is a list of downward API volume file - items: - description: DownwardAPIVolumeFile represents information - to create the file containing the pod field - properties: - fieldRef: - description: 'Required: Selects a field of the pod: - only annotations, labels, name and namespace are - supported.' - properties: - apiVersion: - description: Version of the schema the FieldPath - is written in terms of, defaults to "v1". - type: string - fieldPath: - description: Path of the field to select in the - specified API version. - type: string - required: - - fieldPath - type: object - x-kubernetes-map-type: atomic - mode: - description: 'Optional: mode bits used to set permissions - on this file, must be an octal value between 0000 - and 0777 or a decimal value between 0 and 511. YAML - accepts both octal and decimal values, JSON requires - decimal values for mode bits. If not specified, - the volume defaultMode will be used. This might - be in conflict with other options that affect the - file mode, like fsGroup, and the result can be other - mode bits set.' - format: int32 - type: integer - path: - description: 'Required: Path is the relative path - name of the file to be created. Must not be absolute - or contain the ''..'' path. Must be utf-8 encoded. - The first item of the relative path must not start - with ''..''' - type: string - resourceFieldRef: - description: 'Selects a resource of the container: - only resources limits and requests (limits.cpu, - limits.memory, requests.cpu and requests.memory) - are currently supported.' - properties: - containerName: - description: 'Container name: required for volumes, - optional for env vars' - type: string - divisor: - anyOf: - - type: integer - - type: string - description: Specifies the output format of the - exposed resources, defaults to "1" - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - description: 'Required: resource to select' - type: string - required: - - resource - type: object - x-kubernetes-map-type: atomic - required: - - path - type: object - type: array - type: object - emptyDir: - description: 'emptyDir represents a temporary directory that - shares a pod''s lifetime. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' - properties: - medium: - description: 'medium represents what type of storage medium - should back this directory. The default is "" which means - to use the node''s default medium. Must be an empty string - (default) or Memory. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' - type: string - sizeLimit: - anyOf: - - type: integer - - type: string - description: 'sizeLimit is the total amount of local storage - required for this EmptyDir volume. The size limit is also - applicable for memory medium. The maximum usage on memory - medium EmptyDir would be the minimum value between the - SizeLimit specified here and the sum of memory limits - of all containers in a pod. The default is nil which means - that the limit is undefined. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - ephemeral: - description: "ephemeral represents a volume that is handled - by a cluster storage driver. The volume's lifecycle is tied - to the pod that defines it - it will be created before the - pod starts, and deleted when the pod is removed. \n Use this - if: a) the volume is only needed while the pod runs, b) features - of normal volumes like restoring from snapshot or capacity - tracking are needed, c) the storage driver is specified through - a storage class, and d) the storage driver supports dynamic - volume provisioning through a PersistentVolumeClaim (see EphemeralVolumeSource - for more information on the connection between this volume - type and PersistentVolumeClaim). \n Use PersistentVolumeClaim - or one of the vendor-specific APIs for volumes that persist - for longer than the lifecycle of an individual pod. \n Use - CSI for light-weight local ephemeral volumes if the CSI driver - is meant to be used that way - see the documentation of the - driver for more information. \n A pod can use both types of - ephemeral volumes and persistent volumes at the same time." - properties: - volumeClaimTemplate: - description: "Will be used to create a stand-alone PVC to - provision the volume. The pod in which this EphemeralVolumeSource - is embedded will be the owner of the PVC, i.e. the PVC - will be deleted together with the pod. The name of the - PVC will be `-` where `` is the name from the `PodSpec.Volumes` array entry. - Pod validation will reject the pod if the concatenated - name is not valid for a PVC (for example, too long). \n - An existing PVC with that name that is not owned by the - pod will *not* be used for the pod to avoid using an unrelated - volume by mistake. Starting the pod is then blocked until - the unrelated PVC is removed. If such a pre-created PVC - is meant to be used by the pod, the PVC has to updated - with an owner reference to the pod once the pod exists. - Normally this should not be necessary, but it may be useful - when manually reconstructing a broken cluster. \n This - field is read-only and no changes will be made by Kubernetes - to the PVC after it has been created. \n Required, must - not be nil." - properties: - metadata: - description: May contain labels and annotations that - will be copied into the PVC when creating it. No other - fields are allowed and will be rejected during validation. - type: object - spec: - description: The specification for the PersistentVolumeClaim. - The entire content is copied unchanged into the PVC - that gets created from this template. The same fields - as in a PersistentVolumeClaim are also valid here. - properties: - accessModes: - description: 'accessModes contains the desired access - modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' - items: - type: string - type: array - dataSource: - description: 'dataSource field can be used to specify - either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) - * An existing PVC (PersistentVolumeClaim) If the - provisioner or an external controller can support - the specified data source, it will create a new - volume based on the contents of the specified - data source. When the AnyVolumeDataSource feature - gate is enabled, dataSource contents will be copied - to dataSourceRef, and dataSourceRef contents will - be copied to dataSource when dataSourceRef.namespace - is not specified. If the namespace is specified, - then dataSourceRef will not be copied to dataSource.' - properties: - apiGroup: - description: APIGroup is the group for the resource - being referenced. If APIGroup is not specified, - the specified Kind must be in the core API - group. For any other third-party types, APIGroup - is required. - type: string - kind: - description: Kind is the type of resource being - referenced - type: string - name: - description: Name is the name of resource being - referenced - type: string - required: - - kind - - name - type: object - x-kubernetes-map-type: atomic - dataSourceRef: - description: 'dataSourceRef specifies the object - from which to populate the volume with data, if - a non-empty volume is desired. This may be any - object from a non-empty API group (non core object) - or a PersistentVolumeClaim object. When this field - is specified, volume binding will only succeed - if the type of the specified object matches some - installed volume populator or dynamic provisioner. - This field will replace the functionality of the - dataSource field and as such if both fields are - non-empty, they must have the same value. For - backwards compatibility, when namespace isn''t - specified in dataSourceRef, both fields (dataSource - and dataSourceRef) will be set to the same value - automatically if one of them is empty and the - other is non-empty. When namespace is specified - in dataSourceRef, dataSource isn''t set to the - same value and must be empty. There are three - important differences between dataSource and dataSourceRef: - * While dataSource only allows two specific types - of objects, dataSourceRef allows any non-core - object, as well as PersistentVolumeClaim objects. - * While dataSource ignores disallowed values (dropping - them), dataSourceRef preserves all values, and - generates an error if a disallowed value is specified. - * While dataSource only allows local objects, - dataSourceRef allows objects in any namespaces. - (Beta) Using this field requires the AnyVolumeDataSource - feature gate to be enabled. (Alpha) Using the - namespace field of dataSourceRef requires the - CrossNamespaceVolumeDataSource feature gate to - be enabled.' - properties: - apiGroup: - description: APIGroup is the group for the resource - being referenced. If APIGroup is not specified, - the specified Kind must be in the core API - group. For any other third-party types, APIGroup - is required. - type: string - kind: - description: Kind is the type of resource being - referenced - type: string - name: - description: Name is the name of resource being - referenced - type: string - namespace: - description: Namespace is the namespace of resource - being referenced Note that when a namespace - is specified, a gateway.networking.k8s.io/ReferenceGrant - object is required in the referent namespace - to allow that namespace's owner to accept - the reference. See the ReferenceGrant documentation - for details. (Alpha) This field requires the - CrossNamespaceVolumeDataSource feature gate - to be enabled. - type: string - required: - - kind - - name - type: object - resources: - description: 'resources represents the minimum resources - the volume should have. If RecoverVolumeExpansionFailure - feature is enabled users are allowed to specify - resource requirements that are lower than previous - value but must still be higher than capacity recorded - in the status field of the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' - properties: - claims: - description: "Claims lists the names of resources, - defined in spec.resourceClaims, that are used - by this container. \n This is an alpha field - and requires enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. - It can only be set for containers." - items: - description: ResourceClaim references one - entry in PodSpec.ResourceClaims. - properties: - name: - description: Name must match the name - of one entry in pod.spec.resourceClaims - of the Pod where this field is used. - It makes that resource available inside - a container. - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount - of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum - amount of compute resources required. If Requests - is omitted for a container, it defaults to - Limits if that is explicitly specified, otherwise - to an implementation-defined value. Requests - cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - type: object - selector: - description: selector is a label query over volumes - to consider for binding. - properties: - matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are - ANDed. - items: - description: A label selector requirement - is a selector that contains values, a key, - and an operator that relates the key and - values. - properties: - key: - description: key is the label key that - the selector applies to. - type: string - operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. - type: string - values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only "value". - The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - storageClassName: - description: 'storageClassName is the name of the - StorageClass required by the claim. More info: - https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' - type: string - volumeMode: - description: volumeMode defines what type of volume - is required by the claim. Value of Filesystem - is implied when not included in claim spec. - type: string - volumeName: - description: volumeName is the binding reference - to the PersistentVolume backing this claim. - type: string - type: object - required: - - spec - type: object - type: object - fc: - description: fc represents a Fibre Channel resource that is - attached to a kubelet's host machine and then exposed to the - pod. - properties: - fsType: - description: 'fsType is the filesystem type to mount. Must - be a filesystem type supported by the host operating system. - Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" - if unspecified. TODO: how do we prevent errors in the - filesystem from compromising the machine' - type: string - lun: - description: 'lun is Optional: FC target lun number' - format: int32 - type: integer - readOnly: - description: 'readOnly is Optional: Defaults to false (read/write). - ReadOnly here will force the ReadOnly setting in VolumeMounts.' - type: boolean - targetWWNs: - description: 'targetWWNs is Optional: FC target worldwide - names (WWNs)' - items: - type: string - type: array - wwids: - description: 'wwids Optional: FC volume world wide identifiers - (wwids) Either wwids or combination of targetWWNs and - lun must be set, but not both simultaneously.' - items: - type: string - type: array - type: object - flexVolume: - description: flexVolume represents a generic volume resource - that is provisioned/attached using an exec based plugin. - properties: - driver: - description: driver is the name of the driver to use for - this volume. - type: string - fsType: - description: fsType is the filesystem type to mount. Must - be a filesystem type supported by the host operating system. - Ex. "ext4", "xfs", "ntfs". The default filesystem depends - on FlexVolume script. - type: string - options: - additionalProperties: - type: string - description: 'options is Optional: this field holds extra - command options if any.' - type: object - readOnly: - description: 'readOnly is Optional: defaults to false (read/write). - ReadOnly here will force the ReadOnly setting in VolumeMounts.' - type: boolean - secretRef: - description: 'secretRef is Optional: secretRef is reference - to the secret object containing sensitive information - to pass to the plugin scripts. This may be empty if no - secret object is specified. If the secret object contains - more than one secret, all secrets are passed to the plugin - scripts.' - properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - type: object - x-kubernetes-map-type: atomic - required: - - driver - type: object - flocker: - description: flocker represents a Flocker volume attached to - a kubelet's host machine. This depends on the Flocker control - service being running - properties: - datasetName: - description: datasetName is Name of the dataset stored as - metadata -> name on the dataset for Flocker should be - considered as deprecated - type: string - datasetUUID: - description: datasetUUID is the UUID of the dataset. This - is unique identifier of a Flocker dataset - type: string - type: object - gcePersistentDisk: - description: 'gcePersistentDisk represents a GCE Disk resource - that is attached to a kubelet''s host machine and then exposed - to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' - properties: - fsType: - description: 'fsType is filesystem type of the volume that - you want to mount. Tip: Ensure that the filesystem type - is supported by the host operating system. Examples: "ext4", - "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. - More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk - TODO: how do we prevent errors in the filesystem from - compromising the machine' - type: string - partition: - description: 'partition is the partition in the volume that - you want to mount. If omitted, the default is to mount - by volume name. Examples: For volume /dev/sda1, you specify - the partition as "1". Similarly, the volume partition - for /dev/sda is "0" (or you can leave the property empty). - More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' - format: int32 - type: integer - pdName: - description: 'pdName is unique name of the PD resource in - GCE. Used to identify the disk in GCE. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' - type: string - readOnly: - description: 'readOnly here will force the ReadOnly setting - in VolumeMounts. Defaults to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' - type: boolean - required: - - pdName - type: object - gitRepo: - description: 'gitRepo represents a git repository at a particular - revision. DEPRECATED: GitRepo is deprecated. To provision - a container with a git repo, mount an EmptyDir into an InitContainer - that clones the repo using git, then mount the EmptyDir into - the Pod''s container.' - properties: - directory: - description: directory is the target directory name. Must - not contain or start with '..'. If '.' is supplied, the - volume directory will be the git repository. Otherwise, - if specified, the volume will contain the git repository - in the subdirectory with the given name. - type: string - repository: - description: repository is the URL - type: string - revision: - description: revision is the commit hash for the specified - revision. - type: string - required: - - repository - type: object - glusterfs: - description: 'glusterfs represents a Glusterfs mount on the - host that shares a pod''s lifetime. More info: https://examples.k8s.io/volumes/glusterfs/README.md' - properties: - endpoints: - description: 'endpoints is the endpoint name that details - Glusterfs topology. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' - type: string - path: - description: 'path is the Glusterfs volume path. More info: - https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' - type: string - readOnly: - description: 'readOnly here will force the Glusterfs volume - to be mounted with read-only permissions. Defaults to - false. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' - type: boolean - required: - - endpoints - - path - type: object - hostPath: - description: 'hostPath represents a pre-existing file or directory - on the host machine that is directly exposed to the container. - This is generally used for system agents or other privileged - things that are allowed to see the host machine. Most containers - will NOT need this. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath - --- TODO(jonesdl) We need to restrict who can use host directory - mounts and who can/can not mount host directories as read/write.' - properties: - path: - description: 'path of the directory on the host. If the - path is a symlink, it will follow the link to the real - path. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' - type: string - type: - description: 'type for HostPath Volume Defaults to "" More - info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' - type: string - required: - - path - type: object - iscsi: - description: 'iscsi represents an ISCSI Disk resource that is - attached to a kubelet''s host machine and then exposed to - the pod. More info: https://examples.k8s.io/volumes/iscsi/README.md' - properties: - chapAuthDiscovery: - description: chapAuthDiscovery defines whether support iSCSI - Discovery CHAP authentication - type: boolean - chapAuthSession: - description: chapAuthSession defines whether support iSCSI - Session CHAP authentication - type: boolean - fsType: - description: 'fsType is the filesystem type of the volume - that you want to mount. Tip: Ensure that the filesystem - type is supported by the host operating system. Examples: - "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" - if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi - TODO: how do we prevent errors in the filesystem from - compromising the machine' - type: string - initiatorName: - description: initiatorName is the custom iSCSI Initiator - Name. If initiatorName is specified with iscsiInterface - simultaneously, new iSCSI interface : will be created for the connection. - type: string - iqn: - description: iqn is the target iSCSI Qualified Name. - type: string - iscsiInterface: - description: iscsiInterface is the interface Name that uses - an iSCSI transport. Defaults to 'default' (tcp). - type: string - lun: - description: lun represents iSCSI Target Lun number. - format: int32 - type: integer - portals: - description: portals is the iSCSI Target Portal List. The - portal is either an IP or ip_addr:port if the port is - other than default (typically TCP ports 860 and 3260). - items: - type: string - type: array - readOnly: - description: readOnly here will force the ReadOnly setting - in VolumeMounts. Defaults to false. - type: boolean - secretRef: - description: secretRef is the CHAP Secret for iSCSI target - and initiator authentication - properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - type: object - x-kubernetes-map-type: atomic - targetPortal: - description: targetPortal is iSCSI Target Portal. The Portal - is either an IP or ip_addr:port if the port is other than - default (typically TCP ports 860 and 3260). - type: string - required: - - iqn - - lun - - targetPortal - type: object - name: - description: 'name of the volume. Must be a DNS_LABEL and unique - within the pod. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' - type: string - nfs: - description: 'nfs represents an NFS mount on the host that shares - a pod''s lifetime More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' - properties: - path: - description: 'path that is exported by the NFS server. More - info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' - type: string - readOnly: - description: 'readOnly here will force the NFS export to - be mounted with read-only permissions. Defaults to false. - More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' - type: boolean - server: - description: 'server is the hostname or IP address of the - NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' - type: string - required: - - path - - server - type: object - persistentVolumeClaim: - description: 'persistentVolumeClaimVolumeSource represents a - reference to a PersistentVolumeClaim in the same namespace. - More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' - properties: - claimName: - description: 'claimName is the name of a PersistentVolumeClaim - in the same namespace as the pod using this volume. More - info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' - type: string - readOnly: - description: readOnly Will force the ReadOnly setting in - VolumeMounts. Default false. - type: boolean - required: - - claimName - type: object - photonPersistentDisk: - description: photonPersistentDisk represents a PhotonController - persistent disk attached and mounted on kubelets host machine - properties: - fsType: - description: fsType is the filesystem type to mount. Must - be a filesystem type supported by the host operating system. - Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" - if unspecified. - type: string - pdID: - description: pdID is the ID that identifies Photon Controller - persistent disk - type: string - required: - - pdID - type: object - portworxVolume: - description: portworxVolume represents a portworx volume attached - and mounted on kubelets host machine - properties: - fsType: - description: fSType represents the filesystem type to mount - Must be a filesystem type supported by the host operating - system. Ex. "ext4", "xfs". Implicitly inferred to be "ext4" - if unspecified. - type: string - readOnly: - description: readOnly defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. - type: boolean - volumeID: - description: volumeID uniquely identifies a Portworx volume - type: string - required: - - volumeID - type: object - projected: - description: projected items for all in one resources secrets, - configmaps, and downward API - properties: - defaultMode: - description: defaultMode are the mode bits used to set permissions - on created files by default. Must be an octal value between - 0000 and 0777 or a decimal value between 0 and 511. YAML - accepts both octal and decimal values, JSON requires decimal - values for mode bits. Directories within the path are - not affected by this setting. This might be in conflict - with other options that affect the file mode, like fsGroup, - and the result can be other mode bits set. - format: int32 - type: integer - sources: - description: sources is the list of volume projections - items: - description: Projection that may be projected along with - other supported volume types - properties: - configMap: - description: configMap information about the configMap - data to project - properties: - items: - description: items if unspecified, each key-value - pair in the Data field of the referenced ConfigMap - will be projected into the volume as a file - whose name is the key and content is the value. - If specified, the listed keys will be projected - into the specified paths, and unlisted keys - will not be present. If a key is specified which - is not present in the ConfigMap, the volume - setup will error unless it is marked optional. - Paths must be relative and may not contain the - '..' path or start with '..'. - items: - description: Maps a string key to a path within - a volume. - properties: - key: - description: key is the key to project. - type: string - mode: - description: 'mode is Optional: mode bits - used to set permissions on this file. - Must be an octal value between 0000 and - 0777 or a decimal value between 0 and - 511. YAML accepts both octal and decimal - values, JSON requires decimal values for - mode bits. If not specified, the volume - defaultMode will be used. This might be - in conflict with other options that affect - the file mode, like fsGroup, and the result - can be other mode bits set.' - format: int32 - type: integer - path: - description: path is the relative path of - the file to map the key to. May not be - an absolute path. May not contain the - path element '..'. May not start with - the string '..'. - type: string - required: - - key - - path - type: object - type: array - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: optional specify whether the ConfigMap - or its keys must be defined - type: boolean - type: object - x-kubernetes-map-type: atomic - downwardAPI: - description: downwardAPI information about the downwardAPI - data to project - properties: - items: - description: Items is a list of DownwardAPIVolume - file - items: - description: DownwardAPIVolumeFile represents - information to create the file containing - the pod field - properties: - fieldRef: - description: 'Required: Selects a field - of the pod: only annotations, labels, - name and namespace are supported.' - properties: - apiVersion: - description: Version of the schema the - FieldPath is written in terms of, - defaults to "v1". - type: string - fieldPath: - description: Path of the field to select - in the specified API version. - type: string - required: - - fieldPath - type: object - x-kubernetes-map-type: atomic - mode: - description: 'Optional: mode bits used to - set permissions on this file, must be - an octal value between 0000 and 0777 or - a decimal value between 0 and 511. YAML - accepts both octal and decimal values, - JSON requires decimal values for mode - bits. If not specified, the volume defaultMode - will be used. This might be in conflict - with other options that affect the file - mode, like fsGroup, and the result can - be other mode bits set.' - format: int32 - type: integer - path: - description: 'Required: Path is the relative - path name of the file to be created. Must - not be absolute or contain the ''..'' - path. Must be utf-8 encoded. The first - item of the relative path must not start - with ''..''' - type: string - resourceFieldRef: - description: 'Selects a resource of the - container: only resources limits and requests - (limits.cpu, limits.memory, requests.cpu - and requests.memory) are currently supported.' - properties: - containerName: - description: 'Container name: required - for volumes, optional for env vars' - type: string - divisor: - anyOf: - - type: integer - - type: string - description: Specifies the output format - of the exposed resources, defaults - to "1" - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - description: 'Required: resource to - select' - type: string - required: - - resource - type: object - x-kubernetes-map-type: atomic - required: - - path - type: object - type: array - type: object - secret: - description: secret information about the secret data - to project - properties: - items: - description: items if unspecified, each key-value - pair in the Data field of the referenced Secret - will be projected into the volume as a file - whose name is the key and content is the value. - If specified, the listed keys will be projected - into the specified paths, and unlisted keys - will not be present. If a key is specified which - is not present in the Secret, the volume setup - will error unless it is marked optional. Paths - must be relative and may not contain the '..' - path or start with '..'. - items: - description: Maps a string key to a path within - a volume. - properties: - key: - description: key is the key to project. - type: string - mode: - description: 'mode is Optional: mode bits - used to set permissions on this file. - Must be an octal value between 0000 and - 0777 or a decimal value between 0 and - 511. YAML accepts both octal and decimal - values, JSON requires decimal values for - mode bits. If not specified, the volume - defaultMode will be used. This might be - in conflict with other options that affect - the file mode, like fsGroup, and the result - can be other mode bits set.' - format: int32 - type: integer - path: - description: path is the relative path of - the file to map the key to. May not be - an absolute path. May not contain the - path element '..'. May not start with - the string '..'. - type: string - required: - - key - - path - type: object - type: array - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: optional field specify whether the - Secret or its key must be defined - type: boolean - type: object - x-kubernetes-map-type: atomic - serviceAccountToken: - description: serviceAccountToken is information about - the serviceAccountToken data to project - properties: - audience: - description: audience is the intended audience - of the token. A recipient of a token must identify - itself with an identifier specified in the audience - of the token, and otherwise should reject the - token. The audience defaults to the identifier - of the apiserver. - type: string - expirationSeconds: - description: expirationSeconds is the requested - duration of validity of the service account - token. As the token approaches expiration, the - kubelet volume plugin will proactively rotate - the service account token. The kubelet will - start trying to rotate the token if the token - is older than 80 percent of its time to live - or if the token is older than 24 hours.Defaults - to 1 hour and must be at least 10 minutes. - format: int64 - type: integer - path: - description: path is the path relative to the - mount point of the file to project the token - into. - type: string - required: - - path - type: object - type: object - type: array - type: object - quobyte: - description: quobyte represents a Quobyte mount on the host - that shares a pod's lifetime - properties: - group: - description: group to map volume access to Default is no - group - type: string - readOnly: - description: readOnly here will force the Quobyte volume - to be mounted with read-only permissions. Defaults to - false. - type: boolean - registry: - description: registry represents a single or multiple Quobyte - Registry services specified as a string as host:port pair - (multiple entries are separated with commas) which acts - as the central registry for volumes - type: string - tenant: - description: tenant owning the given Quobyte volume in the - Backend Used with dynamically provisioned Quobyte volumes, - value is set by the plugin - type: string - user: - description: user to map volume access to Defaults to serivceaccount - user - type: string - volume: - description: volume is a string that references an already - created Quobyte volume by name. - type: string - required: - - registry - - volume - type: object - rbd: - description: 'rbd represents a Rados Block Device mount on the - host that shares a pod''s lifetime. More info: https://examples.k8s.io/volumes/rbd/README.md' - properties: - fsType: - description: 'fsType is the filesystem type of the volume - that you want to mount. Tip: Ensure that the filesystem - type is supported by the host operating system. Examples: - "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" - if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd - TODO: how do we prevent errors in the filesystem from - compromising the machine' - type: string - image: - description: 'image is the rados image name. More info: - https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' - type: string - keyring: - description: 'keyring is the path to key ring for RBDUser. - Default is /etc/ceph/keyring. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' - type: string - monitors: - description: 'monitors is a collection of Ceph monitors. - More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' - items: - type: string - type: array - pool: - description: 'pool is the rados pool name. Default is rbd. - More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' - type: string - readOnly: - description: 'readOnly here will force the ReadOnly setting - in VolumeMounts. Defaults to false. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' - type: boolean - secretRef: - description: 'secretRef is name of the authentication secret - for RBDUser. If provided overrides keyring. Default is - nil. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' - properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - type: object - x-kubernetes-map-type: atomic - user: - description: 'user is the rados user name. Default is admin. - More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' - type: string - required: - - image - - monitors - type: object - scaleIO: - description: scaleIO represents a ScaleIO persistent volume - attached and mounted on Kubernetes nodes. - properties: - fsType: - description: fsType is the filesystem type to mount. Must - be a filesystem type supported by the host operating system. - Ex. "ext4", "xfs", "ntfs". Default is "xfs". - type: string - gateway: - description: gateway is the host address of the ScaleIO - API Gateway. - type: string - protectionDomain: - description: protectionDomain is the name of the ScaleIO - Protection Domain for the configured storage. - type: string - readOnly: - description: readOnly Defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. - type: boolean - secretRef: - description: secretRef references to the secret for ScaleIO - user and other sensitive information. If this is not provided, - Login operation will fail. - properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - type: object - x-kubernetes-map-type: atomic - sslEnabled: - description: sslEnabled Flag enable/disable SSL communication - with Gateway, default false - type: boolean - storageMode: - description: storageMode indicates whether the storage for - a volume should be ThickProvisioned or ThinProvisioned. - Default is ThinProvisioned. - type: string - storagePool: - description: storagePool is the ScaleIO Storage Pool associated - with the protection domain. - type: string - system: - description: system is the name of the storage system as - configured in ScaleIO. - type: string - volumeName: - description: volumeName is the name of a volume already - created in the ScaleIO system that is associated with - this volume source. - type: string - required: - - gateway - - secretRef - - system - type: object - secret: - description: 'secret represents a secret that should populate - this volume. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' - properties: - defaultMode: - description: 'defaultMode is Optional: mode bits used to - set permissions on created files by default. Must be an - octal value between 0000 and 0777 or a decimal value between - 0 and 511. YAML accepts both octal and decimal values, - JSON requires decimal values for mode bits. Defaults to - 0644. Directories within the path are not affected by - this setting. This might be in conflict with other options - that affect the file mode, like fsGroup, and the result - can be other mode bits set.' - format: int32 - type: integer - items: - description: items If unspecified, each key-value pair in - the Data field of the referenced Secret will be projected - into the volume as a file whose name is the key and content - is the value. If specified, the listed keys will be projected - into the specified paths, and unlisted keys will not be - present. If a key is specified which is not present in - the Secret, the volume setup will error unless it is marked - optional. Paths must be relative and may not contain the - '..' path or start with '..'. - items: - description: Maps a string key to a path within a volume. - properties: - key: - description: key is the key to project. - type: string - mode: - description: 'mode is Optional: mode bits used to - set permissions on this file. Must be an octal value - between 0000 and 0777 or a decimal value between - 0 and 511. YAML accepts both octal and decimal values, - JSON requires decimal values for mode bits. If not - specified, the volume defaultMode will be used. - This might be in conflict with other options that - affect the file mode, like fsGroup, and the result - can be other mode bits set.' - format: int32 - type: integer - path: - description: path is the relative path of the file - to map the key to. May not be an absolute path. - May not contain the path element '..'. May not start - with the string '..'. - type: string - required: - - key - - path - type: object - type: array - optional: - description: optional field specify whether the Secret or - its keys must be defined - type: boolean - secretName: - description: 'secretName is the name of the secret in the - pod''s namespace to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' - type: string - type: object - storageos: - description: storageOS represents a StorageOS volume attached - and mounted on Kubernetes nodes. - properties: - fsType: - description: fsType is the filesystem type to mount. Must - be a filesystem type supported by the host operating system. - Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" - if unspecified. - type: string - readOnly: - description: readOnly defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. - type: boolean - secretRef: - description: secretRef specifies the secret to use for obtaining - the StorageOS API credentials. If not specified, default - values will be attempted. - properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - type: object - x-kubernetes-map-type: atomic - volumeName: - description: volumeName is the human-readable name of the - StorageOS volume. Volume names are only unique within - a namespace. - type: string - volumeNamespace: - description: volumeNamespace specifies the scope of the - volume within StorageOS. If no namespace is specified - then the Pod's namespace will be used. This allows the - Kubernetes name scoping to be mirrored within StorageOS - for tighter integration. Set VolumeName to any name to - override the default behaviour. Set to "default" if you - are not using namespaces within StorageOS. Namespaces - that do not pre-exist within StorageOS will be created. - type: string - type: object - vsphereVolume: - description: vsphereVolume represents a vSphere volume attached - and mounted on kubelets host machine - properties: - fsType: - description: fsType is filesystem type to mount. Must be - a filesystem type supported by the host operating system. - Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" - if unspecified. - type: string - storagePolicyID: - description: storagePolicyID is the storage Policy Based - Management (SPBM) profile ID associated with the StoragePolicyName. - type: string - storagePolicyName: - description: storagePolicyName is the storage Policy Based - Management (SPBM) profile name. - type: string - volumePath: - description: volumePath is the path that identifies vSphere - volume vmdk - type: string - required: - - volumePath - type: object - required: - - name - type: object - type: array - type: object - type: object - served: true - storage: true diff --git a/production/operator/crds/monitoring.grafana.com_integrations.yaml b/production/operator/crds/monitoring.grafana.com_integrations.yaml deleted file mode 100644 index e786166447fd..000000000000 --- a/production/operator/crds/monitoring.grafana.com_integrations.yaml +++ /dev/null @@ -1,1738 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.9.2 - creationTimestamp: null - name: integrations.monitoring.grafana.com -spec: - group: monitoring.grafana.com - names: - categories: - - agent-operator - kind: Integration - listKind: IntegrationList - plural: integrations - singular: integration - scope: Namespaced - versions: - - name: v1alpha1 - schema: - openAPIV3Schema: - description: "Integration runs a single Grafana Agent integration. Integrations - that generate telemetry must be configured to send that telemetry somewhere, - such as autoscrape for exporter-based integrations. \n Integrations have - access to the LogsInstances and MetricsInstances in the same GrafanaAgent - resource set, referenced by the / of the Instance resource. - \n For example, if there is a default/production MetricsInstance, you can - configure a supported integration's autoscrape block with: \n autoscrape: - enable: true metrics_instance: default/production \n There is currently - no way for telemetry created by an Operator-managed integration to be collected - from outside of the integration itself." - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: Specifies the desired behavior of the Integration. - properties: - config: - description: "The configuration for the named integration. Note that - Integrations are deployed with the integrations-next feature flag, - which has different common settings: \n https://grafana.com/docs/agent/latest/configuration/integrations/integrations-next/" - type: object - x-kubernetes-preserve-unknown-fields: true - configMaps: - description: "An extra list of keys from ConfigMaps in the same namespace - as the Integration which will be mounted into the Grafana Agent - pod running this Integration. \n ConfigMaps are mounted at /etc/grafana-agent/integrations/configMaps///." - items: - description: Selects a key from a ConfigMap. - properties: - key: - description: The key to select. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the ConfigMap or its key must be - defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: array - name: - description: Name of the integration to run (e.g., "node_exporter", - "mysqld_exporter"). - type: string - secrets: - description: "An extra list of keys from Secrets in the same namespace - as the Integration which will be mounted into the Grafana Agent - pod running this Integration. \n Secrets will be mounted at /etc/grafana-agent/integrations/secrets///." - items: - description: SecretKeySelector selects a key of a Secret. - properties: - key: - description: The key of the secret to select from. Must be - a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: array - type: - description: Type informs Grafana Agent Operator about how to manage - the integration being configured. - properties: - allNodes: - description: When true, the configured integration should be run - on every Node in the cluster. This is required for Integrations - that generate Node-specific metrics like node_exporter, otherwise - it must be false to avoid generating duplicate metrics. - type: boolean - unique: - description: Whether this integration can only be defined once - for a Grafana Agent process, such as statsd_exporter. It is - invalid for a GrafanaAgent to discover multiple unique Integrations - with the same Integration name (i.e., a single GrafanaAgent - cannot deploy two statsd_exporters). - type: boolean - type: object - volumeMounts: - description: "An extra list of VolumeMounts to be associated with - the Grafana Agent pods running this integration. VolumeMount names - are mutated to be unique across all used IntegrationSpecs. \n Mount - paths should include the namespace/name of the Integration CR to - avoid potentially colliding with other resources." - items: - description: VolumeMount describes a mounting of a Volume within - a container. - properties: - mountPath: - description: Path within the container at which the volume should - be mounted. Must not contain ':'. - type: string - mountPropagation: - description: mountPropagation determines how mounts are propagated - from the host to container and the other way around. When - not set, MountPropagationNone is used. This field is beta - in 1.10. - type: string - name: - description: This must match the Name of a Volume. - type: string - readOnly: - description: Mounted read-only if true, read-write otherwise - (false or unspecified). Defaults to false. - type: boolean - subPath: - description: Path within the volume from which the container's - volume should be mounted. Defaults to "" (volume's root). - type: string - subPathExpr: - description: Expanded path within the volume from which the - container's volume should be mounted. Behaves similarly to - SubPath but environment variable references $(VAR_NAME) are - expanded using the container's environment. Defaults to "" - (volume's root). SubPathExpr and SubPath are mutually exclusive. - type: string - required: - - mountPath - - name - type: object - type: array - volumes: - description: "An extra list of Volumes to be associated with the Grafana - Agent pods running this integration. Volume names are mutated to - be unique across all Integrations. Note that the specified volumes - should be able to tolerate existing on multiple pods at once when - type is daemonset. \n Don't use volumes for loading Secrets or ConfigMaps - from the same namespace as the Integration; use the Secrets and - ConfigMaps fields instead." - items: - description: Volume represents a named volume in a pod that may - be accessed by any container in the pod. - properties: - awsElasticBlockStore: - description: 'awsElasticBlockStore represents an AWS Disk resource - that is attached to a kubelet''s host machine and then exposed - to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' - properties: - fsType: - description: 'fsType is the filesystem type of the volume - that you want to mount. Tip: Ensure that the filesystem - type is supported by the host operating system. Examples: - "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" - if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore - TODO: how do we prevent errors in the filesystem from - compromising the machine' - type: string - partition: - description: 'partition is the partition in the volume that - you want to mount. If omitted, the default is to mount - by volume name. Examples: For volume /dev/sda1, you specify - the partition as "1". Similarly, the volume partition - for /dev/sda is "0" (or you can leave the property empty).' - format: int32 - type: integer - readOnly: - description: 'readOnly value true will force the readOnly - setting in VolumeMounts. More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' - type: boolean - volumeID: - description: 'volumeID is unique ID of the persistent disk - resource in AWS (Amazon EBS volume). More info: https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore' - type: string - required: - - volumeID - type: object - azureDisk: - description: azureDisk represents an Azure Data Disk mount on - the host and bind mount to the pod. - properties: - cachingMode: - description: 'cachingMode is the Host Caching mode: None, - Read Only, Read Write.' - type: string - diskName: - description: diskName is the Name of the data disk in the - blob storage - type: string - diskURI: - description: diskURI is the URI of data disk in the blob - storage - type: string - fsType: - description: fsType is Filesystem type to mount. Must be - a filesystem type supported by the host operating system. - Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" - if unspecified. - type: string - kind: - description: 'kind expected values are Shared: multiple - blob disks per storage account Dedicated: single blob - disk per storage account Managed: azure managed data - disk (only in managed availability set). defaults to shared' - type: string - readOnly: - description: readOnly Defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. - type: boolean - required: - - diskName - - diskURI - type: object - azureFile: - description: azureFile represents an Azure File Service mount - on the host and bind mount to the pod. - properties: - readOnly: - description: readOnly defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. - type: boolean - secretName: - description: secretName is the name of secret that contains - Azure Storage Account Name and Key - type: string - shareName: - description: shareName is the azure share Name - type: string - required: - - secretName - - shareName - type: object - cephfs: - description: cephFS represents a Ceph FS mount on the host that - shares a pod's lifetime - properties: - monitors: - description: 'monitors is Required: Monitors is a collection - of Ceph monitors More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' - items: - type: string - type: array - path: - description: 'path is Optional: Used as the mounted root, - rather than the full Ceph tree, default is /' - type: string - readOnly: - description: 'readOnly is Optional: Defaults to false (read/write). - ReadOnly here will force the ReadOnly setting in VolumeMounts. - More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' - type: boolean - secretFile: - description: 'secretFile is Optional: SecretFile is the - path to key ring for User, default is /etc/ceph/user.secret - More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' - type: string - secretRef: - description: 'secretRef is Optional: SecretRef is reference - to the authentication secret for User, default is empty. - More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' - properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - type: object - x-kubernetes-map-type: atomic - user: - description: 'user is optional: User is the rados user name, - default is admin More info: https://examples.k8s.io/volumes/cephfs/README.md#how-to-use-it' - type: string - required: - - monitors - type: object - cinder: - description: 'cinder represents a cinder volume attached and - mounted on kubelets host machine. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' - properties: - fsType: - description: 'fsType is the filesystem type to mount. Must - be a filesystem type supported by the host operating system. - Examples: "ext4", "xfs", "ntfs". Implicitly inferred to - be "ext4" if unspecified. More info: https://examples.k8s.io/mysql-cinder-pd/README.md' - type: string - readOnly: - description: 'readOnly defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. - More info: https://examples.k8s.io/mysql-cinder-pd/README.md' - type: boolean - secretRef: - description: 'secretRef is optional: points to a secret - object containing parameters used to connect to OpenStack.' - properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - type: object - x-kubernetes-map-type: atomic - volumeID: - description: 'volumeID used to identify the volume in cinder. - More info: https://examples.k8s.io/mysql-cinder-pd/README.md' - type: string - required: - - volumeID - type: object - configMap: - description: configMap represents a configMap that should populate - this volume - properties: - defaultMode: - description: 'defaultMode is optional: mode bits used to - set permissions on created files by default. Must be an - octal value between 0000 and 0777 or a decimal value between - 0 and 511. YAML accepts both octal and decimal values, - JSON requires decimal values for mode bits. Defaults to - 0644. Directories within the path are not affected by - this setting. This might be in conflict with other options - that affect the file mode, like fsGroup, and the result - can be other mode bits set.' - format: int32 - type: integer - items: - description: items if unspecified, each key-value pair in - the Data field of the referenced ConfigMap will be projected - into the volume as a file whose name is the key and content - is the value. If specified, the listed keys will be projected - into the specified paths, and unlisted keys will not be - present. If a key is specified which is not present in - the ConfigMap, the volume setup will error unless it is - marked optional. Paths must be relative and may not contain - the '..' path or start with '..'. - items: - description: Maps a string key to a path within a volume. - properties: - key: - description: key is the key to project. - type: string - mode: - description: 'mode is Optional: mode bits used to - set permissions on this file. Must be an octal value - between 0000 and 0777 or a decimal value between - 0 and 511. YAML accepts both octal and decimal values, - JSON requires decimal values for mode bits. If not - specified, the volume defaultMode will be used. - This might be in conflict with other options that - affect the file mode, like fsGroup, and the result - can be other mode bits set.' - format: int32 - type: integer - path: - description: path is the relative path of the file - to map the key to. May not be an absolute path. - May not contain the path element '..'. May not start - with the string '..'. - type: string - required: - - key - - path - type: object - type: array - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: optional specify whether the ConfigMap or its - keys must be defined - type: boolean - type: object - x-kubernetes-map-type: atomic - csi: - description: csi (Container Storage Interface) represents ephemeral - storage that is handled by certain external CSI drivers (Beta - feature). - properties: - driver: - description: driver is the name of the CSI driver that handles - this volume. Consult with your admin for the correct name - as registered in the cluster. - type: string - fsType: - description: fsType to mount. Ex. "ext4", "xfs", "ntfs". - If not provided, the empty value is passed to the associated - CSI driver which will determine the default filesystem - to apply. - type: string - nodePublishSecretRef: - description: nodePublishSecretRef is a reference to the - secret object containing sensitive information to pass - to the CSI driver to complete the CSI NodePublishVolume - and NodeUnpublishVolume calls. This field is optional, - and may be empty if no secret is required. If the secret - object contains more than one secret, all secret references - are passed. - properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - type: object - x-kubernetes-map-type: atomic - readOnly: - description: readOnly specifies a read-only configuration - for the volume. Defaults to false (read/write). - type: boolean - volumeAttributes: - additionalProperties: - type: string - description: volumeAttributes stores driver-specific properties - that are passed to the CSI driver. Consult your driver's - documentation for supported values. - type: object - required: - - driver - type: object - downwardAPI: - description: downwardAPI represents downward API about the pod - that should populate this volume - properties: - defaultMode: - description: 'Optional: mode bits to use on created files - by default. Must be a Optional: mode bits used to set - permissions on created files by default. Must be an octal - value between 0000 and 0777 or a decimal value between - 0 and 511. YAML accepts both octal and decimal values, - JSON requires decimal values for mode bits. Defaults to - 0644. Directories within the path are not affected by - this setting. This might be in conflict with other options - that affect the file mode, like fsGroup, and the result - can be other mode bits set.' - format: int32 - type: integer - items: - description: Items is a list of downward API volume file - items: - description: DownwardAPIVolumeFile represents information - to create the file containing the pod field - properties: - fieldRef: - description: 'Required: Selects a field of the pod: - only annotations, labels, name and namespace are - supported.' - properties: - apiVersion: - description: Version of the schema the FieldPath - is written in terms of, defaults to "v1". - type: string - fieldPath: - description: Path of the field to select in the - specified API version. - type: string - required: - - fieldPath - type: object - x-kubernetes-map-type: atomic - mode: - description: 'Optional: mode bits used to set permissions - on this file, must be an octal value between 0000 - and 0777 or a decimal value between 0 and 511. YAML - accepts both octal and decimal values, JSON requires - decimal values for mode bits. If not specified, - the volume defaultMode will be used. This might - be in conflict with other options that affect the - file mode, like fsGroup, and the result can be other - mode bits set.' - format: int32 - type: integer - path: - description: 'Required: Path is the relative path - name of the file to be created. Must not be absolute - or contain the ''..'' path. Must be utf-8 encoded. - The first item of the relative path must not start - with ''..''' - type: string - resourceFieldRef: - description: 'Selects a resource of the container: - only resources limits and requests (limits.cpu, - limits.memory, requests.cpu and requests.memory) - are currently supported.' - properties: - containerName: - description: 'Container name: required for volumes, - optional for env vars' - type: string - divisor: - anyOf: - - type: integer - - type: string - description: Specifies the output format of the - exposed resources, defaults to "1" - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - description: 'Required: resource to select' - type: string - required: - - resource - type: object - x-kubernetes-map-type: atomic - required: - - path - type: object - type: array - type: object - emptyDir: - description: 'emptyDir represents a temporary directory that - shares a pod''s lifetime. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' - properties: - medium: - description: 'medium represents what type of storage medium - should back this directory. The default is "" which means - to use the node''s default medium. Must be an empty string - (default) or Memory. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' - type: string - sizeLimit: - anyOf: - - type: integer - - type: string - description: 'sizeLimit is the total amount of local storage - required for this EmptyDir volume. The size limit is also - applicable for memory medium. The maximum usage on memory - medium EmptyDir would be the minimum value between the - SizeLimit specified here and the sum of memory limits - of all containers in a pod. The default is nil which means - that the limit is undefined. More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir' - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - ephemeral: - description: "ephemeral represents a volume that is handled - by a cluster storage driver. The volume's lifecycle is tied - to the pod that defines it - it will be created before the - pod starts, and deleted when the pod is removed. \n Use this - if: a) the volume is only needed while the pod runs, b) features - of normal volumes like restoring from snapshot or capacity - tracking are needed, c) the storage driver is specified through - a storage class, and d) the storage driver supports dynamic - volume provisioning through a PersistentVolumeClaim (see EphemeralVolumeSource - for more information on the connection between this volume - type and PersistentVolumeClaim). \n Use PersistentVolumeClaim - or one of the vendor-specific APIs for volumes that persist - for longer than the lifecycle of an individual pod. \n Use - CSI for light-weight local ephemeral volumes if the CSI driver - is meant to be used that way - see the documentation of the - driver for more information. \n A pod can use both types of - ephemeral volumes and persistent volumes at the same time." - properties: - volumeClaimTemplate: - description: "Will be used to create a stand-alone PVC to - provision the volume. The pod in which this EphemeralVolumeSource - is embedded will be the owner of the PVC, i.e. the PVC - will be deleted together with the pod. The name of the - PVC will be `-` where `` is the name from the `PodSpec.Volumes` array entry. - Pod validation will reject the pod if the concatenated - name is not valid for a PVC (for example, too long). \n - An existing PVC with that name that is not owned by the - pod will *not* be used for the pod to avoid using an unrelated - volume by mistake. Starting the pod is then blocked until - the unrelated PVC is removed. If such a pre-created PVC - is meant to be used by the pod, the PVC has to updated - with an owner reference to the pod once the pod exists. - Normally this should not be necessary, but it may be useful - when manually reconstructing a broken cluster. \n This - field is read-only and no changes will be made by Kubernetes - to the PVC after it has been created. \n Required, must - not be nil." - properties: - metadata: - description: May contain labels and annotations that - will be copied into the PVC when creating it. No other - fields are allowed and will be rejected during validation. - type: object - spec: - description: The specification for the PersistentVolumeClaim. - The entire content is copied unchanged into the PVC - that gets created from this template. The same fields - as in a PersistentVolumeClaim are also valid here. - properties: - accessModes: - description: 'accessModes contains the desired access - modes the volume should have. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#access-modes-1' - items: - type: string - type: array - dataSource: - description: 'dataSource field can be used to specify - either: * An existing VolumeSnapshot object (snapshot.storage.k8s.io/VolumeSnapshot) - * An existing PVC (PersistentVolumeClaim) If the - provisioner or an external controller can support - the specified data source, it will create a new - volume based on the contents of the specified - data source. When the AnyVolumeDataSource feature - gate is enabled, dataSource contents will be copied - to dataSourceRef, and dataSourceRef contents will - be copied to dataSource when dataSourceRef.namespace - is not specified. If the namespace is specified, - then dataSourceRef will not be copied to dataSource.' - properties: - apiGroup: - description: APIGroup is the group for the resource - being referenced. If APIGroup is not specified, - the specified Kind must be in the core API - group. For any other third-party types, APIGroup - is required. - type: string - kind: - description: Kind is the type of resource being - referenced - type: string - name: - description: Name is the name of resource being - referenced - type: string - required: - - kind - - name - type: object - x-kubernetes-map-type: atomic - dataSourceRef: - description: 'dataSourceRef specifies the object - from which to populate the volume with data, if - a non-empty volume is desired. This may be any - object from a non-empty API group (non core object) - or a PersistentVolumeClaim object. When this field - is specified, volume binding will only succeed - if the type of the specified object matches some - installed volume populator or dynamic provisioner. - This field will replace the functionality of the - dataSource field and as such if both fields are - non-empty, they must have the same value. For - backwards compatibility, when namespace isn''t - specified in dataSourceRef, both fields (dataSource - and dataSourceRef) will be set to the same value - automatically if one of them is empty and the - other is non-empty. When namespace is specified - in dataSourceRef, dataSource isn''t set to the - same value and must be empty. There are three - important differences between dataSource and dataSourceRef: - * While dataSource only allows two specific types - of objects, dataSourceRef allows any non-core - object, as well as PersistentVolumeClaim objects. - * While dataSource ignores disallowed values (dropping - them), dataSourceRef preserves all values, and - generates an error if a disallowed value is specified. - * While dataSource only allows local objects, - dataSourceRef allows objects in any namespaces. - (Beta) Using this field requires the AnyVolumeDataSource - feature gate to be enabled. (Alpha) Using the - namespace field of dataSourceRef requires the - CrossNamespaceVolumeDataSource feature gate to - be enabled.' - properties: - apiGroup: - description: APIGroup is the group for the resource - being referenced. If APIGroup is not specified, - the specified Kind must be in the core API - group. For any other third-party types, APIGroup - is required. - type: string - kind: - description: Kind is the type of resource being - referenced - type: string - name: - description: Name is the name of resource being - referenced - type: string - namespace: - description: Namespace is the namespace of resource - being referenced Note that when a namespace - is specified, a gateway.networking.k8s.io/ReferenceGrant - object is required in the referent namespace - to allow that namespace's owner to accept - the reference. See the ReferenceGrant documentation - for details. (Alpha) This field requires the - CrossNamespaceVolumeDataSource feature gate - to be enabled. - type: string - required: - - kind - - name - type: object - resources: - description: 'resources represents the minimum resources - the volume should have. If RecoverVolumeExpansionFailure - feature is enabled users are allowed to specify - resource requirements that are lower than previous - value but must still be higher than capacity recorded - in the status field of the claim. More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#resources' - properties: - claims: - description: "Claims lists the names of resources, - defined in spec.resourceClaims, that are used - by this container. \n This is an alpha field - and requires enabling the DynamicResourceAllocation - feature gate. \n This field is immutable. - It can only be set for containers." - items: - description: ResourceClaim references one - entry in PodSpec.ResourceClaims. - properties: - name: - description: Name must match the name - of one entry in pod.spec.resourceClaims - of the Pod where this field is used. - It makes that resource available inside - a container. - type: string - required: - - name - type: object - type: array - x-kubernetes-list-map-keys: - - name - x-kubernetes-list-type: map - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Limits describes the maximum amount - of compute resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - description: 'Requests describes the minimum - amount of compute resources required. If Requests - is omitted for a container, it defaults to - Limits if that is explicitly specified, otherwise - to an implementation-defined value. Requests - cannot exceed Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/' - type: object - type: object - selector: - description: selector is a label query over volumes - to consider for binding. - properties: - matchExpressions: - description: matchExpressions is a list of label - selector requirements. The requirements are - ANDed. - items: - description: A label selector requirement - is a selector that contains values, a key, - and an operator that relates the key and - values. - properties: - key: - description: key is the label key that - the selector applies to. - type: string - operator: - description: operator represents a key's - relationship to a set of values. Valid - operators are In, NotIn, Exists and - DoesNotExist. - type: string - values: - description: values is an array of string - values. If the operator is In or NotIn, - the values array must be non-empty. - If the operator is Exists or DoesNotExist, - the values array must be empty. This - array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} - pairs. A single {key,value} in the matchLabels - map is equivalent to an element of matchExpressions, - whose key field is "key", the operator is - "In", and the values array contains only "value". - The requirements are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - storageClassName: - description: 'storageClassName is the name of the - StorageClass required by the claim. More info: - https://kubernetes.io/docs/concepts/storage/persistent-volumes#class-1' - type: string - volumeMode: - description: volumeMode defines what type of volume - is required by the claim. Value of Filesystem - is implied when not included in claim spec. - type: string - volumeName: - description: volumeName is the binding reference - to the PersistentVolume backing this claim. - type: string - type: object - required: - - spec - type: object - type: object - fc: - description: fc represents a Fibre Channel resource that is - attached to a kubelet's host machine and then exposed to the - pod. - properties: - fsType: - description: 'fsType is the filesystem type to mount. Must - be a filesystem type supported by the host operating system. - Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" - if unspecified. TODO: how do we prevent errors in the - filesystem from compromising the machine' - type: string - lun: - description: 'lun is Optional: FC target lun number' - format: int32 - type: integer - readOnly: - description: 'readOnly is Optional: Defaults to false (read/write). - ReadOnly here will force the ReadOnly setting in VolumeMounts.' - type: boolean - targetWWNs: - description: 'targetWWNs is Optional: FC target worldwide - names (WWNs)' - items: - type: string - type: array - wwids: - description: 'wwids Optional: FC volume world wide identifiers - (wwids) Either wwids or combination of targetWWNs and - lun must be set, but not both simultaneously.' - items: - type: string - type: array - type: object - flexVolume: - description: flexVolume represents a generic volume resource - that is provisioned/attached using an exec based plugin. - properties: - driver: - description: driver is the name of the driver to use for - this volume. - type: string - fsType: - description: fsType is the filesystem type to mount. Must - be a filesystem type supported by the host operating system. - Ex. "ext4", "xfs", "ntfs". The default filesystem depends - on FlexVolume script. - type: string - options: - additionalProperties: - type: string - description: 'options is Optional: this field holds extra - command options if any.' - type: object - readOnly: - description: 'readOnly is Optional: defaults to false (read/write). - ReadOnly here will force the ReadOnly setting in VolumeMounts.' - type: boolean - secretRef: - description: 'secretRef is Optional: secretRef is reference - to the secret object containing sensitive information - to pass to the plugin scripts. This may be empty if no - secret object is specified. If the secret object contains - more than one secret, all secrets are passed to the plugin - scripts.' - properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - type: object - x-kubernetes-map-type: atomic - required: - - driver - type: object - flocker: - description: flocker represents a Flocker volume attached to - a kubelet's host machine. This depends on the Flocker control - service being running - properties: - datasetName: - description: datasetName is Name of the dataset stored as - metadata -> name on the dataset for Flocker should be - considered as deprecated - type: string - datasetUUID: - description: datasetUUID is the UUID of the dataset. This - is unique identifier of a Flocker dataset - type: string - type: object - gcePersistentDisk: - description: 'gcePersistentDisk represents a GCE Disk resource - that is attached to a kubelet''s host machine and then exposed - to the pod. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' - properties: - fsType: - description: 'fsType is filesystem type of the volume that - you want to mount. Tip: Ensure that the filesystem type - is supported by the host operating system. Examples: "ext4", - "xfs", "ntfs". Implicitly inferred to be "ext4" if unspecified. - More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk - TODO: how do we prevent errors in the filesystem from - compromising the machine' - type: string - partition: - description: 'partition is the partition in the volume that - you want to mount. If omitted, the default is to mount - by volume name. Examples: For volume /dev/sda1, you specify - the partition as "1". Similarly, the volume partition - for /dev/sda is "0" (or you can leave the property empty). - More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' - format: int32 - type: integer - pdName: - description: 'pdName is unique name of the PD resource in - GCE. Used to identify the disk in GCE. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' - type: string - readOnly: - description: 'readOnly here will force the ReadOnly setting - in VolumeMounts. Defaults to false. More info: https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk' - type: boolean - required: - - pdName - type: object - gitRepo: - description: 'gitRepo represents a git repository at a particular - revision. DEPRECATED: GitRepo is deprecated. To provision - a container with a git repo, mount an EmptyDir into an InitContainer - that clones the repo using git, then mount the EmptyDir into - the Pod''s container.' - properties: - directory: - description: directory is the target directory name. Must - not contain or start with '..'. If '.' is supplied, the - volume directory will be the git repository. Otherwise, - if specified, the volume will contain the git repository - in the subdirectory with the given name. - type: string - repository: - description: repository is the URL - type: string - revision: - description: revision is the commit hash for the specified - revision. - type: string - required: - - repository - type: object - glusterfs: - description: 'glusterfs represents a Glusterfs mount on the - host that shares a pod''s lifetime. More info: https://examples.k8s.io/volumes/glusterfs/README.md' - properties: - endpoints: - description: 'endpoints is the endpoint name that details - Glusterfs topology. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' - type: string - path: - description: 'path is the Glusterfs volume path. More info: - https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' - type: string - readOnly: - description: 'readOnly here will force the Glusterfs volume - to be mounted with read-only permissions. Defaults to - false. More info: https://examples.k8s.io/volumes/glusterfs/README.md#create-a-pod' - type: boolean - required: - - endpoints - - path - type: object - hostPath: - description: 'hostPath represents a pre-existing file or directory - on the host machine that is directly exposed to the container. - This is generally used for system agents or other privileged - things that are allowed to see the host machine. Most containers - will NOT need this. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath - --- TODO(jonesdl) We need to restrict who can use host directory - mounts and who can/can not mount host directories as read/write.' - properties: - path: - description: 'path of the directory on the host. If the - path is a symlink, it will follow the link to the real - path. More info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' - type: string - type: - description: 'type for HostPath Volume Defaults to "" More - info: https://kubernetes.io/docs/concepts/storage/volumes#hostpath' - type: string - required: - - path - type: object - iscsi: - description: 'iscsi represents an ISCSI Disk resource that is - attached to a kubelet''s host machine and then exposed to - the pod. More info: https://examples.k8s.io/volumes/iscsi/README.md' - properties: - chapAuthDiscovery: - description: chapAuthDiscovery defines whether support iSCSI - Discovery CHAP authentication - type: boolean - chapAuthSession: - description: chapAuthSession defines whether support iSCSI - Session CHAP authentication - type: boolean - fsType: - description: 'fsType is the filesystem type of the volume - that you want to mount. Tip: Ensure that the filesystem - type is supported by the host operating system. Examples: - "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" - if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#iscsi - TODO: how do we prevent errors in the filesystem from - compromising the machine' - type: string - initiatorName: - description: initiatorName is the custom iSCSI Initiator - Name. If initiatorName is specified with iscsiInterface - simultaneously, new iSCSI interface : will be created for the connection. - type: string - iqn: - description: iqn is the target iSCSI Qualified Name. - type: string - iscsiInterface: - description: iscsiInterface is the interface Name that uses - an iSCSI transport. Defaults to 'default' (tcp). - type: string - lun: - description: lun represents iSCSI Target Lun number. - format: int32 - type: integer - portals: - description: portals is the iSCSI Target Portal List. The - portal is either an IP or ip_addr:port if the port is - other than default (typically TCP ports 860 and 3260). - items: - type: string - type: array - readOnly: - description: readOnly here will force the ReadOnly setting - in VolumeMounts. Defaults to false. - type: boolean - secretRef: - description: secretRef is the CHAP Secret for iSCSI target - and initiator authentication - properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - type: object - x-kubernetes-map-type: atomic - targetPortal: - description: targetPortal is iSCSI Target Portal. The Portal - is either an IP or ip_addr:port if the port is other than - default (typically TCP ports 860 and 3260). - type: string - required: - - iqn - - lun - - targetPortal - type: object - name: - description: 'name of the volume. Must be a DNS_LABEL and unique - within the pod. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names' - type: string - nfs: - description: 'nfs represents an NFS mount on the host that shares - a pod''s lifetime More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' - properties: - path: - description: 'path that is exported by the NFS server. More - info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' - type: string - readOnly: - description: 'readOnly here will force the NFS export to - be mounted with read-only permissions. Defaults to false. - More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' - type: boolean - server: - description: 'server is the hostname or IP address of the - NFS server. More info: https://kubernetes.io/docs/concepts/storage/volumes#nfs' - type: string - required: - - path - - server - type: object - persistentVolumeClaim: - description: 'persistentVolumeClaimVolumeSource represents a - reference to a PersistentVolumeClaim in the same namespace. - More info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' - properties: - claimName: - description: 'claimName is the name of a PersistentVolumeClaim - in the same namespace as the pod using this volume. More - info: https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims' - type: string - readOnly: - description: readOnly Will force the ReadOnly setting in - VolumeMounts. Default false. - type: boolean - required: - - claimName - type: object - photonPersistentDisk: - description: photonPersistentDisk represents a PhotonController - persistent disk attached and mounted on kubelets host machine - properties: - fsType: - description: fsType is the filesystem type to mount. Must - be a filesystem type supported by the host operating system. - Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" - if unspecified. - type: string - pdID: - description: pdID is the ID that identifies Photon Controller - persistent disk - type: string - required: - - pdID - type: object - portworxVolume: - description: portworxVolume represents a portworx volume attached - and mounted on kubelets host machine - properties: - fsType: - description: fSType represents the filesystem type to mount - Must be a filesystem type supported by the host operating - system. Ex. "ext4", "xfs". Implicitly inferred to be "ext4" - if unspecified. - type: string - readOnly: - description: readOnly defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. - type: boolean - volumeID: - description: volumeID uniquely identifies a Portworx volume - type: string - required: - - volumeID - type: object - projected: - description: projected items for all in one resources secrets, - configmaps, and downward API - properties: - defaultMode: - description: defaultMode are the mode bits used to set permissions - on created files by default. Must be an octal value between - 0000 and 0777 or a decimal value between 0 and 511. YAML - accepts both octal and decimal values, JSON requires decimal - values for mode bits. Directories within the path are - not affected by this setting. This might be in conflict - with other options that affect the file mode, like fsGroup, - and the result can be other mode bits set. - format: int32 - type: integer - sources: - description: sources is the list of volume projections - items: - description: Projection that may be projected along with - other supported volume types - properties: - configMap: - description: configMap information about the configMap - data to project - properties: - items: - description: items if unspecified, each key-value - pair in the Data field of the referenced ConfigMap - will be projected into the volume as a file - whose name is the key and content is the value. - If specified, the listed keys will be projected - into the specified paths, and unlisted keys - will not be present. If a key is specified which - is not present in the ConfigMap, the volume - setup will error unless it is marked optional. - Paths must be relative and may not contain the - '..' path or start with '..'. - items: - description: Maps a string key to a path within - a volume. - properties: - key: - description: key is the key to project. - type: string - mode: - description: 'mode is Optional: mode bits - used to set permissions on this file. - Must be an octal value between 0000 and - 0777 or a decimal value between 0 and - 511. YAML accepts both octal and decimal - values, JSON requires decimal values for - mode bits. If not specified, the volume - defaultMode will be used. This might be - in conflict with other options that affect - the file mode, like fsGroup, and the result - can be other mode bits set.' - format: int32 - type: integer - path: - description: path is the relative path of - the file to map the key to. May not be - an absolute path. May not contain the - path element '..'. May not start with - the string '..'. - type: string - required: - - key - - path - type: object - type: array - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: optional specify whether the ConfigMap - or its keys must be defined - type: boolean - type: object - x-kubernetes-map-type: atomic - downwardAPI: - description: downwardAPI information about the downwardAPI - data to project - properties: - items: - description: Items is a list of DownwardAPIVolume - file - items: - description: DownwardAPIVolumeFile represents - information to create the file containing - the pod field - properties: - fieldRef: - description: 'Required: Selects a field - of the pod: only annotations, labels, - name and namespace are supported.' - properties: - apiVersion: - description: Version of the schema the - FieldPath is written in terms of, - defaults to "v1". - type: string - fieldPath: - description: Path of the field to select - in the specified API version. - type: string - required: - - fieldPath - type: object - x-kubernetes-map-type: atomic - mode: - description: 'Optional: mode bits used to - set permissions on this file, must be - an octal value between 0000 and 0777 or - a decimal value between 0 and 511. YAML - accepts both octal and decimal values, - JSON requires decimal values for mode - bits. If not specified, the volume defaultMode - will be used. This might be in conflict - with other options that affect the file - mode, like fsGroup, and the result can - be other mode bits set.' - format: int32 - type: integer - path: - description: 'Required: Path is the relative - path name of the file to be created. Must - not be absolute or contain the ''..'' - path. Must be utf-8 encoded. The first - item of the relative path must not start - with ''..''' - type: string - resourceFieldRef: - description: 'Selects a resource of the - container: only resources limits and requests - (limits.cpu, limits.memory, requests.cpu - and requests.memory) are currently supported.' - properties: - containerName: - description: 'Container name: required - for volumes, optional for env vars' - type: string - divisor: - anyOf: - - type: integer - - type: string - description: Specifies the output format - of the exposed resources, defaults - to "1" - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - description: 'Required: resource to - select' - type: string - required: - - resource - type: object - x-kubernetes-map-type: atomic - required: - - path - type: object - type: array - type: object - secret: - description: secret information about the secret data - to project - properties: - items: - description: items if unspecified, each key-value - pair in the Data field of the referenced Secret - will be projected into the volume as a file - whose name is the key and content is the value. - If specified, the listed keys will be projected - into the specified paths, and unlisted keys - will not be present. If a key is specified which - is not present in the Secret, the volume setup - will error unless it is marked optional. Paths - must be relative and may not contain the '..' - path or start with '..'. - items: - description: Maps a string key to a path within - a volume. - properties: - key: - description: key is the key to project. - type: string - mode: - description: 'mode is Optional: mode bits - used to set permissions on this file. - Must be an octal value between 0000 and - 0777 or a decimal value between 0 and - 511. YAML accepts both octal and decimal - values, JSON requires decimal values for - mode bits. If not specified, the volume - defaultMode will be used. This might be - in conflict with other options that affect - the file mode, like fsGroup, and the result - can be other mode bits set.' - format: int32 - type: integer - path: - description: path is the relative path of - the file to map the key to. May not be - an absolute path. May not contain the - path element '..'. May not start with - the string '..'. - type: string - required: - - key - - path - type: object - type: array - name: - description: 'Name of the referent. More info: - https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: optional field specify whether the - Secret or its key must be defined - type: boolean - type: object - x-kubernetes-map-type: atomic - serviceAccountToken: - description: serviceAccountToken is information about - the serviceAccountToken data to project - properties: - audience: - description: audience is the intended audience - of the token. A recipient of a token must identify - itself with an identifier specified in the audience - of the token, and otherwise should reject the - token. The audience defaults to the identifier - of the apiserver. - type: string - expirationSeconds: - description: expirationSeconds is the requested - duration of validity of the service account - token. As the token approaches expiration, the - kubelet volume plugin will proactively rotate - the service account token. The kubelet will - start trying to rotate the token if the token - is older than 80 percent of its time to live - or if the token is older than 24 hours.Defaults - to 1 hour and must be at least 10 minutes. - format: int64 - type: integer - path: - description: path is the path relative to the - mount point of the file to project the token - into. - type: string - required: - - path - type: object - type: object - type: array - type: object - quobyte: - description: quobyte represents a Quobyte mount on the host - that shares a pod's lifetime - properties: - group: - description: group to map volume access to Default is no - group - type: string - readOnly: - description: readOnly here will force the Quobyte volume - to be mounted with read-only permissions. Defaults to - false. - type: boolean - registry: - description: registry represents a single or multiple Quobyte - Registry services specified as a string as host:port pair - (multiple entries are separated with commas) which acts - as the central registry for volumes - type: string - tenant: - description: tenant owning the given Quobyte volume in the - Backend Used with dynamically provisioned Quobyte volumes, - value is set by the plugin - type: string - user: - description: user to map volume access to Defaults to serivceaccount - user - type: string - volume: - description: volume is a string that references an already - created Quobyte volume by name. - type: string - required: - - registry - - volume - type: object - rbd: - description: 'rbd represents a Rados Block Device mount on the - host that shares a pod''s lifetime. More info: https://examples.k8s.io/volumes/rbd/README.md' - properties: - fsType: - description: 'fsType is the filesystem type of the volume - that you want to mount. Tip: Ensure that the filesystem - type is supported by the host operating system. Examples: - "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" - if unspecified. More info: https://kubernetes.io/docs/concepts/storage/volumes#rbd - TODO: how do we prevent errors in the filesystem from - compromising the machine' - type: string - image: - description: 'image is the rados image name. More info: - https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' - type: string - keyring: - description: 'keyring is the path to key ring for RBDUser. - Default is /etc/ceph/keyring. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' - type: string - monitors: - description: 'monitors is a collection of Ceph monitors. - More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' - items: - type: string - type: array - pool: - description: 'pool is the rados pool name. Default is rbd. - More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' - type: string - readOnly: - description: 'readOnly here will force the ReadOnly setting - in VolumeMounts. Defaults to false. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' - type: boolean - secretRef: - description: 'secretRef is name of the authentication secret - for RBDUser. If provided overrides keyring. Default is - nil. More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' - properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - type: object - x-kubernetes-map-type: atomic - user: - description: 'user is the rados user name. Default is admin. - More info: https://examples.k8s.io/volumes/rbd/README.md#how-to-use-it' - type: string - required: - - image - - monitors - type: object - scaleIO: - description: scaleIO represents a ScaleIO persistent volume - attached and mounted on Kubernetes nodes. - properties: - fsType: - description: fsType is the filesystem type to mount. Must - be a filesystem type supported by the host operating system. - Ex. "ext4", "xfs", "ntfs". Default is "xfs". - type: string - gateway: - description: gateway is the host address of the ScaleIO - API Gateway. - type: string - protectionDomain: - description: protectionDomain is the name of the ScaleIO - Protection Domain for the configured storage. - type: string - readOnly: - description: readOnly Defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. - type: boolean - secretRef: - description: secretRef references to the secret for ScaleIO - user and other sensitive information. If this is not provided, - Login operation will fail. - properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - type: object - x-kubernetes-map-type: atomic - sslEnabled: - description: sslEnabled Flag enable/disable SSL communication - with Gateway, default false - type: boolean - storageMode: - description: storageMode indicates whether the storage for - a volume should be ThickProvisioned or ThinProvisioned. - Default is ThinProvisioned. - type: string - storagePool: - description: storagePool is the ScaleIO Storage Pool associated - with the protection domain. - type: string - system: - description: system is the name of the storage system as - configured in ScaleIO. - type: string - volumeName: - description: volumeName is the name of a volume already - created in the ScaleIO system that is associated with - this volume source. - type: string - required: - - gateway - - secretRef - - system - type: object - secret: - description: 'secret represents a secret that should populate - this volume. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' - properties: - defaultMode: - description: 'defaultMode is Optional: mode bits used to - set permissions on created files by default. Must be an - octal value between 0000 and 0777 or a decimal value between - 0 and 511. YAML accepts both octal and decimal values, - JSON requires decimal values for mode bits. Defaults to - 0644. Directories within the path are not affected by - this setting. This might be in conflict with other options - that affect the file mode, like fsGroup, and the result - can be other mode bits set.' - format: int32 - type: integer - items: - description: items If unspecified, each key-value pair in - the Data field of the referenced Secret will be projected - into the volume as a file whose name is the key and content - is the value. If specified, the listed keys will be projected - into the specified paths, and unlisted keys will not be - present. If a key is specified which is not present in - the Secret, the volume setup will error unless it is marked - optional. Paths must be relative and may not contain the - '..' path or start with '..'. - items: - description: Maps a string key to a path within a volume. - properties: - key: - description: key is the key to project. - type: string - mode: - description: 'mode is Optional: mode bits used to - set permissions on this file. Must be an octal value - between 0000 and 0777 or a decimal value between - 0 and 511. YAML accepts both octal and decimal values, - JSON requires decimal values for mode bits. If not - specified, the volume defaultMode will be used. - This might be in conflict with other options that - affect the file mode, like fsGroup, and the result - can be other mode bits set.' - format: int32 - type: integer - path: - description: path is the relative path of the file - to map the key to. May not be an absolute path. - May not contain the path element '..'. May not start - with the string '..'. - type: string - required: - - key - - path - type: object - type: array - optional: - description: optional field specify whether the Secret or - its keys must be defined - type: boolean - secretName: - description: 'secretName is the name of the secret in the - pod''s namespace to use. More info: https://kubernetes.io/docs/concepts/storage/volumes#secret' - type: string - type: object - storageos: - description: storageOS represents a StorageOS volume attached - and mounted on Kubernetes nodes. - properties: - fsType: - description: fsType is the filesystem type to mount. Must - be a filesystem type supported by the host operating system. - Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" - if unspecified. - type: string - readOnly: - description: readOnly defaults to false (read/write). ReadOnly - here will force the ReadOnly setting in VolumeMounts. - type: boolean - secretRef: - description: secretRef specifies the secret to use for obtaining - the StorageOS API credentials. If not specified, default - values will be attempted. - properties: - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - type: object - x-kubernetes-map-type: atomic - volumeName: - description: volumeName is the human-readable name of the - StorageOS volume. Volume names are only unique within - a namespace. - type: string - volumeNamespace: - description: volumeNamespace specifies the scope of the - volume within StorageOS. If no namespace is specified - then the Pod's namespace will be used. This allows the - Kubernetes name scoping to be mirrored within StorageOS - for tighter integration. Set VolumeName to any name to - override the default behaviour. Set to "default" if you - are not using namespaces within StorageOS. Namespaces - that do not pre-exist within StorageOS will be created. - type: string - type: object - vsphereVolume: - description: vsphereVolume represents a vSphere volume attached - and mounted on kubelets host machine - properties: - fsType: - description: fsType is filesystem type to mount. Must be - a filesystem type supported by the host operating system. - Ex. "ext4", "xfs", "ntfs". Implicitly inferred to be "ext4" - if unspecified. - type: string - storagePolicyID: - description: storagePolicyID is the storage Policy Based - Management (SPBM) profile ID associated with the StoragePolicyName. - type: string - storagePolicyName: - description: storagePolicyName is the storage Policy Based - Management (SPBM) profile name. - type: string - volumePath: - description: volumePath is the path that identifies vSphere - volume vmdk - type: string - required: - - volumePath - type: object - required: - - name - type: object - type: array - required: - - config - - name - - type - type: object - type: object - served: true - storage: true diff --git a/production/operator/crds/monitoring.grafana.com_logsinstances.yaml b/production/operator/crds/monitoring.grafana.com_logsinstances.yaml deleted file mode 100644 index f36440ab0cd0..000000000000 --- a/production/operator/crds/monitoring.grafana.com_logsinstances.yaml +++ /dev/null @@ -1,500 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.9.2 - creationTimestamp: null - name: logsinstances.monitoring.grafana.com -spec: - group: monitoring.grafana.com - names: - categories: - - agent-operator - kind: LogsInstance - listKind: LogsInstanceList - plural: logsinstances - singular: logsinstance - scope: Namespaced - versions: - - name: v1alpha1 - schema: - openAPIV3Schema: - description: LogsInstance controls an individual logs instance within a Grafana - Agent deployment. - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: Spec holds the specification of the desired behavior for - the logs instance. - properties: - additionalScrapeConfigs: - description: "AdditionalScrapeConfigs allows specifying a key of a - Secret containing additional Grafana Agent logging scrape configurations. - Scrape configurations specified are appended to the configurations - generated by the Grafana Agent Operator. \n Job configurations specified - must have the form as specified in the official Promtail documentation: - \n https://grafana.com/docs/loki/latest/clients/promtail/configuration/#scrape_configs - \n As scrape configs are appended, the user is responsible to make - sure it is valid. Note that using this feature may expose the possibility - to break upgrades of Grafana Agent. It is advised to review both - Grafana Agent and Promtail release notes to ensure that no incompatible - scrape configs are going to break Grafana Agent after the upgrade." - properties: - key: - description: The key of the secret to select from. Must be a - valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - clients: - description: Clients controls where logs are written to for this instance. - items: - description: LogsClientSpec defines the client integration for logs, - indicating which Loki server to send logs to. - properties: - backoffConfig: - description: Configures how to retry requests to Loki when a - request fails. Defaults to a minPeriod of 500ms, maxPeriod - of 5m, and maxRetries of 10. - properties: - maxPeriod: - description: Maximum backoff time between retries. - type: string - maxRetries: - description: Maximum number of retries to perform before - giving up a request. - type: integer - minPeriod: - description: Initial backoff time between retries. Time - between retries is increased exponentially. - type: string - type: object - basicAuth: - description: BasicAuth for the Loki server. - properties: - password: - description: The secret in the service monitor namespace - that contains the password for authentication. - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must - be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - username: - description: The secret in the service monitor namespace - that contains the username for authentication. - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must - be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - batchSize: - description: Maximum batch size (in bytes) of logs to accumulate - before sending the batch to Loki. - type: integer - batchWait: - description: Maximum amount of time to wait before sending a - batch, even if that batch isn't full. - type: string - bearerToken: - description: BearerToken used for remote_write. - type: string - bearerTokenFile: - description: BearerTokenFile used to read bearer token. - type: string - externalLabels: - additionalProperties: - type: string - description: ExternalLabels are labels to add to any time series - when sending data to Loki. - type: object - oauth2: - description: Oauth2 for URL - properties: - clientId: - description: The secret or configmap containing the OAuth2 - client id - properties: - configMap: - description: ConfigMap containing data to use for the - targets. - properties: - key: - description: The key to select. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the ConfigMap or its - key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - secret: - description: Secret containing data to use for the targets. - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the Secret or its key - must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - clientSecret: - description: The secret containing the OAuth2 client secret - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must - be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - endpointParams: - additionalProperties: - type: string - description: Parameters to append to the token URL - type: object - scopes: - description: OAuth2 scopes used for the token request - items: - type: string - type: array - tokenUrl: - description: The URL to fetch the token from - minLength: 1 - type: string - required: - - clientId - - clientSecret - - tokenUrl - type: object - proxyUrl: - description: ProxyURL to proxy requests through. Optional. - type: string - tenantId: - description: Tenant ID used by default to push logs to Loki. - If omitted assumes remote Loki is running in single-tenant - mode or an authentication layer is used to inject an X-Scope-OrgID - header. - type: string - timeout: - description: Maximum time to wait for a server to respond to - a request. - type: string - tlsConfig: - description: TLSConfig to use for the client. Only used when - the protocol of the URL is https. - properties: - ca: - description: Certificate authority used when verifying server - certificates. - properties: - configMap: - description: ConfigMap containing data to use for the - targets. - properties: - key: - description: The key to select. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the ConfigMap or its - key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - secret: - description: Secret containing data to use for the targets. - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the Secret or its key - must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - caFile: - description: Path to the CA cert in the Prometheus container - to use for the targets. - type: string - cert: - description: Client certificate to present when doing client-authentication. - properties: - configMap: - description: ConfigMap containing data to use for the - targets. - properties: - key: - description: The key to select. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the ConfigMap or its - key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - secret: - description: Secret containing data to use for the targets. - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the Secret or its key - must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - certFile: - description: Path to the client cert file in the Prometheus - container for the targets. - type: string - insecureSkipVerify: - description: Disable target certificate validation. - type: boolean - keyFile: - description: Path to the client key file in the Prometheus - container for the targets. - type: string - keySecret: - description: Secret containing the client key file for the - targets. - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must - be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - serverName: - description: Used to verify the hostname for the targets. - type: string - type: object - url: - description: 'URL is the URL where Loki is listening. Must be - a full HTTP URL, including protocol. Required. Example: https://logs-prod-us-central1.grafana.net/loki/api/v1/push.' - type: string - required: - - url - type: object - type: array - podLogsNamespaceSelector: - description: Set of labels to determine which namespaces should be - watched for PodLogs. If not provided, checks only namespace of the - instance. - properties: - matchExpressions: - description: matchExpressions is a list of label selector requirements. - The requirements are ANDed. - items: - description: A label selector requirement is a selector that - contains values, a key, and an operator that relates the key - and values. - properties: - key: - description: key is the label key that the selector applies - to. - type: string - operator: - description: operator represents a key's relationship to - a set of values. Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of string values. If the - operator is In or NotIn, the values array must be non-empty. - If the operator is Exists or DoesNotExist, the values - array must be empty. This array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. A single - {key,value} in the matchLabels map is equivalent to an element - of matchExpressions, whose key field is "key", the operator - is "In", and the values array contains only "value". The requirements - are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - podLogsSelector: - description: Determines which PodLogs should be selected for including - in this instance. - properties: - matchExpressions: - description: matchExpressions is a list of label selector requirements. - The requirements are ANDed. - items: - description: A label selector requirement is a selector that - contains values, a key, and an operator that relates the key - and values. - properties: - key: - description: key is the label key that the selector applies - to. - type: string - operator: - description: operator represents a key's relationship to - a set of values. Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of string values. If the - operator is In or NotIn, the values array must be non-empty. - If the operator is Exists or DoesNotExist, the values - array must be empty. This array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. A single - {key,value} in the matchLabels map is equivalent to an element - of matchExpressions, whose key field is "key", the operator - is "In", and the values array contains only "value". The requirements - are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - targetConfig: - description: Configures how tailed targets are watched. - properties: - syncPeriod: - description: Period to resync directories being watched and files - being tailed to discover new ones or stop watching removed ones. - type: string - type: object - type: object - type: object - served: true - storage: true diff --git a/production/operator/crds/monitoring.grafana.com_metricsinstances.yaml b/production/operator/crds/monitoring.grafana.com_metricsinstances.yaml deleted file mode 100644 index 015c0339ce1a..000000000000 --- a/production/operator/crds/monitoring.grafana.com_metricsinstances.yaml +++ /dev/null @@ -1,861 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.9.2 - creationTimestamp: null - name: metricsinstances.monitoring.grafana.com -spec: - group: monitoring.grafana.com - names: - categories: - - agent-operator - kind: MetricsInstance - listKind: MetricsInstanceList - plural: metricsinstances - singular: metricsinstance - scope: Namespaced - versions: - - name: v1alpha1 - schema: - openAPIV3Schema: - description: MetricsInstance controls an individual Metrics instance within - a Grafana Agent deployment. - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: Spec holds the specification of the desired behavior for - the Metrics instance. - properties: - additionalScrapeConfigs: - description: 'AdditionalScrapeConfigs lets you specify a key of a - Secret containing additional Grafana Agent Prometheus scrape configurations. - The specified scrape configurations are appended to the configurations - generated by Grafana Agent Operator. Specified job configurations - must have the form specified in the official Prometheus documentation: - https://prometheus.io/docs/prometheus/latest/configuration/configuration/#scrape_config. - As scrape configs are appended, you must make sure the configuration - is still valid. Note that it''s possible that this feature will - break future upgrades of Grafana Agent. Review both Grafana Agent - and Prometheus release notes to ensure that no incompatible scrape - configs will break Grafana Agent after the upgrade.' - properties: - key: - description: The key of the secret to select from. Must be a - valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - maxWALTime: - description: MaxWALTime is the maximum amount of time that series - and samples can exist in the WAL before being forcibly deleted. - type: string - minWALTime: - description: MinWALTime is the minimum amount of time that series - and samples can exist in the WAL before being considered for deletion. - type: string - podMonitorNamespaceSelector: - description: PodMonitorNamespaceSelector are the set of labels to - determine which namespaces to watch for PodMonitor discovery. If - nil, it only checks its own namespace. - properties: - matchExpressions: - description: matchExpressions is a list of label selector requirements. - The requirements are ANDed. - items: - description: A label selector requirement is a selector that - contains values, a key, and an operator that relates the key - and values. - properties: - key: - description: key is the label key that the selector applies - to. - type: string - operator: - description: operator represents a key's relationship to - a set of values. Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of string values. If the - operator is In or NotIn, the values array must be non-empty. - If the operator is Exists or DoesNotExist, the values - array must be empty. This array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. A single - {key,value} in the matchLabels map is equivalent to an element - of matchExpressions, whose key field is "key", the operator - is "In", and the values array contains only "value". The requirements - are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - podMonitorSelector: - description: PodMonitorSelector determines which PodMonitors to selected - for target discovery. Experimental. - properties: - matchExpressions: - description: matchExpressions is a list of label selector requirements. - The requirements are ANDed. - items: - description: A label selector requirement is a selector that - contains values, a key, and an operator that relates the key - and values. - properties: - key: - description: key is the label key that the selector applies - to. - type: string - operator: - description: operator represents a key's relationship to - a set of values. Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of string values. If the - operator is In or NotIn, the values array must be non-empty. - If the operator is Exists or DoesNotExist, the values - array must be empty. This array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. A single - {key,value} in the matchLabels map is equivalent to an element - of matchExpressions, whose key field is "key", the operator - is "In", and the values array contains only "value". The requirements - are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - probeNamespaceSelector: - description: ProbeNamespaceSelector is the set of labels that determines - which namespaces to watch for Probe discovery. If nil, it only checks - own namespace. - properties: - matchExpressions: - description: matchExpressions is a list of label selector requirements. - The requirements are ANDed. - items: - description: A label selector requirement is a selector that - contains values, a key, and an operator that relates the key - and values. - properties: - key: - description: key is the label key that the selector applies - to. - type: string - operator: - description: operator represents a key's relationship to - a set of values. Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of string values. If the - operator is In or NotIn, the values array must be non-empty. - If the operator is Exists or DoesNotExist, the values - array must be empty. This array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. A single - {key,value} in the matchLabels map is equivalent to an element - of matchExpressions, whose key field is "key", the operator - is "In", and the values array contains only "value". The requirements - are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - probeSelector: - description: ProbeSelector determines which Probes to select for target - discovery. - properties: - matchExpressions: - description: matchExpressions is a list of label selector requirements. - The requirements are ANDed. - items: - description: A label selector requirement is a selector that - contains values, a key, and an operator that relates the key - and values. - properties: - key: - description: key is the label key that the selector applies - to. - type: string - operator: - description: operator represents a key's relationship to - a set of values. Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of string values. If the - operator is In or NotIn, the values array must be non-empty. - If the operator is Exists or DoesNotExist, the values - array must be empty. This array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. A single - {key,value} in the matchLabels map is equivalent to an element - of matchExpressions, whose key field is "key", the operator - is "In", and the values array contains only "value". The requirements - are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - remoteFlushDeadline: - description: RemoteFlushDeadline is the deadline for flushing data - when an instance shuts down. - type: string - remoteWrite: - description: RemoteWrite controls remote_write settings for this instance. - items: - description: RemoteWriteSpec defines the remote_write configuration - for Prometheus. - properties: - basicAuth: - description: BasicAuth for the URL. - properties: - password: - description: The secret in the service monitor namespace - that contains the password for authentication. - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must - be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - username: - description: The secret in the service monitor namespace - that contains the username for authentication. - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must - be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - bearerToken: - description: BearerToken used for remote_write. - type: string - bearerTokenFile: - description: BearerTokenFile used to read bearer token. - type: string - headers: - additionalProperties: - type: string - description: Headers is a set of custom HTTP headers to be sent - along with each remote_write request. Be aware that any headers - set by Grafana Agent itself can't be overwritten. - type: object - metadataConfig: - description: MetadataConfig configures the sending of series - metadata to remote storage. - properties: - send: - description: Send enables metric metadata to be sent to - remote storage. - type: boolean - sendInterval: - description: SendInterval controls how frequently metric - metadata is sent to remote storage. - type: string - type: object - name: - description: Name of the remote_write queue. Must be unique - if specified. The name is used in metrics and logging in order - to differentiate queues. - type: string - oauth2: - description: Oauth2 for URL - properties: - clientId: - description: The secret or configmap containing the OAuth2 - client id - properties: - configMap: - description: ConfigMap containing data to use for the - targets. - properties: - key: - description: The key to select. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the ConfigMap or its - key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - secret: - description: Secret containing data to use for the targets. - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the Secret or its key - must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - clientSecret: - description: The secret containing the OAuth2 client secret - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must - be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - endpointParams: - additionalProperties: - type: string - description: Parameters to append to the token URL - type: object - scopes: - description: OAuth2 scopes used for the token request - items: - type: string - type: array - tokenUrl: - description: The URL to fetch the token from - minLength: 1 - type: string - required: - - clientId - - clientSecret - - tokenUrl - type: object - proxyUrl: - description: ProxyURL to proxy requests through. Optional. - type: string - queueConfig: - description: QueueConfig allows tuning of the remote_write queue - parameters. - properties: - batchSendDeadline: - description: BatchSendDeadline is the maximum time a sample - will wait in the buffer. - type: string - capacity: - description: Capacity is the number of samples to buffer - per shard before samples start being dropped. - type: integer - maxBackoff: - description: MaxBackoff is the maximum retry delay. - type: string - maxRetries: - description: MaxRetries is the maximum number of times to - retry a batch on recoverable errors. - type: integer - maxSamplesPerSend: - description: MaxSamplesPerSend is the maximum number of - samples per send. - type: integer - maxShards: - description: MaxShards is the maximum number of shards, - i.e., the amount of concurrency. - type: integer - minBackoff: - description: MinBackoff is the initial retry delay. MinBackoff - is doubled for every retry. - type: string - minShards: - description: MinShards is the minimum number of shards, - i.e., the amount of concurrency. - type: integer - retryOnRateLimit: - description: RetryOnRateLimit retries requests when encountering - rate limits. - type: boolean - type: object - remoteTimeout: - description: RemoteTimeout is the timeout for requests to the - remote_write endpoint. - type: string - sigv4: - description: SigV4 configures SigV4-based authentication to - the remote_write endpoint. SigV4-based authentication is used - if SigV4 is defined, even with an empty object. - properties: - accessKey: - description: AccessKey holds the secret of the AWS API access - key to use for signing. If not provided, the environment - variable AWS_ACCESS_KEY_ID is used. - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must - be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - profile: - description: Profile is the named AWS profile to use for - authentication. - type: string - region: - description: Region of the AWS endpoint. If blank, the region - from the default credentials chain is used. - type: string - roleARN: - description: RoleARN is the AWS Role ARN to use for authentication, - as an alternative for using the AWS API keys. - type: string - secretKey: - description: SecretKey of the AWS API to use for signing. - If blank, the environment variable AWS_SECRET_ACCESS_KEY - is used. - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must - be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - tlsConfig: - description: TLSConfig to use for remote_write. - properties: - ca: - description: Certificate authority used when verifying server - certificates. - properties: - configMap: - description: ConfigMap containing data to use for the - targets. - properties: - key: - description: The key to select. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the ConfigMap or its - key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - secret: - description: Secret containing data to use for the targets. - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the Secret or its key - must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - caFile: - description: Path to the CA cert in the Prometheus container - to use for the targets. - type: string - cert: - description: Client certificate to present when doing client-authentication. - properties: - configMap: - description: ConfigMap containing data to use for the - targets. - properties: - key: - description: The key to select. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the ConfigMap or its - key must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - secret: - description: Secret containing data to use for the targets. - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, - uid?' - type: string - optional: - description: Specify whether the Secret or its key - must be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - type: object - certFile: - description: Path to the client cert file in the Prometheus - container for the targets. - type: string - insecureSkipVerify: - description: Disable target certificate validation. - type: boolean - keyFile: - description: Path to the client key file in the Prometheus - container for the targets. - type: string - keySecret: - description: Secret containing the client key file for the - targets. - properties: - key: - description: The key of the secret to select from. Must - be a valid secret key. - type: string - name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' - type: string - optional: - description: Specify whether the Secret or its key must - be defined - type: boolean - required: - - key - type: object - x-kubernetes-map-type: atomic - serverName: - description: Used to verify the hostname for the targets. - type: string - type: object - url: - description: URL of the endpoint to send samples to. - type: string - writeRelabelConfigs: - description: WriteRelabelConfigs holds relabel_configs to relabel - samples before they are sent to the remote_write endpoint. - items: - description: 'RelabelConfig allows dynamic rewriting of the - label set, being applied to samples before ingestion. It - defines ``-section of Prometheus - configuration. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs' - properties: - action: - default: replace - description: Action to perform based on regex matching. - Default is 'replace'. uppercase and lowercase actions - require Prometheus >= 2.36. - enum: - - replace - - Replace - - keep - - Keep - - drop - - Drop - - hashmod - - HashMod - - labelmap - - LabelMap - - labeldrop - - LabelDrop - - labelkeep - - LabelKeep - - lowercase - - Lowercase - - uppercase - - Uppercase - - keepequal - - KeepEqual - - dropequal - - DropEqual - type: string - modulus: - description: Modulus to take of the hash of the source - label values. - format: int64 - type: integer - regex: - description: Regular expression against which the extracted - value is matched. Default is '(.*)' - type: string - replacement: - description: Replacement value against which a regex replace - is performed if the regular expression matches. Regex - capture groups are available. Default is '$1' - type: string - separator: - description: Separator placed between concatenated source - label values. default is ';'. - type: string - sourceLabels: - description: The source labels select values from existing - labels. Their content is concatenated using the configured - separator and matched against the configured regular - expression for the replace, keep, and drop actions. - items: - description: LabelName is a valid Prometheus label name - which may only contain ASCII letters, numbers, as - well as underscores. - pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ - type: string - type: array - targetLabel: - description: Label to which the resulting value is written - in a replace action. It is mandatory for replace actions. - Regex capture groups are available. - type: string - type: object - type: array - required: - - url - type: object - type: array - serviceMonitorNamespaceSelector: - description: ServiceMonitorNamespaceSelector is the set of labels - that determine which namespaces to watch for ServiceMonitor discovery. - If nil, it only checks its own namespace. - properties: - matchExpressions: - description: matchExpressions is a list of label selector requirements. - The requirements are ANDed. - items: - description: A label selector requirement is a selector that - contains values, a key, and an operator that relates the key - and values. - properties: - key: - description: key is the label key that the selector applies - to. - type: string - operator: - description: operator represents a key's relationship to - a set of values. Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of string values. If the - operator is In or NotIn, the values array must be non-empty. - If the operator is Exists or DoesNotExist, the values - array must be empty. This array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. A single - {key,value} in the matchLabels map is equivalent to an element - of matchExpressions, whose key field is "key", the operator - is "In", and the values array contains only "value". The requirements - are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - serviceMonitorSelector: - description: ServiceMonitorSelector determines which ServiceMonitors - to select for target discovery. - properties: - matchExpressions: - description: matchExpressions is a list of label selector requirements. - The requirements are ANDed. - items: - description: A label selector requirement is a selector that - contains values, a key, and an operator that relates the key - and values. - properties: - key: - description: key is the label key that the selector applies - to. - type: string - operator: - description: operator represents a key's relationship to - a set of values. Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of string values. If the - operator is In or NotIn, the values array must be non-empty. - If the operator is Exists or DoesNotExist, the values - array must be empty. This array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. A single - {key,value} in the matchLabels map is equivalent to an element - of matchExpressions, whose key field is "key", the operator - is "In", and the values array contains only "value". The requirements - are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - walTruncateFrequency: - description: WALTruncateFrequency specifies how frequently to run - the WAL truncation process. Higher values cause the WAL to increase - and for old series to stay in the WAL longer, but reduces the chance - of data loss when remote_write fails for longer than the given frequency. - type: string - writeStaleOnShutdown: - description: WriteStaleOnShutdown writes staleness markers on shutdown - for all series. - type: boolean - type: object - type: object - served: true - storage: true diff --git a/production/operator/crds/monitoring.grafana.com_podlogs.yaml b/production/operator/crds/monitoring.grafana.com_podlogs.yaml deleted file mode 100644 index ff6531f61e88..000000000000 --- a/production/operator/crds/monitoring.grafana.com_podlogs.yaml +++ /dev/null @@ -1,588 +0,0 @@ ---- -apiVersion: apiextensions.k8s.io/v1 -kind: CustomResourceDefinition -metadata: - annotations: - controller-gen.kubebuilder.io/version: v0.9.2 - creationTimestamp: null - name: podlogs.monitoring.grafana.com -spec: - group: monitoring.grafana.com - names: - categories: - - agent-operator - kind: PodLogs - listKind: PodLogsList - plural: podlogs - singular: podlogs - scope: Namespaced - versions: - - name: v1alpha1 - schema: - openAPIV3Schema: - description: PodLogs defines how to collect logs for a pod. - properties: - apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' - type: string - kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' - type: string - metadata: - type: object - spec: - description: Spec holds the specification of the desired behavior for - the PodLogs. - properties: - jobLabel: - description: The label to use to retrieve the job name from. - type: string - namespaceSelector: - description: Selector to select which namespaces the Pod objects are - discovered from. - properties: - any: - description: Boolean describing whether all namespaces are selected - in contrast to a list restricting them. - type: boolean - matchNames: - description: List of namespace names to select from. - items: - type: string - type: array - type: object - pipelineStages: - description: Pipeline stages for this pod. Pipeline stages support - transforming and filtering log lines. - items: - description: "PipelineStageSpec defines an individual pipeline stage. - Each stage type is mutually exclusive and no more than one may - be set per stage. \n More information on pipelines can be found - in the Promtail documentation: https://grafana.com/docs/loki/latest/clients/promtail/pipelines/" - properties: - cri: - description: 'CRI is a parsing stage that reads log lines using - the standard CRI logging format. Supply cri: {} to enable.' - type: object - docker: - description: 'Docker is a parsing stage that reads log lines - using the standard Docker logging format. Supply docker: {} - to enable.' - type: object - drop: - description: Drop is a filtering stage that lets you drop certain - logs. - properties: - dropCounterReason: - description: Every time a log line is dropped, the metric - logentry_dropped_lines_total is incremented. A "reason" - label is added, and can be customized by providing a custom - value here. Defaults to "drop_stage". - type: string - expression: - description: "RE2 regular expression. \n If source is provided, - the regex attempts to match the source. \n If no source - is provided, then the regex attempts to attach the log - line. \n If the provided regex matches the log line or - a provided source, the line is dropped." - type: string - longerThan: - description: LongerThan will drop a log line if it its content - is longer than this value (in bytes). Can be expressed - as an integer (8192) or a number with a suffix (8kb). - type: string - olderThan: - description: OlderThan will be parsed as a Go duration. - If the log line's timestamp is older than the current - time minus the provided duration, it will be dropped. - type: string - source: - description: Name from the extract data to parse. If empty, - uses the log message. - type: string - value: - description: "Value can only be specified when source is - specified. If the value provided is an exact match for - the given source then the line will be dropped. \n Mutually - exclusive with expression." - type: string - type: object - json: - description: "JSON is a parsing stage that reads the log line - as JSON and accepts JMESPath expressions to extract data. - \n Information on JMESPath: http://jmespath.org/" - properties: - expressions: - additionalProperties: - type: string - description: "Set of the key/value pairs of JMESPath expressions. - The key will be the key in the extracted data while the - expression will be the value, evaluated as a JMESPath - from the source data. \n Literal JMESPath expressions - can be used by wrapping a key in double quotes, which - then must be wrapped again in single quotes in YAML so - they get passed to the JMESPath parser." - type: object - source: - description: Name from the extracted data to parse as JSON. - If empty, uses entire log message. - type: string - type: object - labelAllow: - description: LabelAllow is an action stage that only allows - the provided labels to be included in the label set that is - sent to Loki with the log entry. - items: - type: string - type: array - labelDrop: - description: LabelDrop is an action stage that drops labels - from the label set that is sent to Loki with the log entry. - items: - type: string - type: array - labels: - additionalProperties: - type: string - description: "Labels is an action stage that takes data from - the extracted map and modifies the label set that is sent - to Loki with the log entry. \n The key is REQUIRED and represents - the name for the label that will be created. Value is optional - and will be the name from extracted data to use for the value - of the label. If the value is not provided, it defaults to - match the key." - type: object - limit: - description: Limit is a rate-limiting stage that throttles logs - based on several options. - properties: - burst: - description: The cap in the quantity of burst lines that - Promtail will push to Loki. - type: integer - drop: - description: "When drop is true, log lines that exceed the - current rate limit are discarded. When drop is false, - log lines that exceed the current rate limit wait to enter - the back pressure mode. \n Defaults to false." - type: boolean - rate: - description: The rate limit in lines per second that Promtail - will push to Loki. - type: integer - type: object - match: - description: Match is a filtering stage that conditionally applies - a set of stages or drop entries when a log entry matches a - configurable LogQL stream selector and filter expressions. - properties: - action: - description: Determines what action is taken when the selector - matches the log line. Can be keep or drop. Defaults to - keep. When set to drop, entries are dropped and no later - metrics are recorded. Stages must be empty when dropping - metrics. - type: string - dropCounterReason: - description: Every time a log line is dropped, the metric - logentry_dropped_lines_total is incremented. A "reason" - label is added, and can be customized by providing a custom - value here. Defaults to "match_stage." - type: string - pipelineName: - description: Names the pipeline. When defined, creates an - additional label in the pipeline_duration_seconds histogram, - where the value is concatenated with job_name using an - underscore. - type: string - selector: - description: LogQL stream selector and filter expressions. - Required. - type: string - stages: - description: "Nested set of pipeline stages to execute when - action is keep and the log line matches selector. \n An - example value for stages may be: \n stages: | - json: - {} - labelAllow: [foo, bar] \n Note that stages is a string - because SIG API Machinery does not support recursive types, - and so it cannot be validated for correctness. Be careful - not to mistype anything." - type: string - required: - - selector - type: object - metrics: - additionalProperties: - description: MetricsStageSpec is an action stage that allows - for defining and updating metrics based on data from the - extracted map. Created metrics are not pushed to Loki or - Prometheus and are instead exposed via the /metrics endpoint - of the Grafana Agent pod. The Grafana Agent Operator should - be configured with a MetricsInstance that discovers the - logging DaemonSet to collect metrics created by this stage. - properties: - action: - description: "The action to take against the metric. Required. - \n Must be either \"inc\" or \"add\" for type: counter - or type: histogram. When type: gauge, must be one of - \"set\", \"inc\", \"dec\", \"add\", or \"sub\". \n \"add\", - \"set\", or \"sub\" requires the extracted value to - be convertible to a positive float." - type: string - buckets: - description: 'Buckets to create. Bucket values must be - convertible to float64s. Extremely large or small numbers - are subject to some loss of precision. Only valid for - type: histogram.' - items: - type: string - type: array - countEntryBytes: - description: "If true all log line bytes are counted. - Can only be set with matchAll: true and action: add. - \n Only valid for type: counter." - type: boolean - description: - description: Sets the description for the created metric. - type: string - matchAll: - description: "If true, all log lines are counted without - attempting to match the source to the extracted map. - Mutually exclusive with value. \n Only valid for type: - counter." - type: boolean - maxIdleDuration: - description: "Label values on metrics are dynamic which - can cause exported metrics to go stale. To prevent unbounded - cardinality, any metrics not updated within MaxIdleDuration - are removed. \n Must be greater or equal to 1s. Defaults - to 5m." - type: string - prefix: - description: Sets the custom prefix name for the metric. - Defaults to "promtail_custom_". - type: string - source: - description: Key from the extracted data map to use for - the metric. Defaults to the metrics name if not present. - type: string - type: - description: The metric type to create. Must be one of - counter, gauge, histogram. Required. - type: string - value: - description: Filters down source data and only changes - the metric if the targeted value matches the provided - string exactly. If not present, all data matches. - type: string - required: - - action - - type - type: object - description: Metrics is an action stage that supports defining - and updating metrics based on data from the extracted map. - Created metrics are not pushed to Loki or Prometheus and are - instead exposed via the /metrics endpoint of the Grafana Agent - pod. The Grafana Agent Operator should be configured with - a MetricsInstance that discovers the logging DaemonSet to - collect metrics created by this stage. - type: object - multiline: - description: Multiline stage merges multiple lines into a multiline - block before passing it on to the next stage in the pipeline. - properties: - firstLine: - description: RE2 regular expression. Creates a new multiline - block when matched. Required. - type: string - maxLines: - description: Maximum number of lines a block can have. A - new block is started if the number of lines surpasses - this value. Defaults to 128. - type: integer - maxWaitTime: - description: Maximum time to wait before passing on the - multiline block to the next stage if no new lines are - received. Defaults to 3s. - type: string - required: - - firstLine - type: object - output: - description: Output stage is an action stage that takes data - from the extracted map and changes the log line that will - be sent to Loki. - properties: - source: - description: Name from extract data to use for the log entry. - Required. - type: string - required: - - source - type: object - pack: - description: Pack is a transform stage that lets you embed extracted - values and labels into the log line by packing the log line - and labels inside of a JSON object. - properties: - ingestTimestamp: - description: If the resulting log line should use any existing - timestamp or use time.Now() when the line was created. - Set to true when combining several log streams from different - containers to avoid out of order errors. - type: boolean - labels: - description: Name from extracted data or line labels. Required. - Labels provided here are automatically removed from output - labels. - items: - type: string - type: array - required: - - labels - type: object - regex: - description: Regex is a parsing stage that parses a log line - using a regular expression. Named capture groups in the regex - allows for adding data into the extracted map. - properties: - expression: - description: RE2 regular expression. Each capture group - MUST be named. Required. - type: string - source: - description: Name from extracted data to parse. If empty, - defaults to using the log message. - type: string - required: - - expression - type: object - replace: - description: Replace is a parsing stage that parses a log line - using a regular expression and replaces the log line. Named - capture groups in the regex allows for adding data into the - extracted map. - properties: - expression: - description: RE2 regular expression. Each capture group - MUST be named. Required. - type: string - replace: - description: Value to replace the captured group with. - type: string - source: - description: Name from extracted data to parse. If empty, - defaults to using the log message. - type: string - required: - - expression - type: object - template: - description: Template is a transform stage that manipulates - the values in the extracted map using Go's template syntax. - properties: - source: - description: Name from extracted data to parse. Required. - If empty, defaults to using the log message. - type: string - template: - description: Go template string to use. Required. In addition - to normal template functions, ToLower, ToUpper, Replace, - Trim, TrimLeft, TrimRight, TrimPrefix, and TrimSpace are - also available. - type: string - required: - - source - - template - type: object - tenant: - description: Tenant is an action stage that sets the tenant - ID for the log entry picking it from a field in the extracted - data map. If the field is missing, the default LogsClientSpec.tenantId - will be used. - properties: - label: - description: Name from labels whose value should be set - as tenant ID. Mutually exclusive with source and value. - type: string - source: - description: Name from extracted data to use as the tenant - ID. Mutually exclusive with label and value. - type: string - value: - description: Value to use for the template ID. Useful when - this stage is used within a conditional pipeline such - as match. Mutually exclusive with label and source. - type: string - type: object - timestamp: - description: Timestamp is an action stage that can change the - timestamp of a log line before it is sent to Loki. If not - present, the timestamp of a log line defaults to the time - when the log line was read. - properties: - actionOnFailure: - description: Action to take when the timestamp can't be - extracted or parsed. Can be skip or fudge. Defaults to - fudge. - type: string - fallbackFormats: - description: Fallback formats to try if format fails. - items: - type: string - type: array - format: - description: 'Determines format of the time string. Required. - Can be one of: ANSIC, UnixDate, RubyDate, RFC822, RFC822Z, - RFC850, RFC1123, RFC1123Z, RFC3339, RFC3339Nano, Unix, - UnixMs, UnixUs, UnixNs.' - type: string - location: - description: IANA Timezone Database string. - type: string - source: - description: Name from extracted data to use as the timestamp. - Required. - type: string - required: - - format - - source - type: object - type: object - type: array - podTargetLabels: - description: PodTargetLabels transfers labels on the Kubernetes Pod - onto the target. - items: - type: string - type: array - relabelings: - description: "RelabelConfigs to apply to logs before delivering. Grafana - Agent Operator automatically adds relabelings for a few standard - Kubernetes fields and replaces original scrape job name with __tmp_logs_job_name. - \n More info: https://grafana.com/docs/loki/latest/clients/promtail/configuration/#relabel_configs" - items: - description: 'RelabelConfig allows dynamic rewriting of the label - set, being applied to samples before ingestion. It defines ``-section - of Prometheus configuration. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs' - properties: - action: - default: replace - description: Action to perform based on regex matching. Default - is 'replace'. uppercase and lowercase actions require Prometheus - >= 2.36. - enum: - - replace - - Replace - - keep - - Keep - - drop - - Drop - - hashmod - - HashMod - - labelmap - - LabelMap - - labeldrop - - LabelDrop - - labelkeep - - LabelKeep - - lowercase - - Lowercase - - uppercase - - Uppercase - - keepequal - - KeepEqual - - dropequal - - DropEqual - type: string - modulus: - description: Modulus to take of the hash of the source label - values. - format: int64 - type: integer - regex: - description: Regular expression against which the extracted - value is matched. Default is '(.*)' - type: string - replacement: - description: Replacement value against which a regex replace - is performed if the regular expression matches. Regex capture - groups are available. Default is '$1' - type: string - separator: - description: Separator placed between concatenated source label - values. default is ';'. - type: string - sourceLabels: - description: The source labels select values from existing labels. - Their content is concatenated using the configured separator - and matched against the configured regular expression for - the replace, keep, and drop actions. - items: - description: LabelName is a valid Prometheus label name which - may only contain ASCII letters, numbers, as well as underscores. - pattern: ^[a-zA-Z_][a-zA-Z0-9_]*$ - type: string - type: array - targetLabel: - description: Label to which the resulting value is written in - a replace action. It is mandatory for replace actions. Regex - capture groups are available. - type: string - type: object - type: array - selector: - description: Selector to select Pod objects. Required. - properties: - matchExpressions: - description: matchExpressions is a list of label selector requirements. - The requirements are ANDed. - items: - description: A label selector requirement is a selector that - contains values, a key, and an operator that relates the key - and values. - properties: - key: - description: key is the label key that the selector applies - to. - type: string - operator: - description: operator represents a key's relationship to - a set of values. Valid operators are In, NotIn, Exists - and DoesNotExist. - type: string - values: - description: values is an array of string values. If the - operator is In or NotIn, the values array must be non-empty. - If the operator is Exists or DoesNotExist, the values - array must be empty. This array is replaced during a strategic - merge patch. - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - description: matchLabels is a map of {key,value} pairs. A single - {key,value} in the matchLabels map is equivalent to an element - of matchExpressions, whose key field is "key", the operator - is "In", and the values array contains only "value". The requirements - are ANDed. - type: object - type: object - x-kubernetes-map-type: atomic - required: - - selector - type: object - type: object - served: true - storage: true diff --git a/production/operator/templates/agent-operator.yaml b/production/operator/templates/agent-operator.yaml deleted file mode 100644 index 442bab4fa353..000000000000 --- a/production/operator/templates/agent-operator.yaml +++ /dev/null @@ -1,645 +0,0 @@ -apiVersion: v1 -kind: ServiceAccount -metadata: - name: grafana-agent - namespace: ${NAMESPACE} ---- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: grafana-agent-operator - namespace: ${NAMESPACE} ---- -apiVersion: v1 -automountServiceAccountToken: false -kind: ServiceAccount -metadata: - labels: - app.kubernetes.io/component: exporter - app.kubernetes.io/name: kube-state-metrics - app.kubernetes.io/version: 2.5.0 - name: kube-state-metrics - namespace: ${NAMESPACE} ---- -apiVersion: v1 -data: {} -kind: Secret -metadata: - name: logs-secret - namespace: ${NAMESPACE} -stringData: - password: ${LOGS_KEY} - username: ${LOGS_USER} -type: Opaque ---- -apiVersion: v1 -data: {} -kind: Secret -metadata: - name: metrics-secret - namespace: ${NAMESPACE} -stringData: - password: ${METRICS_KEY} - username: ${METRICS_USER} -type: Opaque ---- -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: agent-eventhandler - namespace: ${NAMESPACE} -spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 1Gi ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: grafana-agent -rules: -- apiGroups: - - "" - resources: - - nodes - - nodes/proxy - - nodes/metrics - - services - - endpoints - - pods - - events - verbs: - - get - - list - - watch -- apiGroups: - - networking.k8s.io - resources: - - ingresses - verbs: - - get - - list - - watch -- nonResourceURLs: - - /metrics - - /metrics/cadvisor - verbs: - - get ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: grafana-agent-operator -rules: -- apiGroups: - - monitoring.grafana.com - resources: - - grafanaagents - - metricsinstances - - logsinstances - - podlogs - - integrations - verbs: - - get - - list - - watch -- apiGroups: - - monitoring.grafana.com - resources: - - grafanaagents/finalizers - - metricsinstances/finalizers - - logsinstances/finalizers - - podlogs/finalizers - - integrations/finalizers - verbs: - - get - - list - - watch - - update -- apiGroups: - - monitoring.coreos.com - resources: - - podmonitors - - probes - - servicemonitors - verbs: - - get - - list - - watch -- apiGroups: - - monitoring.coreos.com - resources: - - podmonitors/finalizers - - probes/finalizers - - servicemonitors/finalizers - verbs: - - get - - list - - watch - - update -- apiGroups: - - "" - resources: - - namespaces - - nodes - verbs: - - get - - list - - watch -- apiGroups: - - "" - resources: - - secrets - - services - - configmaps - - endpoints - verbs: - - get - - list - - watch - - create - - update - - patch - - delete -- apiGroups: - - apps - resources: - - statefulsets - - daemonsets - - deployments - verbs: - - get - - list - - watch - - create - - update - - patch - - delete ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - labels: - app.kubernetes.io/component: exporter - app.kubernetes.io/name: kube-state-metrics - app.kubernetes.io/version: 2.5.0 - name: kube-state-metrics -rules: -- apiGroups: - - "" - resources: - - configmaps - - secrets - - nodes - - pods - - services - - resourcequotas - - replicationcontrollers - - limitranges - - persistentvolumeclaims - - persistentvolumes - - namespaces - - endpoints - verbs: - - list - - watch -- apiGroups: - - apps - resources: - - statefulsets - - daemonsets - - deployments - - replicasets - verbs: - - list - - watch -- apiGroups: - - batch - resources: - - cronjobs - - jobs - verbs: - - list - - watch -- apiGroups: - - autoscaling - resources: - - horizontalpodautoscalers - verbs: - - list - - watch -- apiGroups: - - authentication.k8s.io - resources: - - tokenreviews - verbs: - - create -- apiGroups: - - authorization.k8s.io - resources: - - subjectaccessreviews - verbs: - - create -- apiGroups: - - policy - resources: - - poddisruptionbudgets - verbs: - - list - - watch -- apiGroups: - - certificates.k8s.io - resources: - - certificatesigningrequests - verbs: - - list - - watch -- apiGroups: - - storage.k8s.io - resources: - - storageclasses - - volumeattachments - verbs: - - list - - watch -- apiGroups: - - admissionregistration.k8s.io - resources: - - mutatingwebhookconfigurations - - validatingwebhookconfigurations - verbs: - - list - - watch -- apiGroups: - - networking.k8s.io - resources: - - networkpolicies - - ingresses - verbs: - - list - - watch -- apiGroups: - - coordination.k8s.io - resources: - - leases - verbs: - - list - - watch ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: grafana-agent -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: grafana-agent -subjects: -- kind: ServiceAccount - name: grafana-agent - namespace: ${NAMESPACE} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: grafana-agent-operator -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: grafana-agent-operator -subjects: -- kind: ServiceAccount - name: grafana-agent-operator - namespace: ${NAMESPACE} ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - labels: - app.kubernetes.io/component: exporter - app.kubernetes.io/name: kube-state-metrics - app.kubernetes.io/version: 2.5.0 - name: kube-state-metrics -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: ClusterRole - name: kube-state-metrics -subjects: -- kind: ServiceAccount - name: kube-state-metrics - namespace: ${NAMESPACE} ---- -apiVersion: v1 -kind: Service -metadata: - labels: - app.kubernetes.io/component: exporter - app.kubernetes.io/name: kube-state-metrics - app.kubernetes.io/version: 2.5.0 - name: kube-state-metrics - namespace: ${NAMESPACE} -spec: - clusterIP: None - ports: - - name: http-metrics - port: 8080 - targetPort: http-metrics - - name: telemetry - port: 8081 - targetPort: telemetry - selector: - app.kubernetes.io/name: kube-state-metrics ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: grafana-agent-operator - namespace: ${NAMESPACE} -spec: - minReadySeconds: 10 - replicas: 1 - revisionHistoryLimit: 10 - selector: - matchLabels: - name: grafana-agent-operator - template: - metadata: - labels: - name: grafana-agent-operator - spec: - containers: - - args: - - --kubelet-service=default/kubelet - image: grafana/agent-operator:v0.39.0 - imagePullPolicy: IfNotPresent - name: grafana-agent-operator - serviceAccount: grafana-agent-operator ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - labels: - app.kubernetes.io/component: exporter - app.kubernetes.io/name: kube-state-metrics - app.kubernetes.io/version: 2.5.0 - name: kube-state-metrics - namespace: ${NAMESPACE} -spec: - replicas: 1 - selector: - matchLabels: - app.kubernetes.io/name: kube-state-metrics - template: - metadata: - labels: - app.kubernetes.io/component: exporter - app.kubernetes.io/name: kube-state-metrics - app.kubernetes.io/version: 2.5.0 - spec: - automountServiceAccountToken: true - containers: - - image: registry.k8s.io/kube-state-metrics/kube-state-metrics:v2.5.0 - livenessProbe: - httpGet: - path: /healthz - port: 8080 - initialDelaySeconds: 5 - timeoutSeconds: 5 - name: kube-state-metrics - ports: - - containerPort: 8080 - name: http-metrics - - containerPort: 8081 - name: telemetry - readinessProbe: - httpGet: - path: / - port: 8081 - initialDelaySeconds: 5 - timeoutSeconds: 5 - securityContext: - allowPrivilegeEscalation: false - capabilities: - drop: - - ALL - readOnlyRootFilesystem: true - runAsUser: 65534 - nodeSelector: - kubernetes.io/os: linux - serviceAccountName: kube-state-metrics ---- -apiVersion: monitoring.grafana.com/v1alpha1 -kind: GrafanaAgent -metadata: - name: grafana-agent - namespace: ${NAMESPACE} -spec: - image: grafana/agent:v0.39.0 - integrations: - selector: - matchLabels: - agent: grafana-agent - logs: - instanceSelector: - matchLabels: - agent: grafana-agent - metrics: - externalLabels: - cluster: ${CLUSTER} - instanceSelector: - matchLabels: - agent: grafana-agent - serviceAccountName: grafana-agent ---- -apiVersion: monitoring.grafana.com/v1alpha1 -kind: Integration -metadata: - labels: - agent: grafana-agent - name: agent-eventhandler - namespace: ${NAMESPACE} -spec: - config: - cache_path: /etc/eventhandler/eventhandler.cache - logs_instance: ${NAMESPACE}/grafana-agent-logs - name: eventhandler - type: - unique: true - volumeMounts: - - mountPath: /etc/eventhandler - name: agent-eventhandler - volumes: - - name: agent-eventhandler - persistentVolumeClaim: - claimName: agent-eventhandler ---- -apiVersion: monitoring.grafana.com/v1alpha1 -kind: LogsInstance -metadata: - labels: - agent: grafana-agent - name: grafana-agent-logs - namespace: ${NAMESPACE} -spec: - clients: - - basicAuth: - password: - key: password - name: logs-secret - username: - key: username - name: logs-secret - externalLabels: - cluster: ${CLUSTER} - url: ${LOGS_URL} - podLogsNamespaceSelector: {} - podLogsSelector: - matchLabels: - instance: primary ---- -apiVersion: monitoring.grafana.com/v1alpha1 -kind: MetricsInstance -metadata: - labels: - agent: grafana-agent - name: grafana-agent-metrics - namespace: ${NAMESPACE} -spec: - remoteWrite: - - basicAuth: - password: - key: password - name: metrics-secret - username: - key: username - name: metrics-secret - url: ${METRICS_URL} - serviceMonitorNamespaceSelector: {} - serviceMonitorSelector: - matchLabels: - instance: primary ---- -apiVersion: monitoring.grafana.com/v1alpha1 -kind: PodLogs -metadata: - labels: - instance: primary - name: kubernetes-logs - namespace: ${NAMESPACE} -spec: - namespaceSelector: - any: true - pipelineStages: - - cri: {} - relabelings: - - sourceLabels: - - __meta_kubernetes_pod_node_name - targetLabel: __host__ - - action: replace - sourceLabels: - - __meta_kubernetes_namespace - targetLabel: namespace - - action: replace - sourceLabels: - - __meta_kubernetes_pod_name - targetLabel: pod - - action: replace - sourceLabels: - - __meta_kubernetes_pod_container_name - targetLabel: container - - replacement: /var/log/pods/*$1/*.log - separator: / - sourceLabels: - - __meta_kubernetes_pod_uid - - __meta_kubernetes_pod_container_name - targetLabel: __path__ - selector: - matchLabels: {} ---- -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - labels: - instance: primary - name: cadvisor-monitor - namespace: ${NAMESPACE} -spec: - endpoints: - - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token - honorLabels: true - interval: 60s - path: /metrics/cadvisor - port: https-metrics - relabelings: - - sourceLabels: - - __metrics_path__ - targetLabel: metrics_path - - action: replace - replacement: cadvisor - targetLabel: job - scheme: https - tlsConfig: - insecureSkipVerify: true - namespaceSelector: - matchNames: - - default - selector: - matchLabels: - app.kubernetes.io/name: kubelet ---- -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - labels: - instance: primary - name: ksm-monitor - namespace: ${NAMESPACE} -spec: - endpoints: - - honorLabels: true - interval: 60s - path: /metrics - port: http-metrics - relabelings: - - action: replace - replacement: kube-state-metrics - targetLabel: job - namespaceSelector: - matchNames: - - ${NAMESPACE} - selector: - matchLabels: - app.kubernetes.io/name: kube-state-metrics ---- -apiVersion: monitoring.coreos.com/v1 -kind: ServiceMonitor -metadata: - labels: - instance: primary - name: kubelet-monitor - namespace: ${NAMESPACE} -spec: - endpoints: - - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token - honorLabels: true - interval: 60s - path: /metrics - port: https-metrics - relabelings: - - sourceLabels: - - __metrics_path__ - targetLabel: metrics_path - - action: replace - replacement: kubelet - targetLabel: job - scheme: https - tlsConfig: - insecureSkipVerify: true - namespaceSelector: - matchNames: - - default - selector: - matchLabels: - app.kubernetes.io/name: kubelet diff --git a/production/tanka/grafana-agent-operator/jsonnetfile.json b/production/tanka/grafana-agent-operator/jsonnetfile.json deleted file mode 100644 index bb15a4133cc2..000000000000 --- a/production/tanka/grafana-agent-operator/jsonnetfile.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "dependencies": [ - { - "name": "ksonnet-util", - "source": { - "git": { - "remote": "https://github.com/grafana/jsonnet-libs", - "subdir": "ksonnet-util" - } - }, - "version": "master" - }, - { - "name": "agent-operator-gen", - "source": { - "git": { - "remote": "https://github.com/jsonnet-libs/grafana-agent-libsonnet.git", - "subdir": "0.26" - } - }, - "version": "main" - }, - { - "name": "prom-operator-gen", - "source": { - "git": { - "remote": "https://github.com/jsonnet-libs/prometheus-operator-libsonnet.git", - "subdir": "0.57" - } - }, - "version": "main" - } - ] -} diff --git a/production/tanka/grafana-agent-operator/operator.libsonnet b/production/tanka/grafana-agent-operator/operator.libsonnet deleted file mode 100644 index 71c2fb8264c9..000000000000 --- a/production/tanka/grafana-agent-operator/operator.libsonnet +++ /dev/null @@ -1,60 +0,0 @@ -{ - new(name='grafana-agent-operator', namespace='', image='grafana/agent-operator:v0.26.0-rc.0', serviceAccount=''):: { - local k = (import 'ksonnet-util/kausal.libsonnet'), - - local container = k.core.v1.container, - local deployment = k.apps.v1.deployment, - - local this = self, - - container:: - container.new(name, image) + - container.withArgsMixin(k.util.mapToFlags({'-kubelet-service': 'default/kubelet'})), - - controller: - deployment.new(name, 1, [this.container]) + - deployment.mixin.metadata.withNamespace(namespace) + - deployment.mixin.spec.template.spec.withServiceAccount(name), - - }, - - withRbac(name, namespace):: { - local k = (import 'ksonnet-util/kausal.libsonnet') { _config+:: { namespace: namespace } }, - local policyRule = k.rbac.v1.policyRule, - local serviceAccount = k.core.v1.serviceAccount, - - rbac: - k.util.rbac(name, [ - policyRule.withApiGroups(['monitoring.grafana.com']) + - policyRule.withResources(['grafanaagents', 'metricsinstances', 'logsinstances', 'podlogs', 'integrations']) + - policyRule.withVerbs(['get', 'list', 'watch']), - - policyRule.withApiGroups(['monitoring.grafana.com']) + - policyRule.withResources(['grafanaagents/finalizers', 'metricsinstances/finalizers', 'logsinstances/finalizers', 'podlogs/finalizers', 'integrations/finalizers']) + - policyRule.withVerbs(['get', 'list', 'watch', 'update']), - - policyRule.withApiGroups(['monitoring.coreos.com']) + - policyRule.withResources(['podmonitors', 'probes', 'servicemonitors']) + - policyRule.withVerbs(['get', 'list', 'watch']), - - policyRule.withApiGroups(['monitoring.coreos.com']) + - policyRule.withResources(['podmonitors/finalizers', 'probes/finalizers', 'servicemonitors/finalizers']) + - policyRule.withVerbs(['get', 'list', 'watch', 'update']), - - policyRule.withApiGroups(['']) + - policyRule.withResources(['namespaces', 'nodes']) + - policyRule.withVerbs(['get', 'list', 'watch']), - - policyRule.withApiGroups(['']) + - policyRule.withResources(['secrets', 'services', 'configmaps', 'endpoints']) + - policyRule.withVerbs(['get', 'list', 'watch', 'create', 'update', 'patch', 'delete']), - - policyRule.withApiGroups(['apps']) + - policyRule.withResources(['statefulsets', 'daemonsets', 'deployments']) + - policyRule.withVerbs(['get', 'list', 'watch', 'create', 'update', 'patch', 'delete']), - - ]) { - service_account+: serviceAccount.mixin.metadata.withNamespace(namespace), - }, - } -} diff --git a/production/tanka/grafana-agent-operator/util/grafana-agent.libsonnet b/production/tanka/grafana-agent-operator/util/grafana-agent.libsonnet deleted file mode 100644 index d5edf3ac7bd5..000000000000 --- a/production/tanka/grafana-agent-operator/util/grafana-agent.libsonnet +++ /dev/null @@ -1,23 +0,0 @@ -{ - withRbac(name, namespace):: { - local k = (import 'ksonnet-util/kausal.libsonnet') + { _config+:: { namespace: namespace } }, - local policyRule = k.rbac.v1.policyRule, - local serviceAccount = k.core.v1.serviceAccount, - - rbac: - k.util.rbac(name, [ - policyRule.withApiGroups(['']) + - policyRule.withResources(['nodes', 'nodes/proxy', 'nodes/metrics', 'services', 'endpoints', 'pods', 'events']) + - policyRule.withVerbs(['get', 'list', 'watch']), - - policyRule.withApiGroups(['networking.k8s.io']) + - policyRule.withResources(['ingresses']) + - policyRule.withVerbs(['get', 'list', 'watch']), - - policyRule.withNonResourceURLs(['/metrics', '/metrics/cadvisor']) + - policyRule.withVerbs(['get']), - ]) { - service_account+: serviceAccount.mixin.metadata.withNamespace(namespace), - }, - } -} diff --git a/production/tanka/grafana-agent-operator/util/integrations.libsonnet b/production/tanka/grafana-agent-operator/util/integrations.libsonnet deleted file mode 100644 index 04161e8a29ec..000000000000 --- a/production/tanka/grafana-agent-operator/util/integrations.libsonnet +++ /dev/null @@ -1,17 +0,0 @@ -local gen = import 'agent-operator-gen/main.libsonnet'; -local int = gen.monitoring.v1alpha1.integration; - -{ - withPVC(name):: { - spec+: { - volumeMounts: [ - int.spec.volumeMounts.withName(name) + - int.spec.volumeMounts.withMountPath('/etc/eventhandler') - ], - volumes: [ - int.spec.volumes.withName(name) + - int.spec.volumes.persistentVolumeClaim.withClaimName(name) - ] - } - } -} diff --git a/production/tanka/grafana-agent-operator/util/k8slogs.libsonnet b/production/tanka/grafana-agent-operator/util/k8slogs.libsonnet deleted file mode 100644 index 93d4b9e2104c..000000000000 --- a/production/tanka/grafana-agent-operator/util/k8slogs.libsonnet +++ /dev/null @@ -1,33 +0,0 @@ -local gen = import 'agent-operator-gen/main.libsonnet'; -local pl = gen.monitoring.v1alpha1.podLogs; -local r = pl.spec.relabelings; - -{ - withK8sLogsRelabeling():: [ - r.withSourceLabels(['__meta_kubernetes_pod_node_name']) + - r.withTargetLabel('__host__'), - - // r.withAction('replace') + - // r.withReplacement('$1') + - // r.withSeparator('/') + - // r.withSourceLabels(['__meta_kubernetes_namespace', '__meta_kubernetes_pod_name']) + - // r.withTargetLabel('job'), - - r.withAction('replace') + - r.withSourceLabels('__meta_kubernetes_namespace') + - r.withTargetLabel('namespace'), - - r.withAction('replace') + - r.withSourceLabels('__meta_kubernetes_pod_name') + - r.withTargetLabel('pod'), - - r.withAction('replace') + - r.withSourceLabels('__meta_kubernetes_pod_container_name') + - r.withTargetLabel('container'), - - r.withReplacement('/var/log/pods/*$1/*.log') + - r.withSeparator('/') + - r.withSourceLabels(['__meta_kubernetes_pod_uid', '__meta_kubernetes_pod_container_name']) + - r.withTargetLabel('__path__') - ] -} diff --git a/production/tanka/grafana-agent-operator/util/k8smonitors.libsonnet b/production/tanka/grafana-agent-operator/util/k8smonitors.libsonnet deleted file mode 100644 index 90de24a88962..000000000000 --- a/production/tanka/grafana-agent-operator/util/k8smonitors.libsonnet +++ /dev/null @@ -1,56 +0,0 @@ -local prom_gen = import 'prom-operator-gen/main.libsonnet'; -local sm = prom_gen.monitoring.v1.serviceMonitor; -local e = sm.spec.endpoints; -local mr = e.metricRelabelings; -local r = e.relabelings; - -{ - local metricArrayToString(arr) = std.join("|", arr), - - local withJobReplace(job_label) = - r.withAction('replace') + - r.withTargetLabel('job') + - r.withReplacement(job_label), - - local withAllowList(metrics) = - mr.withAction('keep') + - mr.withSourceLabels(['__name__']) + - mr.withRegex(metricArrayToString(metrics)), - - local withMetricsPath() = - r.withSourceLabels(['__metrics_path__']) + - r.withTargetLabel('metrics_path'), - - local withDefaultEndpoint(jobLabel, port, allowlist, allowlistMetrics, path) = - e.withHonorLabels(true) + - e.withInterval('60s') + - (if allowlist then e.withMetricRelabelings(withAllowList(allowlistMetrics)) else {}) + - e.withPort(port) + - e.withPath(path), - - - newKubernetesMonitor(name, namespace, monitorLabels, targetNamespace, targetLabels, jobLabel, metricsPath, allowlist=false, allowlistMetrics=[]):: - sm.new(name) + - sm.metadata.withNamespace(namespace) + - sm.metadata.withLabels(monitorLabels) + - sm.spec.namespaceSelector.withMatchNames(targetNamespace) + - sm.spec.selector.withMatchLabels(targetLabels) + - sm.spec.withEndpoints([ - withDefaultEndpoint(jobLabel, 'https-metrics', allowlist, allowlistMetrics, metricsPath) + - e.withBearerTokenFile('/var/run/secrets/kubernetes.io/serviceaccount/token') + - e.tlsConfig.withInsecureSkipVerify(true) + - e.withRelabelings([withMetricsPath(), withJobReplace(jobLabel)]) + - e.withScheme('https') - ]), - - newServiceMonitor(name, namespace, monitorLabels, targetNamespace, targetLabels, jobLabel, metricsPath, allowlist=false, allowlistMetrics=[]):: - sm.new(name) + - sm.metadata.withNamespace(namespace) + - sm.metadata.withLabels(monitorLabels) + - sm.spec.namespaceSelector.withMatchNames(targetNamespace) + - sm.spec.selector.withMatchLabels(targetLabels) + - sm.spec.withEndpoints([ - withDefaultEndpoint(jobLabel, 'http-metrics', allowlist, allowlistMetrics, metricsPath) + - e.withRelabelings([withJobReplace(jobLabel)]) - ]), -} diff --git a/production/tanka/grafana-agent-operator/util/logsinstance.libsonnet b/production/tanka/grafana-agent-operator/util/logsinstance.libsonnet deleted file mode 100644 index 4f667c14f5f0..000000000000 --- a/production/tanka/grafana-agent-operator/util/logsinstance.libsonnet +++ /dev/null @@ -1,21 +0,0 @@ -local gen = import 'agent-operator-gen/main.libsonnet'; -local li = gen.monitoring.v1alpha1.logsInstance; -local clients = li.spec.clients; - -{ - withLogsClient(secretName, logsUrl, externalLabels={}):: - li.spec.withClients( - clients.withUrl(logsUrl) + - clients.basicAuth.username.withKey('username') + - clients.basicAuth.username.withName(secretName) + - clients.basicAuth.password.withKey('password') + - clients.basicAuth.password.withName(secretName) + - if externalLabels != {} then clients.withExternalLabels(externalLabels) else {} - ), - - withNilPodLogsNamespace():: { - spec+: { - podLogsNamespaceSelector: {} - } - }, -} diff --git a/production/tanka/grafana-agent-operator/util/metricsinstance.libsonnet b/production/tanka/grafana-agent-operator/util/metricsinstance.libsonnet deleted file mode 100644 index af0da101fd46..000000000000 --- a/production/tanka/grafana-agent-operator/util/metricsinstance.libsonnet +++ /dev/null @@ -1,20 +0,0 @@ -local gen = import 'agent-operator-gen/main.libsonnet'; -local mi = gen.monitoring.v1alpha1.metricsInstance; -local rw = mi.spec.remoteWrite; - -{ - withRemoteWrite(secretName, metricsUrl):: - mi.spec.withRemoteWrite( - rw.withUrl(metricsUrl) + - rw.basicAuth.username.withKey('username') + - rw.basicAuth.username.withName(secretName) + - rw.basicAuth.password.withKey('password') + - rw.basicAuth.password.withName(secretName) - ), - - withNilServiceMonitorNamespace():: { - spec+: { - serviceMonitorNamespaceSelector: {} - } - } -} diff --git a/production/tanka/grafana-agent/config.libsonnet b/production/tanka/grafana-agent/config.libsonnet deleted file mode 100644 index 7c1e7a2c8c80..000000000000 --- a/production/tanka/grafana-agent/config.libsonnet +++ /dev/null @@ -1,117 +0,0 @@ -local k8s_v2 = import './v2/internal/helpers/k8s.libsonnet'; - -{ - _images+:: { - agent: 'grafana/agent:latest', - agentctl: 'grafana/agentctl:latest', - }, - - _config+:: { - // - // Deployment options - // - agent_cluster_role_name: 'grafana-agent', - agent_configmap_name: 'grafana-agent', - agent_deployment_configmap_name: self.agent_configmap_name + '-deployment', - agent_pod_name: 'grafana-agent', - agent_deployment_pod_name: self.agent_pod_name + '-deployment', - - cluster_dns_tld: 'local', - cluster_dns_suffix: 'cluster.' + self.cluster_dns_tld, - cluster_name: error 'must specify cluster name', - namespace: error 'must specify namespace', - - agent_config_hash_annotation: true, - - // - // Prometheus instance options - // - - // Enabling this causes the agent to only scrape metrics on the same node - // on which it is currently running. - // - // Take CAUTION when disabling this! If the agent is deployed - // as a DaemonSet (like it is here by default), then disabling this will - // scrape all metrics multiple times, once per node, leading to - // duplicate samples being rejected and might hit limits. - agent_host_filter: true, - - // The directory where the WAL is stored for all instances. - agent_wal_dir: '/var/lib/agent/data', - - prometheus_kubernetes_api_server_address: 'kubernetes.default.svc.%(cluster_dns_suffix)s:443' % self, - prometheus_insecure_skip_verify: false, - scrape_api_server_endpoints: true, - - // - // Config passed to the agent - // - // agent_config is rendered as a YAML and is the configuration file used - // to control the agent. A single instance is hard-coded and its - // scrape_configs are defined below. - // - // deployment_agent_config is a copy of `agent_config` that is used by the - // single-replica deployment to scrape jobs that don't work in host - // filtering mode. - agent_config: { - server: { - log_level: 'info', - }, - - metrics: { - global: { - scrape_interval: '1m', - }, - - wal_directory: $._config.agent_wal_dir, - - configs: [{ - name: 'agent', - - host_filter: $._config.agent_host_filter, - - scrape_configs: - if $._config.agent_host_filter then - $._config.kubernetes_scrape_configs - else - $._config.kubernetes_scrape_configs + $._config.deployment_scrape_configs, - remote_write: $._config.agent_remote_write, - }], - }, - }, - deployment_agent_config: self.agent_config { - prometheus+: { - configs: [{ - name: 'agent', - - host_filter: false, - - scrape_configs: $._config.deployment_scrape_configs, - remote_write: $._config.agent_remote_write, - }], - }, - - }, - - local all_scrape_configs = k8s_v2.metrics({ - scrape_api_server_endpoints: $._config.scrape_api_server_endpoints, - insecure_skip_verify: $._config.prometheus_insecure_skip_verify, - kubernetes_api_server_address: $._config.prometheus_kubernetes_api_server_address, - ksm_namespace: $._config.namespace, - node_exporter_namespace: $._config.namespace, - }), - - // We have two optional extension points for scrape config. One for the - // statefulset that holds all the agents attached to a node - // (kubernetes_scrape_configs) and One for the single replica deployment - // that is used to scrape jobs that don't work with host filtering mode - // (deployment_scrape_configs) the later is only used when host_filter = - // true. - deployment_scrape_configs: - std.filter(function(job) job.job_name == 'default/kubernetes', all_scrape_configs), - kubernetes_scrape_configs: - std.filter(function(job) job.job_name != 'default/kubernetes', all_scrape_configs), - - agent_remote_write: [], - }, -} diff --git a/production/tanka/grafana-agent/grafana-agent.libsonnet b/production/tanka/grafana-agent/grafana-agent.libsonnet deleted file mode 100644 index f280da77fcf9..000000000000 --- a/production/tanka/grafana-agent/grafana-agent.libsonnet +++ /dev/null @@ -1,85 +0,0 @@ -local config = import 'config.libsonnet'; -local k = import 'ksonnet-util/kausal.libsonnet'; - -k + config { - local configMap = $.core.v1.configMap, - local container = $.core.v1.container, - local daemonSet = $.apps.v1.daemonSet, - local deployment = $.apps.v1.deployment, - local policyRule = $.rbac.v1.policyRule, - local serviceAccount = $.core.v1.serviceAccount, - - agent_rbac: - $.util.rbac($._config.agent_cluster_role_name, [ - policyRule.withApiGroups(['']) + - policyRule.withResources(['nodes', 'nodes/proxy', 'services', 'endpoints', 'pods']) + - policyRule.withVerbs(['get', 'list', 'watch']), - - policyRule.withNonResourceUrls('/metrics') + - policyRule.withVerbs(['get']), - ]) { - service_account+: - serviceAccount.mixin.metadata.withNamespace($._config.namespace), - }, - - agent_config_map: - configMap.new($._config.agent_configmap_name) + - configMap.mixin.metadata.withNamespace($._config.namespace) + - configMap.withData({ - 'agent.yml': $.util.manifestYaml($._config.agent_config), - }), - - agent_args:: { - 'config.file': '/etc/agent/agent.yml', - 'metrics.wal-directory': '/tmp/agent/data', - }, - - agent_container:: - container.new('agent', $._images.agent) + - container.withPorts($.core.v1.containerPort.new('http-metrics', 80)) + - container.withArgsMixin($.util.mapToFlags($.agent_args)) + - container.withEnv([ - $.core.v1.envVar.fromFieldPath('HOSTNAME', 'spec.nodeName'), - ]) + - container.mixin.securityContext.withPrivileged(true) + - container.mixin.securityContext.withRunAsUser(0), - - config_hash_mixin:: { - local hash(config) = { config_hash: std.md5(std.toString(config)) }, - daemonSet: - if $._config.agent_config_hash_annotation then - daemonSet.mixin.spec.template.metadata.withAnnotationsMixin(hash($._config.agent_config)) - else {}, - deployment: - if $._config.agent_config_hash_annotation then - deployment.mixin.spec.template.metadata.withAnnotationsMixin(hash($._config.deployment_agent_config)) - else {}, - }, - - // TODO(rfratto): persistent storage for the WAL here is missing. hostVolume? - agent_daemonset: - daemonSet.new($._config.agent_pod_name, [$.agent_container]) + - daemonSet.mixin.metadata.withNamespace($._config.namespace) + - daemonSet.mixin.spec.template.spec.withServiceAccount($._config.agent_cluster_role_name) + - self.config_hash_mixin.daemonSet + - $.util.configVolumeMount($._config.agent_configmap_name, '/etc/agent'), - - agent_deployment_config_map: - if $._config.agent_host_filter then - configMap.new($._config.agent_deployment_configmap_name) + - configMap.mixin.metadata.withNamespace($._config.namespace) + - configMap.withData({ - 'agent.yml': $.util.manifestYaml($._config.deployment_agent_config), - }) - else {}, - - agent_deployment: - if $._config.agent_host_filter then - deployment.new($._config.agent_deployment_pod_name, 1, [$.agent_container]) + - deployment.mixin.metadata.withNamespace($._config.namespace) + - deployment.mixin.spec.template.spec.withServiceAccount($._config.agent_cluster_role_name) + - deployment.mixin.spec.withReplicas(1) + - self.config_hash_mixin.deployment + - $.util.configVolumeMount($._config.agent_deployment_configmap_name, '/etc/agent') - else {}, -} diff --git a/production/tanka/grafana-agent/jsonnetfile.json b/production/tanka/grafana-agent/jsonnetfile.json deleted file mode 100644 index c903ac17c07c..000000000000 --- a/production/tanka/grafana-agent/jsonnetfile.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "dependencies": [ - { - "name": "ksonnet-util", - "source": { - "git": { - "remote": "https://github.com/grafana/jsonnet-libs", - "subdir": "ksonnet-util" - } - }, - "version": "master" - } - ] -} diff --git a/production/tanka/grafana-agent/scraping-svc/main.libsonnet b/production/tanka/grafana-agent/scraping-svc/main.libsonnet deleted file mode 100644 index 7e414a0e816d..000000000000 --- a/production/tanka/grafana-agent/scraping-svc/main.libsonnet +++ /dev/null @@ -1,107 +0,0 @@ -local config = import '../config.libsonnet'; -local syncer = import './syncer.libsonnet'; -local k = import 'ksonnet-util/kausal.libsonnet'; - -local containerPort = k.core.v1.containerPort; -local configMap = k.core.v1.configMap; -local container = k.core.v1.container; -local deployment = k.apps.v1.deployment; -local policyRule = k.rbac.v1.policyRule; - -{ - new(namespace='default', kube_namespace='kube-system'):: config { - local this = self, - - // Use the default config from the non-scraping-service mode - // but change some of the defaults. - _config+:: { - agent_cluster_role_name: 'grafana-agent-cluster', - agent_configmap_name: 'grafana-agent-cluster', - agent_pod_name: 'grafana-agent-cluster', - agent_replicas: 3, - - namespace: namespace, - kube_namespace: kube_namespace, - - // Scraping service should not be using host filtering - agent_host_filter: false, - - // - // KVStore options - // - agent_config_kvstore: error 'must configure config kvstore', - agent_ring_kvstore: error 'must configure ring kvstore', - - agent_config+: { - metrics+: { - // No configs are used in the scraping service mode. - configs:: [], - - scraping_service: { - enabled: true, - kvstore: this._config.agent_config_kvstore, - lifecycler: { - ring: { - kvstore: this._config.agent_ring_kvstore, - }, - }, - }, - }, - }, - }, - - rbac: - // Need to do a hack here so ksonnet util has our configs :( - (k { _config+: this._config }).util.rbac(this._config.agent_cluster_role_name, [ - policyRule.withApiGroups(['']) + - policyRule.withResources(['nodes', 'nodes/proxy', 'services', 'endpoints', 'pods']) + - policyRule.withVerbs(['get', 'list', 'watch']), - - policyRule.withNonResourceUrls('/metrics') + - policyRule.withVerbs(['get']), - ]), - - configMap: - configMap.new(this._config.agent_configmap_name) + - configMap.withData({ - 'agent.yml': k.util.manifestYaml(this._config.agent_config), - }), - - container:: - container.new('agent-cluster', this._images.agent) + - container.withPorts(containerPort.new(name='http-metrics', port=80)) + - container.withArgsMixin(k.util.mapToFlags({ - 'config.file': '/etc/agent/agent.yml', - 'metrics.wal-directory': '/tmp/agent/data', - })) + - container.withEnv([ - k.core.v1.envVar.fromFieldPath('HOSTNAME', 'spec.nodeName'), - ]) + - container.mixin.securityContext.withPrivileged(true) + - container.mixin.securityContext.withRunAsUser(0), - - deployment: - deployment.new(this._config.agent_pod_name, this._config.agent_replicas, [this.container]) + - deployment.mixin.spec.template.spec.withServiceAccount(this._config.agent_cluster_role_name) + - deployment.mixin.spec.withMinReadySeconds(60) + - deployment.mixin.spec.strategy.rollingUpdate.withMaxSurge(0) + - deployment.mixin.spec.strategy.rollingUpdate.withMaxUnavailable(1) + - deployment.mixin.spec.template.spec.withTerminationGracePeriodSeconds(4800) + - k.util.configVolumeMount(this._config.agent_configmap_name, '/etc/agent'), - - service: - k.util.serviceFor(this.deployment), - - // Create the cronjob that syncs configs to the API - syncer: - syncer.new(this._images.agentctl, this._config), - }, - - withImagesMixin(images):: { _images+: images }, - - // withConfig overrides the config used for the agent. - withConfig(config):: { _config: config }, - - // withConfigMixin merges the provided config with the existing config. - withConfigMixin(config):: { _config+: config }, -} diff --git a/production/tanka/grafana-agent/scraping-svc/syncer.libsonnet b/production/tanka/grafana-agent/scraping-svc/syncer.libsonnet deleted file mode 100644 index d24373e164f0..000000000000 --- a/production/tanka/grafana-agent/scraping-svc/syncer.libsonnet +++ /dev/null @@ -1,61 +0,0 @@ -local k = import 'ksonnet-util/kausal.libsonnet'; - -local cronJob = k.batch.v1.cronJob; -local configMap = k.core.v1.configMap; -local container = k.core.v1.container; -local deployment = k.apps.v1.deployment; -local volumeMount = k.core.v1.volumeMount; -local volume = k.core.v1.volume; - -{ - new(agentctl_image, config):: { - local this = self, - - local configs = std.foldl( - function(agg, cfg) - // Sanitize the name and remove / so every file goes into the same - // folder. - local name = std.strReplace(cfg.job_name, '/', '_'); - - agg { - ['%s.yml' % name]: k.util.manifestYaml( - { - scrape_configs: [cfg], - remote_write: config.agent_remote_write, - }, - ), - }, - config.kubernetes_scrape_configs, - {}, - ), - - configMap: - configMap.new('agent-syncer') + - configMap.withData(configs), - - container:: - container.new('agent-syncer', agentctl_image) + - container.withArgsMixin([ - 'config-sync', - '--addr=http://%(agent_pod_name)s.%(namespace)s.svc.cluster.local:80' % config, - '/etc/configs', - ]) + - container.withVolumeMounts([ - volumeMount.new('agent-syncer', '/etc/configs'), - ]), - - syncer_job: - cronJob.new('agent-syncer', '*/5 * * * *', this.container) + - cronJob.mixin.spec.withSuccessfulJobsHistoryLimit(1) + - cronJob.mixin.spec.withFailedJobsHistoryLimit(3) + - cronJob.mixin.spec.jobTemplate.spec.template.spec.withRestartPolicy('OnFailure') + - cronJob.mixin.spec.jobTemplate.spec.template.spec.withActiveDeadlineSeconds(600) + - cronJob.mixin.spec.jobTemplate.spec.withTtlSecondsAfterFinished(120) + - cronJob.mixin.spec.jobTemplate.spec.template.spec.withVolumes([ - volume.fromConfigMap( - name='agent-syncer', - configMapName=this.configMap.metadata.name, - ), - ]), - }, -} diff --git a/production/tanka/grafana-agent/smoke/avalanche/main.libsonnet b/production/tanka/grafana-agent/smoke/avalanche/main.libsonnet deleted file mode 100644 index 6887337ce2a9..000000000000 --- a/production/tanka/grafana-agent/smoke/avalanche/main.libsonnet +++ /dev/null @@ -1,49 +0,0 @@ -local k = import 'ksonnet-util/kausal.libsonnet'; - -local configMap = k.core.v1.configMap; -local container = k.core.v1.container; -local containerPort = k.core.v1.containerPort; -local deployment = k.apps.v1.deployment; -local pvc = k.core.v1.persistentVolumeClaim; -local service = k.core.v1.service; -local volumeMount = k.core.v1.volumeMount; -local volume = k.core.v1.volume; - -{ - new(name='avalanche', replicas=1, namespace='', config={}):: { - local this = self, - - _config+:: { - image: 'quay.io/freshtracks.io/avalanche:latest', - - metric_count: 500, - label_count: 10, - series_count: 10, - metricname_length: 5, - labelname_length: 5, - value_interval: 30, - series_interval: 30, - metric_interval: 120, - } + config, - - container:: - container.new(name, this._config.image) + - container.withPorts([ - containerPort.newNamed(name='http', containerPort=9001), - ]) + - container.withArgsMixin([ - '--metric-count=%d' % this._config.metric_count, - '--label-count=%d' % this._config.label_count, - '--series-count=%d' % this._config.series_count, - '--metricname-length=%d' % this._config.metricname_length, - '--labelname-length=%d' % this._config.labelname_length, - '--value-interval=%d' % this._config.value_interval, - '--series-interval=%d' % this._config.series_interval, - '--metric-interval=%d' % this._config.metric_interval, - ]), - - deployment: - deployment.new(name, replicas, [self.container]) + - deployment.mixin.metadata.withNamespace(namespace), - }, -} diff --git a/production/tanka/grafana-agent/smoke/crow/main.libsonnet b/production/tanka/grafana-agent/smoke/crow/main.libsonnet deleted file mode 100644 index a159e6c16657..000000000000 --- a/production/tanka/grafana-agent/smoke/crow/main.libsonnet +++ /dev/null @@ -1,36 +0,0 @@ -local k = import 'ksonnet-util/kausal.libsonnet'; - -local configMap = k.core.v1.configMap; -local container = k.core.v1.container; -local containerPort = k.core.v1.containerPort; -local deployment = k.apps.v1.deployment; -local pvc = k.core.v1.persistentVolumeClaim; -local service = k.core.v1.service; -local volumeMount = k.core.v1.volumeMount; -local volume = k.core.v1.volume; - -{ - new(name='crow', namespace='', config={}):: { - local this = self, - - _config+:: { - image: 'us.gcr.io/kubernetes-dev/grafana/agent-crow:main', - args: { - 'server.http.address': '0.0.0.0:80', - }, - pull_secret: '', - } + config, - - container:: - container.new(name, this._config.image) + - container.withPorts([ - containerPort.newNamed(name='http-metrics', containerPort=80), - ]) + - container.withArgsMixin(k.util.mapToFlags(this._config.args)), - - deployment: - deployment.new(name, 1, [self.container]) + - deployment.mixin.metadata.withNamespace(namespace) + - deployment.spec.template.spec.withImagePullSecrets({ name: this._config.pull_secret }), - }, -} diff --git a/production/tanka/grafana-agent/smoke/etcd/main.libsonnet b/production/tanka/grafana-agent/smoke/etcd/main.libsonnet deleted file mode 100644 index 46598632a545..000000000000 --- a/production/tanka/grafana-agent/smoke/etcd/main.libsonnet +++ /dev/null @@ -1,30 +0,0 @@ -local k = import 'ksonnet-util/kausal.libsonnet'; - -local container = k.core.v1.container; -local containerPort = k.core.v1.containerPort; -local deployment = k.apps.v1.deployment; -local service = k.core.v1.service; - -{ - new(namespace=''):: { - container:: - container.new('etcd', 'gcr.io/etcd-development/etcd:v3.4.7') + - container.withPorts([ - containerPort.newNamed(name='etcd', containerPort=2379), - ]) + - container.withArgsMixin([ - '/usr/local/bin/etcd', - '--listen-client-urls=http://0.0.0.0:2379', - '--advertise-client-urls=http://0.0.0.0:2379', - '--log-level=info', - ]), - - deployment: - deployment.new('etcd', 1, [self.container]) + - deployment.mixin.metadata.withNamespace(namespace), - - service: - k.util.serviceFor(self.deployment) + - service.mixin.metadata.withNamespace(namespace), - }, -} diff --git a/production/tanka/grafana-agent/smoke/main.libsonnet b/production/tanka/grafana-agent/smoke/main.libsonnet deleted file mode 100644 index d8cbac4dc142..000000000000 --- a/production/tanka/grafana-agent/smoke/main.libsonnet +++ /dev/null @@ -1,69 +0,0 @@ -local k = import 'ksonnet-util/kausal.libsonnet'; -local policyRule = k.rbac.v1.policyRule; -local serviceAccount = k.core.v1.serviceAccount; -local container = k.core.v1.container; -local containerPort = k.core.v1.containerPort; -local deployment = k.apps.v1.deployment; -local service = k.core.v1.service; -local util = k.util; - -{ - new(name='grafana-agent-smoke', namespace='default', config={}):: { - local k = (import 'ksonnet-util/kausal.libsonnet') { _config+:: { namespace: namespace } }, - - local this = self, - - _images:: { - agentsmoke: 'us.gcr.io/kubernetes-dev/grafana/agent-smoke:main', - }, - - _config:: { - mutationFrequency: '5m', - chaosFrequency: '30m', - image: this._images.agentsmoke, - pull_secret: '', - podPrefix: 'grafana-agent', - simulateErrors: true, - } + config, - - rbac: - k.util.rbac(name, [ - policyRule.withApiGroups(['apps']) + - policyRule.withResources(['deployments/scale']) + - policyRule.withVerbs(['get', 'update']), - policyRule.withApiGroups(['']) + - policyRule.withResources(['pods']) + - policyRule.withVerbs(['list', 'delete']), - ]) { - service_account+: - serviceAccount.mixin.metadata.withNamespace(namespace), - }, - - container:: - container.new('agent-smoke', this._config.image) + - container.withPorts([ - containerPort.newNamed(name='remote-write', containerPort=19090), - ]) + - container.withArgsMixin(k.util.mapToFlags({ - 'log.level': 'debug', - namespace: namespace, - 'mutation-frequency': this._config.mutationFrequency, - 'chaos-frequency': this._config.chaosFrequency, - 'pod-prefix': this._config.podPrefix, - 'fake-remote-write': true, - 'simulate-errors': this._config.simulateErrors, - })), - - agentsmoke_deployment: - deployment.new(name, 1, [self.container]) + - deployment.mixin.metadata.withNamespace(namespace) + - deployment.mixin.spec.template.spec.withServiceAccount(name) + - deployment.spec.template.spec.withImagePullSecrets({ name: this._config.pull_secret }), - - service: - util.serviceFor(self.agentsmoke_deployment) + - service.mixin.metadata.withNamespace(namespace), - }, - - monitoring: (import './prometheus_monitoring.libsonnet'), -} diff --git a/production/tanka/grafana-agent/v1/README.md b/production/tanka/grafana-agent/v1/README.md deleted file mode 100644 index 5eb6f0513722..000000000000 --- a/production/tanka/grafana-agent/v1/README.md +++ /dev/null @@ -1,79 +0,0 @@ -# Tanka Configs - -**STATUS**: Abandoned. Use v0 (parent directory) or v2 instead. - -This directory contains the Tanka configs that we use to deploy the Grafana -Agent. It is marked as `v1` and is incompatible with the `v0` configs -found in the [parent directory](../). - -This library is currently a work in progress and backwards-incompatible changes -may occur. Once the library is considered complete, no further backwards -incompatible changes will be made. - -## Capabilities - -This library is significantly more flexible than its `v0` counterpart. It tries -to allow to deploy and configure the Agent in a feature matrix: - -| Mechanism | Metrics | Logs | Traces | Integrations | -| ---------------- | ------- | --------- | ------ | ------------ | -| DaemonSet | Yes | Yes | Yes | Yes | -| Deployment | Yes | No | No | No | -| Scraping Service | Yes | No | No | No | - -The library can be invoked multiple times to get full coverage. For example, you -may wish to deploy a scraping service for scalable metrics collection, and a -DaemonSet with just Loki Logs for log collection. - -Trying to use the library in incompatible ways will generate errors. For -example, you may not deploy a scraping service with Loki logs collection. - -## API - -## Generate Agent Deployment - -- `new(name, namespace)`: Create a new DaemonSet. This is the default mode to - deploy the Agent. Enables host filtering. -- `newDeployment(name, namespace)`: Create a new single-replica Deployment. - Disables host filtering. -- `newScrapingService(name, namespace, replicas)`: (Not yet available). Create a - scalable deployment of clustered Agents. Requires being given a KV store such as Redis or ETCD. - -## Configure Metrics - -- `withMetricsConfig(config)`: Creates a metrics config block. -- `defaultMetricsConfig`: Default metrics config block. -- `withMetricsInstances(instances)`: Creates a metrics instance config to - tell the Agent what to scrape. -- `withRemoteWrite(remote_writes)`: Configures locations to remote write metrics - to. Controls remote writes globally. -- `scrapeInstanceKubernetes`: Default metrics instance config to scrape from - Kubernetes. - -## Configure Logs - -- `withLogsConfig(config)`: Creates a Logs config block to pass to the Agent. -- `newLogsClient(client_config)`: Creates a new client configuration to pass - to `withLogsClients`. -- `withLogsClients(clients)`: Add a set of clients to a Logs config block. -- `scrapeKubernetesLogs`: Default Logs config that collects logs from Kubernetes - pods. - -## Configure Traces - -- `withTracesConfig(config)`: Creates a Traces config block to pass to the Agent. -- `withTracesRemoteWrite(remote_write)`: Configures one or multiple locations to push spans to. -- `withTracesSamplingStrategies(strategies)`: Configures strategies for trace collection. -- `withTracesScrapeConfigs(scrape_configs)`: Configures scrape configs to attach - labels to incoming spans. -- `tracesScrapeKubernetes`: Default scrape configs to collect meta information - from pods. Aligns with the labels from `scrapeInstanceKubernetes` and - `scrapeKubernetesLogs` so logs, metrics, and traces all use the same set of - labels. - -## General - -- `withImages(images)`: Use custom images. -- `withConfigHash(include=true)`: Whether to include a config hash annotation. -- `withPortsMixin(ports)`: Mixin ports from `k.core.v1.containerPort` against - the container and service. diff --git a/production/tanka/grafana-agent/v1/internal/agent.libsonnet b/production/tanka/grafana-agent/v1/internal/agent.libsonnet deleted file mode 100644 index d6af77dd0bd7..000000000000 --- a/production/tanka/grafana-agent/v1/internal/agent.libsonnet +++ /dev/null @@ -1,72 +0,0 @@ -local k = import 'ksonnet-util/kausal.libsonnet'; - -local configMap = k.core.v1.configMap; -local container = k.core.v1.container; -local daemonSet = k.apps.v1.daemonSet; -local deployment = k.apps.v1.deployment; -local policyRule = k.rbac.v1.policyRule; -local serviceAccount = k.core.v1.serviceAccount; - -{ - newAgent(name='grafana-agent', namespace='default', image, config, use_daemonset=true):: { - local controller = if use_daemonset then daemonSet else deployment, - local k = (import 'ksonnet-util/kausal.libsonnet') { _config+:: { namespace: namespace } }, - local this = self, - - _controller:: controller, - _config_hash:: true, - - listen_port:: 8080, - - rbac: - k.util.rbac(name, [ - // Need for k8s SD on Loki/Prometheus subsystems - policyRule.withApiGroups(['']) + - policyRule.withResources(['nodes', 'nodes/proxy', 'services', 'endpoints', 'pods']) + - policyRule.withVerbs(['get', 'list', 'watch']), - - // Needed for Prometheus subsystem to scrape k8s API - policyRule.withNonResourceUrls('/metrics') + - policyRule.withVerbs(['get']), - ]) { - service_account+: - serviceAccount.mixin.metadata.withNamespace(namespace), - }, - - config_map: - configMap.new(name) + - configMap.mixin.metadata.withNamespace(namespace) + - configMap.withData({ - 'agent.yaml': k.util.manifestYaml(config), - }), - - container:: - container.new('agent', image) + - container.withPorts(k.core.v1.containerPort.new('http-metrics', self.listen_port)) + - container.withArgsMixin(k.util.mapToFlags({ - 'config.file': '/etc/agent/agent.yaml', - 'server.http.address': '0.0.0.0:' + this.listen_port, - })) + - container.withEnvMixin([ - k.core.v1.envVar.fromFieldPath('HOSTNAME', 'spec.nodeName'), - ]), - - agent: - ( - if use_daemonset then daemonSet.new(name, [self.container]) - else deployment.new(name, 1, [self.container]) - ) + - controller.mixin.metadata.withNamespace(namespace) + - controller.mixin.spec.template.spec.withServiceAccount(name) + - ( - if self._config_hash - then controller.mixin.spec.template.metadata.withAnnotationsMixin({ - config_hash: std.md5(std.toString(config)), - }) - else {} - ) + - k.util.configVolumeMount(name, '/etc/agent'), - }, - - withConfigHash(include):: { _config_hash:: include }, -} diff --git a/production/tanka/grafana-agent/v1/internal/kubernetes_instance.libsonnet b/production/tanka/grafana-agent/v1/internal/kubernetes_instance.libsonnet deleted file mode 100644 index a4749c9797fc..000000000000 --- a/production/tanka/grafana-agent/v1/internal/kubernetes_instance.libsonnet +++ /dev/null @@ -1,27 +0,0 @@ -local k8s_v2 = import '../../v2/internal/helpers/k8s.libsonnet'; - -{ - kubernetesScrapeInstanceConfig:: { - scrape_api_server_endpoints: false, - insecure_skip_verify: false, - - cluster_dns_tld: 'local', - cluster_dns_suffix: 'cluster.' + self.cluster_dns_tld, - kubernetes_api_server_address: 'kubernetes.default.svc.%(cluster_dns_suffix)s:443' % self, - }, - - newKubernetesScrapeInstance(config, namespace='default'):: { - local _config = $.kubernetesScrapeInstanceConfig + config, - - name: 'kubernetes', - scrape_configs: k8s_v2.metrics({ - scrape_api_server_endpoints: _config.scrape_api_server_endpoints, - insecure_skip_verify: _config.insecure_skip_verify, - cluster_dns_tld: _config.cluster_dns_tld, - cluster_dns_suffix: _config.cluster_dns_suffix, - kubernetes_api_server_address: _config.kubernetes_api_server_address, - ksm_namespace: namespace, - node_exporter_namespace: namespace, - }), - }, -} diff --git a/production/tanka/grafana-agent/v1/internal/kubernetes_logs.libsonnet b/production/tanka/grafana-agent/v1/internal/kubernetes_logs.libsonnet deleted file mode 100644 index 8ef2d4f40200..000000000000 --- a/production/tanka/grafana-agent/v1/internal/kubernetes_logs.libsonnet +++ /dev/null @@ -1,7 +0,0 @@ -local k8s_v2 = import '../../v2/internal/helpers/k8s.libsonnet'; - -{ - newKubernetesLogsCollector():: { - scrape_configs: k8s_v2.logs(), - }, -} diff --git a/production/tanka/grafana-agent/v1/internal/utils.libsonnet b/production/tanka/grafana-agent/v1/internal/utils.libsonnet deleted file mode 100644 index 35ab5834a782..000000000000 --- a/production/tanka/grafana-agent/v1/internal/utils.libsonnet +++ /dev/null @@ -1,36 +0,0 @@ -{ - // Returns true if the scrape_config only contains a service_discovery for - // Kubernetes (via kubernetes_sd_configs) that has role: pod - isOnlyK8sPodDiscovery(scrape_config):: - // Get all the *_sd_configs and filter that down to the sd_configs that aren't - // kubernetes_sd_configs. It should be 0. - std.length(std.filter( - function(key) key != 'kubernetes_sd_configs', - std.filter( - function(key) std.endsWith(key, '_sd_configs'), - std.objectFields(scrape_config), - ), - )) == 0 && - // Make sure there are 0 kubernetes_sd_configs whose role is not pod - std.length(std.filter( - function(kube_sd_config) kube_sd_config.role != 'pod', - std.flatMap( - function(key) scrape_config[key], - std.filter( - function(key) key == 'kubernetes_sd_configs', - std.objectFields(scrape_config) - ) - ) - )) == 0, - - // host_filter_compatible instances are ones that: - // - only use kubernetes_sd_configs - // - only use kubernetes_sd_configs with role = 'pod' - transformInstances(instances=[], host_filter_compatible=true):: - std.map(function(instance) instance { - scrape_configs: std.filter( - function(cfg) $.isOnlyK8sPodDiscovery(cfg) == host_filter_compatible, - super.scrape_configs, - ), - }, instances), -} diff --git a/production/tanka/grafana-agent/v1/lib/deployment.libsonnet b/production/tanka/grafana-agent/v1/lib/deployment.libsonnet deleted file mode 100644 index e557a0739516..000000000000 --- a/production/tanka/grafana-agent/v1/lib/deployment.libsonnet +++ /dev/null @@ -1,83 +0,0 @@ -local agent = import '../internal/agent.libsonnet'; -local k = import 'ksonnet-util/kausal.libsonnet'; - -local configMap = k.core.v1.configMap; -local service = k.core.v1.service; -local container = k.core.v1.container; - -{ - // newDeployment creates a new single-replicated Deployment of the - // grafana-agent. By default, this deployment will do no collection. You must - // merge the result of this function with the following: - // - // - withMetricsConfig - // - withMetricsInstances - // - optionally withRemoteWrite - // - // newDeployment does not support log collection. - newDeployment(name='grafana-agent', namespace='default'):: { - assert !std.objectHas(self, '_logs_config') : ||| - Log collection is not supported with newDeployment. - |||, - assert !std.objectHas(self, '_integrations') : ||| - Integrations are not supported with newDeployment. - |||, - - local this = self, - - _mode:: 'deployment', - _images:: $._images, - _config_hash:: true, - - local has_metrics_config = std.objectHasAll(self, '_metrics_config'), - local has_metrics_instances = std.objectHasAll(self, '_metrics_instances'), - local has_trace_config = std.objectHasAll(self, '_trace_config'), - local has_sampling_strategies = std.objectHasAll(self, '_traces_sampling_strategies'), - - config:: { - server: { - log_level: 'info', - }, - } + ( - if has_metrics_config - then { - metrics: - this._metrics_config { - configs: - if has_metrics_instances - then this._metrics_instances - else [], - }, - } - else {} - ) + ( - if has_trace_config then { - traces: { - configs: [this._trace_config { - name: 'default', - }], - }, - } - else {} - ), - - agent: - agent.newAgent(name, namespace, self._images.agent, self.config, use_daemonset=false) + - agent.withConfigHash(self._config_hash) + { - // If sampling strategies were defined, we need to mount them as a JSON - // file. - config_map+: - if has_sampling_strategies - then configMap.withDataMixin({ - 'strategies.json': std.toString(this._traces_sampling_strategies), - }) - else {}, - // If we're deploying for tracing, applications will want to write to - // a service for load balancing span delivery. - service: - if has_trace_config - then k.util.serviceFor(self.agent) + service.mixin.metadata.withNamespace(namespace) - else {}, - }, - }, -} diff --git a/production/tanka/grafana-agent/v1/lib/integrations.libsonnet b/production/tanka/grafana-agent/v1/lib/integrations.libsonnet deleted file mode 100644 index 6b1482816cf9..000000000000 --- a/production/tanka/grafana-agent/v1/lib/integrations.libsonnet +++ /dev/null @@ -1,33 +0,0 @@ -local k = import 'ksonnet-util/kausal.libsonnet'; - -local container = k.core.v1.container; - -{ - // withIntegrations controls the integrations component of the Agent. - // - // For the full list of options, refer to the configuration reference: - // https://github.com/grafana/agent/blob/main/docs/configuration-reference.md#integrations_config - withIntegrations(integrations):: { - assert std.objectHasAll(self, '_mode') : ||| - withIntegrations must be merged with the result of calling new. - |||, - _integrations:: integrations, - }, - - integrationsMixin:: { - container+:: - container.mixin.securityContext.withPrivileged(true) + - container.mixin.securityContext.withRunAsUser(0), - - local controller = self._controller, - agent+: - // procfs, sysfs, rotfs - k.util.hostVolumeMount('proc', '/proc', '/host/proc', readOnly=true) + - k.util.hostVolumeMount('sys', '/sys', '/host/sys', readOnly=true) + - k.util.hostVolumeMount('root', '/', '/host/root', readOnly=true) + - - controller.mixin.spec.template.spec.withHostPID(true) + - controller.mixin.spec.template.spec.withHostNetwork(true) + - controller.mixin.spec.template.spec.withDnsPolicy('ClusterFirstWithHostNet'), - }, -} diff --git a/production/tanka/grafana-agent/v1/lib/logs.libsonnet b/production/tanka/grafana-agent/v1/lib/logs.libsonnet deleted file mode 100644 index babb85d5ecca..000000000000 --- a/production/tanka/grafana-agent/v1/lib/logs.libsonnet +++ /dev/null @@ -1,82 +0,0 @@ -local scrape_k8s_logs = import '../internal/kubernetes_logs.libsonnet'; -local k = import 'ksonnet-util/kausal.libsonnet'; - -local container = k.core.v1.container; - -{ - // withLogsConfig adds a Logs config to collect logs. - // - // For the full list of options, refer to the configuration reference: - // https://grafana.com/docs/agent/latest/configuration/logs-config/ - withLogsConfig(config):: { - assert std.objectHasAll(self, '_mode') : ||| - withLogsConfig must be merged with the result of calling new. - |||, - _logs_config:: config, - }, - - // newLogsClient creates a new client object. Results from this can be passed into - // withLogsClients. - // - // client_config should be an object of the following shape: - // - // { - // scheme: 'https', // or http - // hostname: 'logs-us-central1.grafana.net', // replace with hostname to use - // username: '', // OPTIONAL username for Loki API connection - // password: '', // OPTIONAL password for Loki API connection - // external_labels: {}, // OPTIONAL labels to set for connection - // } - newLogsClient(client_config):: - { - url: ( - if std.objectHasAll(client_config, 'username') then - '%(scheme)s://%(username)s:%(password)s@%(hostname)s/loki/api/v1/push' % client_config - else - '%(scheme)s://%(hostname)s/loki/api/v1/push' % client_config - ), - } + ( - if std.objectHasAll(client_config, 'external_labels') - then { external_labels: client_config.external_labels } - else {} - ), - - // withLogsClients adds clients to send logs to. At least one client must be - // present. Clients can be created by calling newLogsClient or by creating - // an object that conforms to the Promtail client_config schema specified - // here: - // - // https://grafana.com/docs/loki/latest/clients/promtail/configuration/#client_config - // - // withLogsClients should be merged with the result of withLogsConfig. - withLogsClients(clients):: { - assert std.objectHasAll(self, '_logs_config') : ||| - withLogsClients must be merged with the result of calling withLogsConfig. - |||, - - _logs_config+:: { - clients: if std.isArray(clients) then clients else [clients], - }, - }, - - // logsPermissionsMixin mutates the container and deployment to work with - // reading Docker container logs. - logsPermissionsMixin:: { - container+:: - container.mixin.securityContext.withPrivileged(true) + - container.mixin.securityContext.withRunAsUser(0), - - agent+: - // For reading docker containers. /var/log is used for the positions file - // and shouldn't be set to readonly. - k.util.hostVolumeMount('varlog', '/var/log', '/var/log') + - k.util.hostVolumeMount('varlibdockercontainers', '/var/lib/docker/containers', '/var/lib/docker/containers', readOnly=true) + - - // For reading journald - k.util.hostVolumeMount('etcmachineid', '/etc/machine-id', '/etc/machine-id', readOnly=true), - }, - - // scrapeKubernetesLogs defines a Logs config that can collect logs from - // Kubernetes pods. - scrapeKubernetesLogs: scrape_k8s_logs.newKubernetesLogsCollector(), -} diff --git a/production/tanka/grafana-agent/v1/lib/metrics.libsonnet b/production/tanka/grafana-agent/v1/lib/metrics.libsonnet deleted file mode 100644 index 3cad8e867ab8..000000000000 --- a/production/tanka/grafana-agent/v1/lib/metrics.libsonnet +++ /dev/null @@ -1,116 +0,0 @@ -local scrape_k8s = import '../internal/kubernetes_instance.libsonnet'; - -{ - // defaultMetricsConfig holds the default Metrics Config with all - // options that the Agent supports. It is better to use this object as a - // reference rather than extending it; since all fields are defined here, if - // the Agent changes a default value in the future, the default change will - // be overridden by the values here. - // - // Required fields will be marked as REQUIRED. - defaultMetricsConfig:: { - // Settings that apply to all launched Metrics instances by default. - // These settings may be overridden on a per-instance basis. - global: { - // How frequently to scrape for metrics. - scrape_interval: '1m', - - // How long to wait before timing out from scraping a target. - scrape_timeout: '10s', - - // Extra labels to apply to all scraped targets. - external_labels: { - /* foo: 'bar', */ - }, - }, - - // Where to store the WAL for metrics before they are sent to remote_write. - // REQUIRED. The value here is preconfigured to work with the Tanka configs. - wal_directory: '/var/lib/agent/data', - - // If an instance crashes abnormally, wait this long before restarting it. - // 0s disables the backoff period and restarts the instance immediately. - instance_restart_backoff: '5s', - - // How to spawn instances based on compatible fields. Supported values: - // "shared" (default), "distinct". - instance_mode: 'shared', - }, - - // withMetricsConfig controls the Metrics engine settings for the Agent. - // defaultMetricsConfig explicitly defines all supported values that can be - // provided within config. - withMetricsConfig(config):: { _metrics_config:: config }, - - // withMetricsInstances controls the Metrics instances the Agent will - // launch. Instances may be a single object or an array of objects. Each - // object must have a name key that is unique to that object. - // - // scrapeInstanceKubernetes defines an example set of instances and the - // ones Grafana Labs uses in production. It does not demonstrate all available - // values for scrape configs and remote_write. For detailed information on - // instance config settings, consult the Agent documentation: - // - // https://github.com/grafana/agent/blob/main/docs/configuration-reference.md#metrics_instance_config - // - // host_filter does not need to be applied here; the library will apply it - // automatically based on how the Agent is being deployed. - // - // remote_write rules may be defined in the instance object. Optionally, - // remove_write rules may be applied to every instance object by using the - // withRemoteWrite function. - withMetricsInstances(instances):: { - assert std.objectHasAll(self, '_mode') : ||| - withMetricsInstances must be merged with the result of calling new, - newDeployment, or newScrapingService. - |||, - - local list = if std.isArray(instances) then instances else [instances], - - // If the library was invoked in daemonset mode, we want to use - // host_filtering mode so each Agent only scrapes stuff from its local - // machine. - local host_filter = super._mode == 'daemonset', - - // Apply host_filtering over our list of instances. - _metrics_instances:: std.map(function(inst) inst { - host_filter: host_filter, - - // Make sure remote_write is an empty array if it doesn't exist. - remote_write: - if !std.objectHas(inst, 'remote_write') || !std.isArray(inst.remote_write) - then [] - else inst.remote_write, - }, list), - }, - - // withRemoteWrite overwrites all the remote_write configs provided in - // withMetricsInstances with the specified remote_writes. This is - // useful when there are multiple instances and you just want everything - // to remote_write to the same place. - // - // Refer to the remote_write specification for all available fields: - // https://github.com/grafana/agent/blob/main/docs/configuration-reference.md#remote_write - withRemoteWrite(remote_writes):: { - assert std.objectHasAll(self, '_mode') : ||| - withMetricsInstances must be merged with the result of calling new, - newDeployment, or newScrapingService. - |||, - - local list = if std.isArray(remote_writes) then remote_writes else [remote_writes], - _metrics_config+:: { global+: { remote_write: list } }, - }, - - // scrapeInstanceKubernetes defines an instance config Grafana Labs uses to - // scrape Kubernetes metrics. - // - // Pods will be scraped if: - // - // 1. They have a port ending in -metrics - // 2. They do not have a prometheus.io/scrape=false annotation - // 3. They have a name label - scrapeInstanceKubernetes: scrape_k8s.newKubernetesScrapeInstance( - config=scrape_k8s.kubernetesScrapeInstanceConfig, - namespace='default', - ), -} diff --git a/production/tanka/grafana-agent/v1/lib/scraping_service.libsonnet b/production/tanka/grafana-agent/v1/lib/scraping_service.libsonnet deleted file mode 100644 index 6962ad3b8d30..000000000000 --- a/production/tanka/grafana-agent/v1/lib/scraping_service.libsonnet +++ /dev/null @@ -1,4 +0,0 @@ -{ - // TODO(rfratto): port scraping service code and expose as newScrapingService - // here. -} diff --git a/production/tanka/grafana-agent/v1/lib/traces.libsonnet b/production/tanka/grafana-agent/v1/lib/traces.libsonnet deleted file mode 100644 index 98a91fcb4191..000000000000 --- a/production/tanka/grafana-agent/v1/lib/traces.libsonnet +++ /dev/null @@ -1,121 +0,0 @@ -{ - // withTracesConfig adds a Traces config to collect traces. - // - // For the full list of options, refer to the configuration reference: - // - withTracesConfig(config):: { - assert std.objectHasAll(self, '_mode') : ||| - withTracesConfig must be merged with the result of calling new. - |||, - _trace_config:: config, - }, - - // withTracesRemoteWrite configures one or multiple backends to write traces to. - // - // Available options can be found in the configuration reference: - // https://github.com/grafana/agent/blob/main/docs/configuration-reference.md#traces_config - withTracesRemoteWrite(remote_write):: { - assert std.objectHasAll(self, '_trace_config') : ||| - withTracesRemoteWrite must be merged with the result of calling - withTracesConfig. - |||, - _trace_config+:: { remote_write: remote_write }, - }, - - // withTracesSamplingStrategies accepts an object for trace sampling strategies. - // - // Refer to Jaeger's documentation for available fields: - // https://www.jaegertracing.io/docs/1.17/sampling/#collector-sampling-configuration - // - // Creating a file isn't necessary; just provide the object and a ConfigMap - // will be created for you and added to the tempo config. - withTracesSamplingStrategies(strategies):: { - assert std.objectHasAll(self, '_trace_config') : ||| - withTracesPushConfig must be merged with the result of calling - withTracesConfig. - |||, - - assert - std.objectHasAll(self._trace_config, 'receivers') && - std.objectHasAll(self._trace_config.receivers, 'jaeger') : ||| - withStrategies can only be used if the traces config is configured for - receiving Jaeger spans and traces. - |||, - - // The main library should detect the presence of _traces_sampling_strategies - // and create a ConfigMap bound to /etc/agent/strategies.json. - _traces_sampling_strategies:: strategies, - _trace_config+:: { - receivers+: { - jaeger+: { - remote_sampling: { - strategy_file: '/etc/agent/strategies.json', - insecure: true, - }, - }, - }, - }, - }, - - // Configures scrape_configs for discovering meta labels that will be attached - // to incoming metrics and spans whose IP matches the __address__ of the - // target. - withTracesScrapeConfigs(scrape_configs):: { - assert std.objectHasAll(self, '_trace_config') : ||| - withTracesScrapeConfigs must be merged with the result of calling - withTracesConfig. - |||, - _trace_config+: { scrape_configs: scrape_configs }, - }, - - // Provides a default set of scrape_configs to use for discovering labels from - // Pods. Labels will be attached to any traces sent from the discovered pods. - tracesScrapeKubernetes:: [ - { - bearer_token_file: '/var/run/secrets/kubernetes.io/serviceaccount/token', - job_name: 'kubernetes-pods', - kubernetes_sd_configs: [{ role: 'pod' }], - relabel_configs: [ - { - action: 'replace', - source_labels: ['__meta_kubernetes_namespace'], - target_label: 'namespace', - }, - { - action: 'replace', - source_labels: ['__meta_kubernetes_pod_name'], - target_label: 'pod', - }, - { - action: 'replace', - source_labels: ['__meta_kubernetes_pod_container_name'], - target_label: 'container', - }, - ], - tls_config: { - ca_file: '/var/run/secrets/kubernetes.io/serviceaccount/ca.crt', - insecure_skip_verify: false, - }, - }, - ], - - // withTracesTailSamplingConfig tail-based sampling for traces. - // - // Available options can be found in the configuration reference: - // https://github.com/grafana/agent/blob/main/docs/configuration-reference.md#traces_config - withTracesTailSamplingConfig(tail_sampling):: { - assert std.objectHasAll(self, '_trace_config') : ||| - withTracesTailSamplingConfig must be merged with the result of calling - withTracesConfig. - |||, - _trace_config+:: { tail_sampling: tail_sampling }, - }, - - withTracesLoadBalancingConfig(load_balancing):: { - assert std.objectHasAll(self, '_trace_config') : ||| - withTracesLoadBalancingConfig must be merged with the result of calling - withTracesConfig. - |||, - _trace_config+:: { load_balancing: load_balancing }, - }, -} diff --git a/production/tanka/grafana-agent/v1/main.libsonnet b/production/tanka/grafana-agent/v1/main.libsonnet deleted file mode 100644 index d4096bc015e9..000000000000 --- a/production/tanka/grafana-agent/v1/main.libsonnet +++ /dev/null @@ -1,142 +0,0 @@ -local agent = import './internal/agent.libsonnet'; -local utils = import './internal/utils.libsonnet'; -local k = import 'ksonnet-util/kausal.libsonnet'; - -local container = k.core.v1.container; -local configMap = k.core.v1.configMap; -local service = k.core.v1.service; - -// Merge all of our libraries to create the final exposed library. -(import './lib/deployment.libsonnet') + -(import './lib/integrations.libsonnet') + -(import './lib/metrics.libsonnet') + -(import './lib/scraping_service.libsonnet') + -(import './lib/logs.libsonnet') + -(import './lib/traces.libsonnet') + -{ - _images:: { - agent: 'grafana/agent:v0.39.0', - agentctl: 'grafana/agentctl:v0.39.0', - }, - - // new creates a new DaemonSet deployment of the grafana-agent. By default, - // the deployment will do no collection. You must merge the result of this - // function with one or more of the following: - // - // - withMetricsConfig, withMetricsInstances (and optionally withRemoteWrite) - // - withLogsConfig - // - // When using withMetricsInstances, a [name]-etc deployment - // with one replica will be created alongside the DaemonSet. This deployment - // is responsible for handling scrape configs that will not work on the host - // machine. - // - // For example, if a scrape_config scrapes the Kubernetes API, that must be - // handled by the [name]-etc deployment as the Kubernetes API does not run - // on any node in the cluster. - // - // scrapeInstanceKubernetes provides the default - // MetricsInstanceConfig Grafana Labs uses in production. - new(name='grafana-agent', namespace='default'):: { - local this = self, - - _mode:: 'daemonset', - _images:: $._images, - _config_hash:: true, - - local has_logs_config = std.objectHasAll(self, '_logs_config'), - local has_trace_config = std.objectHasAll(self, '_trace_config'), - local has_metrics_config = std.objectHasAll(self, '_metrics_config'), - local has_metrics_instances = std.objectHasAll(self, '_metrics_instances'), - local has_integrations = std.objectHasAll(self, '_integrations'), - local has_sampling_strategies = std.objectHasAll(self, '_traces_sampling_strategies'), - - local metrics_instances = - if has_metrics_instances then this._metrics_instances else [], - local host_filter_instances = utils.transformInstances(metrics_instances, true), - local etc_instances = utils.transformInstances(metrics_instances, false), - - config:: { - server: { - log_level: 'info', - }, - } + ( - if has_metrics_config - then { metrics: this._metrics_config { configs: host_filter_instances } } - else {} - ) + ( - if has_logs_config then { - logs: { - positions_directory: '/tmp/positions', - configs: [this._logs_config { - name: 'default', - }], - }, - } else {} - ) + ( - if has_trace_config then { - traces: { - configs: [this._trace_config { - name: 'default', - }], - }, - } - else {} - ) + ( - if has_integrations then { integrations: this._integrations } else {} - ), - - etc_config:: if has_metrics_config then this.config { - // Hide logs and integrations from our extra configs, we just want the - // scrape configs that wouldn't work for the DaemonSet. - metrics+: { - configs: std.map(function(cfg) cfg { host_filter: false }, etc_instances), - }, - logs:: {}, - traces:: {}, - integrations:: {}, - }, - - agent: - agent.newAgent(name, namespace, self._images.agent, self.config, use_daemonset=true) + - agent.withConfigHash(self._config_hash) + { - // If sampling strategies were defined, we need to mount them as a JSON - // file. - config_map+: - if has_sampling_strategies - then configMap.withDataMixin({ - 'strategies.json': std.toString(this._traces_sampling_strategies), - }) - else {}, - - // If we're deploying for tracing, applications will want to write to - // a service for load balancing span delivery. - service: - if has_trace_config - then k.util.serviceFor(self.agent) + service.mixin.metadata.withNamespace(namespace) - else {}, - } + ( - if has_logs_config then $.logsPermissionsMixin else {} - ) + ( - if has_integrations && std.objectHas(this._integrations, 'node_exporter') then $.integrationsMixin else {} - ), - - agent_etc: if std.length(etc_instances) > 0 then - agent.newAgent(name + '-etc', namespace, self._images.agent, self.etc_config, use_daemonset=false) + - agent.withConfigHash(self._config_hash), - }, - - // withImages sets the images used for launching the Agent. - // Keys supported: agent, agentctl - withImages(images):: { _images+: images }, - - // Includes or excludes the config hash annotation. - withConfigHash(include=true):: { _config_hash:: include }, - - // withPortsMixin adds extra ports to expose. - withPortsMixin(ports=[]):: { - agent+: { - container+:: container.withPortsMixin(ports), - }, - }, -} diff --git a/production/tanka/grafana-agent/v2/README.md b/production/tanka/grafana-agent/v2/README.md deleted file mode 100644 index 33c18cadeac7..000000000000 --- a/production/tanka/grafana-agent/v2/README.md +++ /dev/null @@ -1,84 +0,0 @@ -# Tanka Configs - -**STATUS**: Work in progress, use of these configs is not recommended for production. - -This directory contains the Tanka configs that we use to deploy the Grafana -Agent. It is marked as `v2` and is incompatible previous versions of the library -located in other directories. - -This library is currently a work in progress and backwards-incompatible changes -may occur. Once the library is considered complete, no further backwards -incompatible changes will be made. - -## Capabilities - -This library is significantly simplified over the `v0` and `v1` counterparts. -Since there are many ways to combine the various functionalities of the Grafana -Agent, the `v2` library aims to stay out of your way and provide optional composible -helpers that may be useful for some people. - -Users of the library will pick a controller for their deployment. They are -expected to know what feature are compatible with which controller: - -| Controller | Metrics | Logs | Traces | Integrations | -| ---------------- | ------------------- | --------- | ------ | ------------ | -| DaemonSet | If host filtering | Yes | Yes | No | -| Deployment | Yes | No | No | Yes | -| StatefulSet | Yes | No | No | Yes | - -Creating an incompatible deployment will cause runtime issues when running the -Agent (for example, if configuring Logs with a StatefulSet, you will only get -logs from the node the pods are running on). - -To get full coverage of features, you must create multiple deployments of the -library. You may wish to combine a StatefulSet for metrics and integrations, a -Deployment for Traces, and a DaemonSet for logs. - -## API - -## Generate Agent Deployment - -- `new(name='grafana-agent', namespace='')`: Create a new Agent without a - controller. -- `withDeploymentController(replicas=1)`: Attach a Deployment as the Agent - controller. Number of replicas may optionally be given. -- `withDaemonSetController()`: Attach a DaemonSet as the Agent controller. -- `withStatefulSetController(replicas=1, volumeClaims=[])`: Attach a StatefulSet - as the Agent controller. Number of replicas and a set of volume claim - templates may be given. - -## Generate Scraping Service Syncer - -The Scraping Service Syncer is used to sync metrics instance configs against the -scraping service config management API. - -- `newSyncer(name='grafana-agent-sycner', namespace='', config={})` - -## General - -- `withAgentConfig(config)`: Provide a custom Agent config. -- `withArgsMixin(config)`: Pass a map of additional flags to set. -- `withMetricsPort(port)`: Value for the `http-metrics` port (default 80) -- `withImagesMixin(images)`: Use custom images instead of the defaults. -- `withConfigHash(include=true)`: Whether to include a config hash annotation. -- `withPortsMixin(ports=[])`: Mixin ports from `k.core.v1.containerPort` against - the container and service. -- `withVolumesMixin(volumes=[])`: Volume to attach to the pod. -- `withVolumeMountsMixin(mounts=[])`: Volume mounts to attach to the container. - -## Helpers - -- `newKubernetesMetrics(config={})`: Creates a set of metrics scrape_configs for - collecting metrics from Kubernetes pods. -- `newKubernetesLogs(config={})`: Creates a set of logs scrape_configs for - collecting logs from Kubernetes pods. -- `newKubernetesTraces(config={})`: Creates a set of traces scrape_configs for - associating spans with metadata from discovered Kubernetes pods. -- `withLogVolumeMounts(config={})`: Adds volume mounts to the controller for collecting - logs. -- `withLogPermissions(config={})`: Runs the container as privileged and as the root user - so logs can be collected properly. -- `withService(config)`: Add a service for the deployment, statefulset, or daemonset. - Note that this must be called after any ports are added via `withPortsMixin`. - - diff --git a/production/tanka/grafana-agent/v2/internal/base.libsonnet b/production/tanka/grafana-agent/v2/internal/base.libsonnet deleted file mode 100644 index 6d697c93a3aa..000000000000 --- a/production/tanka/grafana-agent/v2/internal/base.libsonnet +++ /dev/null @@ -1,56 +0,0 @@ -function(name='grafana-agent', namespace='') { - local k = (import 'ksonnet-util/kausal.libsonnet') { _config+:: { namespace: namespace } }, - - local container = k.core.v1.container, - local configMap = k.core.v1.configMap, - local containerPort = k.core.v1.containerPort, - local policyRule = k.rbac.v1.policyRule, - local serviceAccount = k.core.v1.serviceAccount, - local envVar = k.core.v1.envVar, - - local this = self, - - _images:: { - agent: 'grafana/agent:v0.39.0', - agentctl: 'grafana/agentctl:v0.39.0', - }, - _config:: { - name: name, - namespace: namespace, - config_hash: true, - agent_config: '', - agent_port: 80, - agent_args: { - 'config.file': '/etc/agent/agent.yaml', - 'server.http.address': '0.0.0.0:80', - 'config.expand-env': 'true', - }, - }, - - rbac: k.util.rbac(name, [ - policyRule.withApiGroups(['']) + - policyRule.withResources(['nodes', 'nodes/proxy', 'services', 'endpoints', 'pods', 'events']) + - policyRule.withVerbs(['get', 'list', 'watch']), - - policyRule.withNonResourceUrls('/metrics') + - policyRule.withVerbs(['get']), - ]) { - service_account+: serviceAccount.mixin.metadata.withNamespace(namespace), - }, - - configMap: - configMap.new(name) + - configMap.mixin.metadata.withNamespace(namespace) + - configMap.withData({ - 'agent.yaml': k.util.manifestYaml(this._config.agent_config), - }), - - container:: - container.new(name, this._images.agent) + - container.withPorts(containerPort.new('http-metrics', this._config.agent_port)) + - container.withArgsMixin(k.util.mapToFlags(this._config.agent_args)) + - // `HOSTNAME` is required for promtail (logs) otherwise it will silently do nothing - container.withEnvMixin([ - envVar.fromFieldPath('HOSTNAME', 'spec.nodeName'), - ]), -} diff --git a/production/tanka/grafana-agent/v2/internal/controllers/daemonset.libsonnet b/production/tanka/grafana-agent/v2/internal/controllers/daemonset.libsonnet deleted file mode 100644 index 5e5f8880a2a4..000000000000 --- a/production/tanka/grafana-agent/v2/internal/controllers/daemonset.libsonnet +++ /dev/null @@ -1,22 +0,0 @@ -function() { - local this = self, - local _config = this._config, - local name = _config.name, - local namespace = _config.namespace, - - local k = (import 'ksonnet-util/kausal.libsonnet') { _config+:: this._config }, - local daemonSet = k.apps.v1.daemonSet, - - controller: - daemonSet.new(name, [this.container]) + - daemonSet.mixin.metadata.withNamespace(namespace) + - daemonSet.mixin.spec.template.spec.withServiceAccountName(name) + - ( - if _config.config_hash - then daemonSet.mixin.spec.template.metadata.withAnnotationsMixin({ - config_hash: std.md5(std.toString(_config.agent_config)), - }) - else {} - ) + - k.util.configVolumeMount(name, '/etc/agent'), -} diff --git a/production/tanka/grafana-agent/v2/internal/controllers/deployment.libsonnet b/production/tanka/grafana-agent/v2/internal/controllers/deployment.libsonnet deleted file mode 100644 index 5afbe9923118..000000000000 --- a/production/tanka/grafana-agent/v2/internal/controllers/deployment.libsonnet +++ /dev/null @@ -1,22 +0,0 @@ -function(replicas=1) { - local this = self, - local _config = this._config, - local name = _config.name, - local namespace = _config.namespace, - - local k = (import 'ksonnet-util/kausal.libsonnet') { _config+:: this._config }, - local deployment = k.apps.v1.deployment, - - controller: - deployment.new(name, replicas, [this.container]) + - deployment.mixin.metadata.withNamespace(namespace) + - deployment.mixin.spec.template.spec.withServiceAccountName(name) + - ( - if _config.config_hash - then deployment.mixin.spec.template.metadata.withAnnotationsMixin({ - config_hash: std.md5(std.toString(_config.agent_config)), - }) - else {} - ) + - k.util.configVolumeMount(name, '/etc/agent'), -} diff --git a/production/tanka/grafana-agent/v2/internal/controllers/statefulset.libsonnet b/production/tanka/grafana-agent/v2/internal/controllers/statefulset.libsonnet deleted file mode 100644 index d80cab383bc5..000000000000 --- a/production/tanka/grafana-agent/v2/internal/controllers/statefulset.libsonnet +++ /dev/null @@ -1,23 +0,0 @@ -function(replicas=1, volumeClaims=[]) { - local this = self, - local _config = this._config, - local name = _config.name, - local namespace = _config.namespace, - - local k = (import 'ksonnet-util/kausal.libsonnet') { _config+:: this._config }, - local statefulSet = k.apps.v1.statefulSet, - - controller: - statefulSet.new(name, replicas, [this.container], volumeClaims) + - statefulSet.mixin.metadata.withNamespace(namespace) + - statefulSet.mixin.spec.withServiceName(name) + - statefulSet.mixin.spec.template.spec.withServiceAccountName(name) + - ( - if _config.config_hash - then statefulSet.mixin.spec.template.metadata.withAnnotationsMixin({ - config_hash: std.md5(std.toString(_config.agent_config)), - }) - else {} - ) + - k.util.configVolumeMount(name, '/etc/agent'), -} diff --git a/production/tanka/grafana-agent/v2/internal/helpers/k8s.libsonnet b/production/tanka/grafana-agent/v2/internal/helpers/k8s.libsonnet deleted file mode 100644 index 5ae43c901a6c..000000000000 --- a/production/tanka/grafana-agent/v2/internal/helpers/k8s.libsonnet +++ /dev/null @@ -1,523 +0,0 @@ -local k8s_tls_config(config) = { - tls_config: { - ca_file: '/var/run/secrets/kubernetes.io/serviceaccount/ca.crt', - insecure_skip_verify: config.insecure_skip_verify, - }, - bearer_token_file: '/var/run/secrets/kubernetes.io/serviceaccount/token', -}; - -local gen_scrape_config(job_name, pod_uid) = { - job_name: job_name, - pipeline_stages: [{ - docker: {}, - }], - kubernetes_sd_configs: [{ - role: 'pod', - }], - - relabel_configs: self.prelabel_config + [ - // Only scrape local pods; Promtail will drop targets with a __host__ label - // that does not match the current host name. - { - source_labels: ['__meta_kubernetes_pod_node_name'], - target_label: '__host__', - }, - - // Drop pods without a __service__ label. - { - source_labels: ['__service__'], - action: 'drop', - regex: '', - }, - - // Include all the other labels on the pod. - // Perform this mapping before applying additional label replacement rules - // to prevent a supplied label from overwriting any of the following labels. - { - action: 'labelmap', - regex: '__meta_kubernetes_pod_label_(.+)', - }, - - // Rename jobs to be /. - { - source_labels: ['__meta_kubernetes_namespace', '__service__'], - action: 'replace', - separator: '/', - target_label: 'job', - replacement: '$1', - }, - - // But also include the namespace, pod, container as separate - // labels. They uniquely identify a container. They are also - // identical to the target labels configured in Prometheus - // (but note that Loki does not use an instance label). - { - source_labels: ['__meta_kubernetes_namespace'], - action: 'replace', - target_label: 'namespace', - }, - { - source_labels: ['__meta_kubernetes_pod_name'], - action: 'replace', - target_label: 'pod', // Not 'pod_name', which disappeared in K8s 1.16. - }, - { - source_labels: ['__meta_kubernetes_pod_container_name'], - action: 'replace', - target_label: 'container', // Not 'container_name', which disappeared in K8s 1.16. - }, - - // Kubernetes puts logs under subdirectories keyed pod UID and container_name. - { - source_labels: [pod_uid, '__meta_kubernetes_pod_container_name'], - target_label: '__path__', - separator: '/', - replacement: '/var/log/pods/*$1/*.log', - }, - ], -}; - -{ - metrics(config):: - local _config = { - scrape_api_server_endpoints: false, - insecure_skip_verify: false, - - cluster_dns_tld: 'local', - cluster_dns_suffix: 'cluster.' + self.cluster_dns_tld, - kubernetes_api_server_address: 'kubernetes.default.svc.%(cluster_dns_suffix)s:443' % self, - - ksm_namespace: 'kube-system', - node_exporter_namespace: 'kube-system', - } + config; - - [ - k8s_tls_config(_config) { - job_name: 'default/kubernetes', - kubernetes_sd_configs: [{ - role: if _config.scrape_api_server_endpoints then 'endpoints' else 'service', - }], - scheme: 'https', - tls_config+: { - server_name: 'kubernetes', - }, - - relabel_configs: [{ - source_labels: ['__meta_kubernetes_service_label_component'], - regex: 'apiserver', - action: 'keep', - }], - - // Keep limited set of metrics to reduce default usage, drop all others - metric_relabel_configs: [ - { - source_labels: ['__name__'], - regex: 'workqueue_queue_duration_seconds_bucket|process_cpu_seconds_total|process_resident_memory_bytes|workqueue_depth|rest_client_request_duration_seconds_bucket|workqueue_adds_total|up|rest_client_requests_total|apiserver_request_total|go_goroutines', - action: 'keep', - }, - ], - }, - - { - job_name: 'kubernetes-pods', - kubernetes_sd_configs: [{ - role: 'pod', - }], - - // You can specify the following annotations (on pods): - // prometheus.io/scrape: false - don't scrape this pod - // prometheus.io/scheme: https - use https for scraping - // prometheus.io/port - scrape this port - // prometheus.io/path - scrape this path - // prometheus.io/param- - send ?parameter=value with the scrape - relabel_configs: [ - // Drop anything annotated with prometheus.io/scrape=false - { - source_labels: ['__meta_kubernetes_pod_annotation_prometheus_io_scrape'], - action: 'drop', - regex: 'false', - }, - - // Drop any endpoint whose pod port name does not end with metrics - { - source_labels: ['__meta_kubernetes_pod_container_port_name'], - action: 'keep', - regex: '.*-metrics', - }, - - // Allow pods to override the scrape scheme with prometheus.io/scheme=https - { - source_labels: ['__meta_kubernetes_pod_annotation_prometheus_io_scheme'], - action: 'replace', - target_label: '__scheme__', - regex: '(https?)', - replacement: '$1', - }, - - // Allow service to override the scrape path with prometheus.io/path=/other_metrics_path - { - source_labels: ['__meta_kubernetes_pod_annotation_prometheus_io_path'], - action: 'replace', - target_label: '__metrics_path__', - regex: '(.+)', - replacement: '$1', - }, - - // Allow services to override the scrape port with prometheus.io/port=1234 - { - source_labels: ['__address__', '__meta_kubernetes_pod_annotation_prometheus_io_port'], - action: 'replace', - target_label: '__address__', - regex: '(.+?)(\\:\\d+)?;(\\d+)', - replacement: '$1:$3', - }, - - // Drop pods without a name label - { - source_labels: ['__meta_kubernetes_pod_label_name'], - action: 'drop', - regex: '', - }, - - // Rename jobs to be / - { - source_labels: ['__meta_kubernetes_namespace', '__meta_kubernetes_pod_label_name'], - action: 'replace', - separator: '/', - target_label: 'job', - replacement: '$1', - }, - - // But also include the namespace as a separate label for routing alerts - { - source_labels: ['__meta_kubernetes_namespace'], - action: 'replace', - target_label: 'namespace', - }, - { - source_labels: ['__meta_kubernetes_pod_name'], - action: 'replace', - target_label: 'pod', // Not 'pod_name', which disappeared in K8s 1.16. - }, - { - source_labels: ['__meta_kubernetes_pod_container_name'], - action: 'replace', - target_label: 'container', // Not 'container_name', which disappeared in K8s 1.16. - }, - - // Rename instances to the concatenation of pod:container:port. - // All three components are needed to guarantee a unique instance label. - { - source_labels: [ - '__meta_kubernetes_pod_name', - '__meta_kubernetes_pod_container_name', - '__meta_kubernetes_pod_container_port_name', - ], - action: 'replace', - separator: ':', - target_label: 'instance', - }, - - // Map prometheus.io/param-=value fields to __param_=value - { - regex: '__meta_kubernetes_pod_annotation_prometheus_io_param_(.+)', - action: 'labelmap', - replacement: '__param_$1', - }, - - // Drop pods with phase Succeeded or Failed - { - source_labels: ['__meta_kubernetes_pod_phase'], - action: 'drop', - regex: 'Succeeded|Failed', - }, - ], - }, - - // A separate scrape config for kube-state-metrics which doesn't add a - // namespace label and instead takes the namespace label from the exported - // timeseries. This prevents the exported namespace label from being - // renamed to exported_namesapce and allows us to route alerts based on - // namespace. - { - job_name: '%s/kube-state-metrics' % _config.ksm_namespace, - kubernetes_sd_configs: [{ - role: 'pod', - namespaces: { - names: [_config.ksm_namespace], - }, - }], - - relabel_configs: [ - // Drop anything whose service is not kube-state-metrics - { - source_labels: ['__meta_kubernetes_pod_label_name'], - regex: 'kube-state-metrics', - action: 'keep', - }, - - // Rename instances to the concatenation of pod:container:port. - // In the specific case of KSM, we could leave out the container - // name and still have a unique instance label, but we leave it - // in here for consistency with the normal pod scraping. - { - source_labels: [ - '__meta_kubernetes_pod_name', - '__meta_kubernetes_pod_container_name', - '__meta_kubernetes_pod_container_port_name', - ], - action: 'replace', - separator: ':', - target_label: 'instance', - }, - ], - }, - - // A separate scrape config for node-exporter which maps the node name - // onto the instance label. - { - job_name: '%s/node-exporter' % _config.node_exporter_namespace, - kubernetes_sd_configs: [{ - role: 'pod', - namespaces: { - names: [_config.node_exporter_namespace], - }, - }], - - relabel_configs: [ - // Drop anything whose name is not node-exporter. - { - source_labels: ['__meta_kubernetes_pod_label_name'], - regex: 'node-exporter', - action: 'keep', - }, - - // Rename instances to be the node name. - { - source_labels: ['__meta_kubernetes_pod_node_name'], - action: 'replace', - target_label: 'instance', - }, - - // But also include the namespace as a separate label, for - // routing alerts. - { - source_labels: ['__meta_kubernetes_namespace'], - action: 'replace', - target_label: 'namespace', - }, - ], - }, - - // This scrape config gathers all kubelet metrics. - k8s_tls_config(_config) { - job_name: 'kube-system/kubelet', - kubernetes_sd_configs: [{ role: 'node' }], - - relabel_configs: [ - { - target_label: '__address__', - replacement: _config.kubernetes_api_server_address, - }, - { - target_label: '__scheme__', - replacement: 'https', - }, - { - source_labels: ['__meta_kubernetes_node_name'], - regex: '(.+)', - target_label: '__metrics_path__', - replacement: '/api/v1/nodes/$1/proxy/metrics', - }, - ], - }, - - // As of k8s 1.7.3, cAdvisor metrics are available via kubelet using the - // /metrics/cadvisor path. - k8s_tls_config(_config) { - job_name: 'kube-system/cadvisor', - kubernetes_sd_configs: [{ - role: 'node', - }], - scheme: 'https', - - relabel_configs: [ - { - target_label: '__address__', - replacement: _config.kubernetes_api_server_address, - }, - { - source_labels: ['__meta_kubernetes_node_name'], - regex: '(.+)', - target_label: '__metrics_path__', - replacement: '/api/v1/nodes/$1/proxy/metrics/cadvisor', - }, - ], - - metric_relabel_configs: [ - // Let system processes like kubelet survive the next rule by giving them a fake image. - { - source_labels: ['__name__', 'id'], - regex: 'container_([a-z_]+);/system.slice/(.+)', - target_label: 'image', - replacement: '$2', - }, - - // Drop container_* metrics with no image. - { - source_labels: ['__name__', 'image'], - regex: 'container_([a-z_]+);', - action: 'drop', - }, - - // Drop a bunch of metrics which are disabled but still sent, - // see https://github.com/google/cadvisor/issues/1925. - { - source_labels: ['__name__'], - regex: 'container_(network_tcp_usage_total|network_udp_usage_total|tasks_state|cpu_load_average_10s)', - action: 'drop', - }, - ], - }, - ], - - logs(config={}):: [ - // Scrape config to scrape any pods with a 'name' label. - gen_scrape_config('kubernetes-pods-name', '__meta_kubernetes_pod_uid') { - prelabel_config:: [ - // Use name label as __service__. - { - source_labels: ['__meta_kubernetes_pod_label_name'], - target_label: '__service__', - }, - ], - }, - - // Scrape config to scrape any pods with an 'app' label. - gen_scrape_config('kubernetes-pods-app', '__meta_kubernetes_pod_uid') { - prelabel_config:: [ - // Drop pods with a 'name' label. They will have already been added by - // the scrape_config that matches on the 'name' label - { - source_labels: ['__meta_kubernetes_pod_label_name'], - action: 'drop', - regex: '.+', - }, - - // Use app label as the __service__. - { - source_labels: ['__meta_kubernetes_pod_label_app'], - target_label: '__service__', - }, - ], - }, - - // Scrape config to scrape any pods with a direct controller (eg - // StatefulSets). - gen_scrape_config('kubernetes-pods-direct-controllers', '__meta_kubernetes_pod_uid') { - prelabel_config:: [ - // Drop pods with a 'name' or 'app' label. They will have already been added by - // the scrape_config that matches above. - { - source_labels: ['__meta_kubernetes_pod_label_name', '__meta_kubernetes_pod_label_app'], - separator: '', - action: 'drop', - regex: '.+', - }, - - // Drop pods with an indirect controller. eg Deployments create replicaSets - // which then create pods. - { - source_labels: ['__meta_kubernetes_pod_controller_name'], - action: 'drop', - regex: '[0-9a-z-.]+-[0-9a-f]{8,10}', - }, - - // Use controller name as __service__. - { - source_labels: ['__meta_kubernetes_pod_controller_name'], - target_label: '__service__', - }, - ], - }, - - // Scrape config to scrape any pods with an indirect controller (eg - // Deployments). - gen_scrape_config('kubernetes-pods-indirect-controller', '__meta_kubernetes_pod_uid') { - prelabel_config:: [ - // Drop pods with a 'name' or 'app' label. They will have already been added by - // the scrape_config that matches above. - { - source_labels: ['__meta_kubernetes_pod_label_name', '__meta_kubernetes_pod_label_app'], - separator: '', - action: 'drop', - regex: '.+', - }, - - // Drop pods not from an indirect controller. eg StatefulSets, DaemonSets - { - source_labels: ['__meta_kubernetes_pod_controller_name'], - regex: '[0-9a-z-.]+-[0-9a-f]{8,10}', - action: 'keep', - }, - - // Put the indirect controller name into a temp label. - { - source_labels: ['__meta_kubernetes_pod_controller_name'], - action: 'replace', - regex: '([0-9a-z-.]+)-[0-9a-f]{8,10}', - target_label: '__service__', - }, - ], - }, - - // Scrape config to scrape any control plane static pods (e.g. kube-apiserver - // etcd, kube-controller-manager & kube-scheduler) - gen_scrape_config('kubernetes-pods-static', '__meta_kubernetes_pod_annotation_kubernetes_io_config_mirror') { - prelabel_config:: [ - // Ignore pods that aren't mirror pods - { - action: 'drop', - source_labels: ['__meta_kubernetes_pod_annotation_kubernetes_io_config_mirror'], - regex: '', - }, - - // Static control plane pods usually have a component label that identifies them - { - action: 'replace', - source_labels: ['__meta_kubernetes_pod_label_component'], - target_label: '__service__', - }, - ], - }, - ], - - traces(config={}):: [ - { - bearer_token_file: '/var/run/secrets/kubernetes.io/serviceaccount/token', - job_name: 'kubernetes-pods', - kubernetes_sd_configs: [{ role: 'pod' }], - relabel_configs: [ - { - action: 'replace', - source_labels: ['__meta_kubernetes_namespace'], - target_label: 'namespace', - }, - { - action: 'replace', - source_labels: ['__meta_kubernetes_pod_name'], - target_label: 'pod', - }, - { - action: 'replace', - source_labels: ['__meta_kubernetes_pod_container_name'], - target_label: 'container', - }, - ], - tls_config: { - ca_file: '/var/run/secrets/kubernetes.io/serviceaccount/ca.crt', - insecure_skip_verify: false, - }, - }, - ], -} diff --git a/production/tanka/grafana-agent/v2/internal/helpers/logs.libsonnet b/production/tanka/grafana-agent/v2/internal/helpers/logs.libsonnet deleted file mode 100644 index 30a88b899d5a..000000000000 --- a/production/tanka/grafana-agent/v2/internal/helpers/logs.libsonnet +++ /dev/null @@ -1,27 +0,0 @@ -local k = import 'ksonnet-util/kausal.libsonnet'; -local container = k.core.v1.container; - -{ - volumeMounts(config={}):: { - // Disable journald mount by default - local _config = { - journald: false, - } + config, - - controller+: - // For reading docker containers. /var/log is used for the positions file - // and shouldn't be set to readonly. - k.util.hostVolumeMount('varlog', '/var/log', '/var/log') + - k.util.hostVolumeMount('varlibdockercontainers', '/var/lib/docker/containers', '/var/lib/docker/containers', readOnly=true) + - - // For reading journald - if _config.journald == false then {} - else k.util.hostVolumeMount('etcmachineid', '/etc/machine-id', '/etc/machine-id', readOnly=true), - }, - - permissions(config={}):: { - container+:: - container.mixin.securityContext.withPrivileged(true) + - container.mixin.securityContext.withRunAsUser(0), - }, -} diff --git a/production/tanka/grafana-agent/v2/internal/helpers/service.libsonnet b/production/tanka/grafana-agent/v2/internal/helpers/service.libsonnet deleted file mode 100644 index 08f6502fa8ef..000000000000 --- a/production/tanka/grafana-agent/v2/internal/helpers/service.libsonnet +++ /dev/null @@ -1,13 +0,0 @@ -local k = import 'ksonnet-util/kausal.libsonnet'; -local svc = k.core.v1.service; - -{ - service(config={}):: { - local this = self, - local _config = this._config, - - controller_service: - k.util.serviceFor(this.controller) + - svc.mixin.metadata.withNamespace(_config.namespace), - }, -} diff --git a/production/tanka/grafana-agent/v2/internal/syncer.libsonnet b/production/tanka/grafana-agent/v2/internal/syncer.libsonnet deleted file mode 100644 index 79409f65f310..000000000000 --- a/production/tanka/grafana-agent/v2/internal/syncer.libsonnet +++ /dev/null @@ -1,62 +0,0 @@ -local k = import 'ksonnet-util/kausal.libsonnet'; - -local cronJob = k.batch.v1.cronJob; -local configMap = k.core.v1.configMap; -local container = k.core.v1.container; -local deployment = k.apps.v1.deployment; -local volumeMount = k.core.v1.volumeMount; -local volume = k.core.v1.volume; - -function( - name='grafana-agent-syncer', - namespace='', - config={}, -) { - local _config = { - api: error 'api must be set', - image: 'grafana/agentctl:v0.39.0', - schedule: '*/5 * * * *', - configs: [], - } + config, - - local this = self, - local _configs = std.foldl( - function(agg, cfg) - // Sanitize the name and remove / so every file goes into the same - // folder. - local name = std.strReplace(cfg.name, '/', '_'); - - agg { ['%s.yml' % name]: k.util.manifestYaml(cfg) }, - _config.configs, - {}, - ), - - configMap: - configMap.new(name) + - configMap.mixin.metadata.withNamespace(namespace) + - configMap.withData(_configs), - - container:: - container.new(name, _config.image) + - container.withArgsMixin([ - 'config-sync', - '--addr=%s' % _config.api, - '/etc/configs', - ]) + - container.withVolumeMounts(volumeMount.new(name, '/etc/configs')), - - job: - cronJob.new(name, _config.schedule, this.container) + - cronJob.mixin.metadata.withNamespace(namespace) + - cronJob.mixin.spec.withSuccessfulJobsHistoryLimit(1) + - cronJob.mixin.spec.withFailedJobsHistoryLimit(3) + - cronJob.mixin.spec.jobTemplate.spec.template.spec.withRestartPolicy('OnFailure') + - cronJob.mixin.spec.jobTemplate.spec.template.spec.withActiveDeadlineSeconds(600) + - cronJob.mixin.spec.jobTemplate.spec.withTtlSecondsAfterFinished(120) + - cronJob.mixin.spec.jobTemplate.spec.template.spec.withVolumes([ - volume.fromConfigMap( - name=name, - configMapName=this.configMap.metadata.name, - ), - ]), -} diff --git a/production/tanka/grafana-agent/v2/main.libsonnet b/production/tanka/grafana-agent/v2/main.libsonnet deleted file mode 100644 index 71a8e4b69f6d..000000000000 --- a/production/tanka/grafana-agent/v2/main.libsonnet +++ /dev/null @@ -1,50 +0,0 @@ -local k = import 'ksonnet-util/kausal.libsonnet'; -local container = k.core.v1.container; -local podTemplateSpec = k.core.v1.podTemplateSpec.spec; - -{ - new(name='grafana-agent', namespace=''):: - (import './internal/base.libsonnet')(name, namespace), - - // Controllers - withDeploymentController(replicas=1):: - (import './internal/controllers/deployment.libsonnet')(replicas), - withDaemonSetController():: - (import './internal/controllers/daemonset.libsonnet')(), - withStatefulSetController(replicas=1, volumeClaims=[]):: - (import './internal/controllers/statefulset.libsonnet')(replicas, volumeClaims), - - // Syncer - newSyncer(name='grafana-agent-syncer', namespace='', config={}):: - (import './internal/syncer.libsonnet')(name, namespace, config), - - // General - withAgentConfig(config):: { _config+: { agent_config: config } }, - withMetricsPort(port):: { _config+: { agent_port: port } }, - withArgsMixin(args):: { _config+: { agent_args+: args } }, - withImagesMixin(images):: { _images+: images }, - withConfigHash(include=true):: { _config+: { config_hash: include } }, - withPortsMixin(ports=[]):: { container+:: container.withPortsMixin(ports) }, - withVolumeMountsMixin(mounts=[]):: { container+:: container.withVolumeMountsMixin(mounts) }, - withVolumesMixin(volumes=[]):: { - controller+: { - spec+: { - template+: podTemplateSpec.withVolumesMixin(volumes), - }, - }, - }, - - // Helpers - newKubernetesMetrics(config={}):: - (import './internal/helpers/k8s.libsonnet').metrics(config), - newKubernetesLogs(config={}):: - (import './internal/helpers/k8s.libsonnet').logs(config), - newKubernetesTraces(config={}):: - (import './internal/helpers/k8s.libsonnet').traces(config), - withLogVolumeMounts(config={}):: - (import './internal/helpers/logs.libsonnet').volumeMounts(config), - withLogPermissions(config={}):: - (import './internal/helpers/logs.libsonnet').permissions(config), - withService(config={}):: - (import './internal/helpers/service.libsonnet').service(config), -} diff --git a/tools/generate-crds.bash b/tools/generate-crds.bash index f4280c05a638..4a46f884c657 100755 --- a/tools/generate-crds.bash +++ b/tools/generate-crds.bash @@ -6,18 +6,18 @@ ROOT=$(git rev-parse --show-toplevel) # Generate objects and controllers for our CRDs cd $ROOT/pkg/operator/apis/monitoring/v1alpha1 controller-gen object paths=. -controller-gen crd:crdVersions=v1 paths=. output:crd:dir=$ROOT/production/operator/crds +controller-gen crd:crdVersions=v1 paths=. output:crd:dir=$ROOT/operations/agent-static-operator/crds # Generate CRDs for prometheus-operator. PROM_OP_DEP_NAME="github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" PROM_OP_DIR=$(go list -f '{{.Dir}}' $PROM_OP_DEP_NAME) cd $PROM_OP_DIR -controller-gen crd:crdVersions=v1 paths=. output:crd:dir=$ROOT/production/operator/crds +controller-gen crd:crdVersions=v1 paths=. output:crd:dir=$ROOT/operations/agent-static-operator/crds # Remove known Prometheus-Operator CRDS we don't generate. (An allowlist would # be better here, but rfratto's bash skills are bad.) -rm -f $ROOT/production/operator/crds/monitoring.coreos.com_alertmanagers.yaml -rm -f $ROOT/production/operator/crds/monitoring.coreos.com_prometheuses.yaml -rm -f $ROOT/production/operator/crds/monitoring.coreos.com_prometheusrules.yaml -rm -f $ROOT/production/operator/crds/monitoring.coreos.com_thanosrulers.yaml +rm -f $ROOT/operations/agent-static-operator/crds/monitoring.coreos.com_alertmanagers.yaml +rm -f $ROOT/operations/agent-static-operator/crds/monitoring.coreos.com_prometheuses.yaml +rm -f $ROOT/operations/agent-static-operator/crds/monitoring.coreos.com_prometheusrules.yaml +rm -f $ROOT/operations/agent-static-operator/crds/monitoring.coreos.com_thanosrulers.yaml From 28a8f20c22dd115a91addef4f5cace159212439a Mon Sep 17 00:00:00 2001 From: Piotr <17101802+thampiotr@users.noreply.github.com> Date: Thu, 11 Jan 2024 14:28:35 +0000 Subject: [PATCH 52/68] Add a link between docs guidelines (#6111) * Update writing-docs.md Add a link to reference docs guide. * Update writing-docs.md --- docs/developer/writing-docs.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/developer/writing-docs.md b/docs/developer/writing-docs.md index 7cd9be07eed3..b4c5be583024 100644 --- a/docs/developer/writing-docs.md +++ b/docs/developer/writing-docs.md @@ -66,6 +66,9 @@ The Reference section is a collection of pages that describe the Agent components and their configuration options exhaustively. This is a more narrow definition than the one found in the [writer's toolkit][]. +We have a dedicated page with the best practices for writing Reference +docs: [writing flow components documentation][writing-flow-docs]. + This is our most detailed documentation, and it should be used as a source of truth. The contents of the Reference pages should not be repeated in other parts of the documentation. @@ -76,3 +79,4 @@ Release notes contain all the notable changes in the Agent. They are updated as part of the release process. [writer's toolkit]: https://grafana.com/docs/writers-toolkit/structure/topic-types/ +[writing-flow-docs]: writing-flow-component-documentation.md From 2ba44881acb1f59f8467172f7ecb24bd7c3c5c76 Mon Sep 17 00:00:00 2001 From: Piotr <17101802+thampiotr@users.noreply.github.com> Date: Thu, 11 Jan 2024 14:50:17 +0000 Subject: [PATCH 53/68] Docs: Rename 'Setup' to 'Get started' and 'Start' to 'Run' (#6112) * Rename 'Setup' to 'Get started' and fix links * Fix links * fix links * Rename 'start' folder to 'run' --- docs/sources/flow/_index.md | 2 +- docs/sources/flow/get-started/_index.md | 25 ++++++++++++++++++ .../{setup => get-started}/deploy-agent.md | 10 +++++-- .../{setup => get-started}/install/_index.md | 8 +++++- .../{setup => get-started}/install/binary.md | 16 ++++++++---- .../{setup => get-started}/install/docker.md | 10 +++++-- .../install/kubernetes.md | 10 +++++-- .../{setup => get-started}/install/linux.md | 16 ++++++++---- .../{setup => get-started}/install/macos.md | 16 ++++++++---- .../{setup => get-started}/install/windows.md | 16 ++++++++---- .../start => get-started/run}/_index.md | 26 +++++++++---------- .../start => get-started/run}/binary.md | 24 ++++++++--------- .../{setup/start => get-started/run}/linux.md | 20 +++++++------- .../{setup/start => get-started/run}/macos.md | 20 +++++++------- .../start => get-started/run}/windows.md | 20 +++++++------- .../otelcol.exporter.loadbalancing.md | 2 +- docs/sources/flow/setup/_index.md | 18 ------------- .../flow/tasks/configure-agent-clustering.md | 4 +-- docs/sources/flow/tasks/configure/_index.md | 4 +-- docs/sources/flow/tasks/debug.md | 4 +-- .../flow/tasks/estimate-resource-usage.md | 2 +- .../flow/tasks/migrate/from-operator.md | 8 +++--- .../flow/tasks/migrate/from-prometheus.md | 8 +++--- .../flow/tasks/migrate/from-promtail.md | 8 +++--- .../sources/flow/tasks/migrate/from-static.md | 8 +++--- docs/sources/shared/wal-data-retention.md | 2 +- 26 files changed, 181 insertions(+), 126 deletions(-) create mode 100644 docs/sources/flow/get-started/_index.md rename docs/sources/flow/{setup => get-started}/deploy-agent.md (87%) rename docs/sources/flow/{setup => get-started}/install/_index.md (73%) rename docs/sources/flow/{setup => get-started}/install/binary.md (65%) rename docs/sources/flow/{setup => get-started}/install/docker.md (85%) rename docs/sources/flow/{setup => get-started}/install/kubernetes.md (79%) rename docs/sources/flow/{setup => get-started}/install/linux.md (80%) rename docs/sources/flow/{setup => get-started}/install/macos.md (71%) rename docs/sources/flow/{setup => get-started}/install/windows.md (80%) rename docs/sources/flow/{setup/start => get-started/run}/_index.md (55%) rename docs/sources/flow/{setup/start => get-started/run}/binary.md (83%) rename docs/sources/flow/{setup/start => get-started/run}/linux.md (77%) rename docs/sources/flow/{setup/start => get-started/run}/macos.md (80%) rename docs/sources/flow/{setup/start => get-started/run}/windows.md (73%) delete mode 100644 docs/sources/flow/setup/_index.md diff --git a/docs/sources/flow/_index.md b/docs/sources/flow/_index.md index 4262238f9020..1b95fbe29ae8 100644 --- a/docs/sources/flow/_index.md +++ b/docs/sources/flow/_index.md @@ -85,7 +85,7 @@ This feature is experimental, and it doesn't support all River components. * Check out our [Reference][] documentation to find specific information you might be looking for. -[Install]: {{< relref "./setup/install/" >}} +[Install]: {{< relref "./get-started/install/" >}} [Concepts]: {{< relref "./concepts/" >}} [Tasks]: {{< relref "./tasks/" >}} [Tutorials]: {{< relref "./tutorials/ ">}} diff --git a/docs/sources/flow/get-started/_index.md b/docs/sources/flow/get-started/_index.md new file mode 100644 index 000000000000..80b48bfdaece --- /dev/null +++ b/docs/sources/flow/get-started/_index.md @@ -0,0 +1,25 @@ +--- +aliases: +- /docs/grafana-cloud/agent/flow/get-started/ +- /docs/grafana-cloud/monitor-infrastructure/agent/flow/get-started/ +- /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/get-started/ +- /docs/grafana-cloud/send-data/agent/flow/get-started/ +# Previous docs aliases for backwards compatibility: +- /docs/grafana-cloud/agent/flow/setup/ +- /docs/grafana-cloud/monitor-infrastructure/agent/flow/setup/ +- /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/setup/ +- /docs/grafana-cloud/send-data/agent/flow/setup/ +- ./setup/ # /docs/agent/latest/flow/setup/ +canonical: https://grafana.com/docs/agent/latest/flow/get-started/ +description: Learn how to install and use Grafana Agent Flow +menuTitle: Get started +title: Get started with Grafana Agent Flow +weight: 50 +--- + +# Get started with {{% param "PRODUCT_NAME" %}} + +This section covers topics that help you get started with {{< param "PRODUCT_NAME" >}}, +including installation, running the agent, overview of deployment topologies, and more. + +{{< section >}} diff --git a/docs/sources/flow/setup/deploy-agent.md b/docs/sources/flow/get-started/deploy-agent.md similarity index 87% rename from docs/sources/flow/setup/deploy-agent.md rename to docs/sources/flow/get-started/deploy-agent.md index 0396b537123c..0a76e62c42df 100644 --- a/docs/sources/flow/setup/deploy-agent.md +++ b/docs/sources/flow/get-started/deploy-agent.md @@ -1,12 +1,18 @@ --- aliases: +- /docs/grafana-cloud/agent/flow/get-started/deploy-agent/ +- /docs/grafana-cloud/monitor-infrastructure/agent/flow/get-started/deploy-agent/ +- /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/get-started/deploy-agent/ +- /docs/grafana-cloud/send-data/agent/flow/get-started/deploy-agent/ +# Previous docs aliases for backwards compatibility: - /docs/grafana-cloud/agent/flow/setup/deploy-agent/ - /docs/grafana-cloud/monitor-infrastructure/agent/flow/setup/deploy-agent/ - /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/setup/deploy-agent/ - /docs/grafana-cloud/send-data/agent/flow/setup/deploy-agent/ -canonical: https://grafana.com/docs/agent/latest/flow/setup/deploy-agent/ +- ../setup/deploy-agent/ # /docs/agent/latest/flow/setup/deploy-agent/ +canonical: https://grafana.com/docs/agent/latest/flow/get-started/deploy-agent/ description: Learn about possible deployment topologies for Grafana Agent Flow -menuTitle: Deploy Grafana Agent Flow +menuTitle: Deploy title: Grafana Agent Flow deployment topologies weight: 900 --- diff --git a/docs/sources/flow/setup/install/_index.md b/docs/sources/flow/get-started/install/_index.md similarity index 73% rename from docs/sources/flow/setup/install/_index.md rename to docs/sources/flow/get-started/install/_index.md index c9bb81a239b4..dabb07857d74 100644 --- a/docs/sources/flow/setup/install/_index.md +++ b/docs/sources/flow/get-started/install/_index.md @@ -1,11 +1,17 @@ --- aliases: +- /docs/grafana-cloud/agent/flow/get-started/install/ +- /docs/grafana-cloud/monitor-infrastructure/agent/flow/get-started/install/ +- /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/get-started/install/ +- /docs/grafana-cloud/send-data/agent/flow/get-started/install/ +# Previous docs aliases for backwards compatibility: - /docs/grafana-cloud/agent/flow/setup/install/ - /docs/grafana-cloud/monitor-infrastructure/agent/flow/setup/install/ - /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/setup/install/ - /docs/grafana-cloud/send-data/agent/flow/setup/install/ - /docs/sources/flow/install/ -canonical: https://grafana.com/docs/agent/latest/flow/setup/install/ +- ../setup/install/ # /docs/agent/latest/flow/setup/install/ +canonical: https://grafana.com/docs/agent/latest/flow/get-started/install/ description: Learn how to install Grafana Agent Flow menuTitle: Install title: Install Grafana Agent Flow diff --git a/docs/sources/flow/setup/install/binary.md b/docs/sources/flow/get-started/install/binary.md similarity index 65% rename from docs/sources/flow/setup/install/binary.md rename to docs/sources/flow/get-started/install/binary.md index ed55b7e5e873..fa304df0acb2 100644 --- a/docs/sources/flow/setup/install/binary.md +++ b/docs/sources/flow/get-started/install/binary.md @@ -1,11 +1,17 @@ --- aliases: -- ../../install/binary/ +- /docs/grafana-cloud/agent/flow/get-started/install/binary/ +- /docs/grafana-cloud/monitor-infrastructure/agent/flow/get-started/install/binary/ +- /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/get-started/install/binary/ +- /docs/grafana-cloud/send-data/agent/flow/get-started/install/binary/ +# Previous docs aliases for backwards compatibility: +- ../../install/binary/ # /docs/agent/latest/flow/install/binary/ - /docs/grafana-cloud/agent/flow/setup/install/binary/ - /docs/grafana-cloud/monitor-infrastructure/agent/flow/setup/install/binary/ - /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/setup/install/binary/ - /docs/grafana-cloud/send-data/agent/flow/setup/install/binary/ -canonical: https://grafana.com/docs/agent/latest/flow/setup/install/binary/ +- ../../setup/install/binary/ # /docs/agent/latest/flow/setup/install/binary/ +canonical: https://grafana.com/docs/agent/latest/flow/get-started/install/binary/ description: Learn how to install Grafana Agent Flow as a standalone binary menuTitle: Standalone title: Install Grafana Agent Flow as a standalone binary @@ -45,9 +51,9 @@ To download {{< param "PRODUCT_NAME" >}} as a standalone binary, perform the fol ## Next steps -- [Start {{< param "PRODUCT_NAME" >}}][Start] +- [Run {{< param "PRODUCT_NAME" >}}][Run] {{% docs/reference %}} -[Start]: "/docs/agent/ -> /docs/agent//flow/setup/start/binary.md" -[Start]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/setup/start/binary.md" +[Run]: "/docs/agent/ -> /docs/agent//flow/get-started/run/binary.md" +[Run]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/get-started/run/binary.md" {{% /docs/reference %}} diff --git a/docs/sources/flow/setup/install/docker.md b/docs/sources/flow/get-started/install/docker.md similarity index 85% rename from docs/sources/flow/setup/install/docker.md rename to docs/sources/flow/get-started/install/docker.md index 9460ab71a8f3..c7884a6dc21b 100644 --- a/docs/sources/flow/setup/install/docker.md +++ b/docs/sources/flow/get-started/install/docker.md @@ -1,11 +1,17 @@ --- aliases: -- ../../install/docker/ +- /docs/grafana-cloud/agent/flow/get-started/install/docker/ +- /docs/grafana-cloud/monitor-infrastructure/agent/flow/get-started/install/docker/ +- /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/get-started/install/docker/ +- /docs/grafana-cloud/send-data/agent/flow/get-started/install/docker/ +# Previous docs aliases for backwards compatibility: +- ../../install/docker/ # /docs/agent/latest/flow/install/docker/ - /docs/grafana-cloud/agent/flow/setup/install/docker/ - /docs/grafana-cloud/monitor-infrastructure/agent/flow/setup/install/docker/ - /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/setup/install/docker/ - /docs/grafana-cloud/send-data/agent/flow/setup/install/docker/ -canonical: https://grafana.com/docs/agent/latest/flow/setup/install/docker/ +- ../../setup/install/docker/ # /docs/agent/latest/flow/setup/install/docker/ +canonical: https://grafana.com/docs/agent/latest/flow/get-started/install/docker/ description: Learn how to install Grafana Agent Flow on Docker menuTitle: Docker title: Run Grafana Agent Flow in a Docker container diff --git a/docs/sources/flow/setup/install/kubernetes.md b/docs/sources/flow/get-started/install/kubernetes.md similarity index 79% rename from docs/sources/flow/setup/install/kubernetes.md rename to docs/sources/flow/get-started/install/kubernetes.md index 3bd0a3240fbc..9326fce4bf03 100644 --- a/docs/sources/flow/setup/install/kubernetes.md +++ b/docs/sources/flow/get-started/install/kubernetes.md @@ -1,11 +1,17 @@ --- aliases: -- ../../install/kubernetes/ +- /docs/grafana-cloud/agent/flow/get-started/install/kubernetes/ +- /docs/grafana-cloud/monitor-infrastructure/agent/flow/get-started/install/kubernetes/ +- /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/get-started/install/kubernetes/ +- /docs/grafana-cloud/send-data/agent/flow/get-started/install/kubernetes/ +# Previous docs aliases for backwards compatibility: +- ../../install/kubernetes/ # /docs/agent/latest/flow/install/kubernetes/ - /docs/grafana-cloud/agent/flow/setup/install/kubernetes/ - /docs/grafana-cloud/monitor-infrastructure/agent/flow/setup/install/kubernetes/ - /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/setup/install/kubernetes/ - /docs/grafana-cloud/send-data/agent/flow/setup/install/kubernetes/ -canonical: https://grafana.com/docs/agent/latest/flow/setup/install/kubernetes/ +- ../../setup/install/kubernetes/ # /docs/agent/latest/flow/setup/install/kubernetes/ +canonical: https://grafana.com/docs/agent/latest/flow/get-started/install/kubernetes/ description: Learn how to deploy Grafana Agent Flow on Kubernetes menuTitle: Kubernetes title: Deploy Grafana Agent Flow on Kubernetes diff --git a/docs/sources/flow/setup/install/linux.md b/docs/sources/flow/get-started/install/linux.md similarity index 80% rename from docs/sources/flow/setup/install/linux.md rename to docs/sources/flow/get-started/install/linux.md index be7bd6246454..2241aeb78d0a 100644 --- a/docs/sources/flow/setup/install/linux.md +++ b/docs/sources/flow/get-started/install/linux.md @@ -1,11 +1,17 @@ --- aliases: -- ../../install/linux/ +- /docs/grafana-cloud/agent/flow/get-started/install/linux/ +- /docs/grafana-cloud/monitor-infrastructure/agent/flow/get-started/install/linux/ +- /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/get-started/install/linux/ +- /docs/grafana-cloud/send-data/agent/flow/get-started/install/linux/ +# Previous docs aliases for backwards compatibility: +- ../../install/linux/ # /docs/agent/latest/flow/install/linux/ - /docs/grafana-cloud/agent/flow/setup/install/linux/ - /docs/grafana-cloud/monitor-infrastructure/agent/flow/setup/install/linux/ - /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/setup/install/linux/ - /docs/grafana-cloud/send-data/agent/flow/setup/install/linux/ -canonical: https://grafana.com/docs/agent/latest/flow/setup/install/linux/ +- ../../setup/install/linux/ # /docs/agent/latest/flow/setup/install/linux/ +canonical: https://grafana.com/docs/agent/latest/flow/get-started/install/linux/ description: Learn how to install Grafana Agent Flow on Linux menuTitle: Linux title: Install Grafana Agent Flow on Linux @@ -119,12 +125,12 @@ To uninstall {{< param "PRODUCT_NAME" >}} on Linux, run the following commands i ## Next steps -- [Start {{< param "PRODUCT_NAME" >}}][Start] +- [Run {{< param "PRODUCT_NAME" >}}][Run] - [Configure {{< param "PRODUCT_NAME" >}}][Configure] {{% docs/reference %}} -[Start]: "/docs/agent/ -> /docs/agent//flow/setup/start/linux.md" -[Start]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/setup/start/linux.md" +[Run]: "/docs/agent/ -> /docs/agent//flow/get-started/run/linux.md" +[Run]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/get-started/run/linux.md" [Configure]: "/docs/agent/ -> /docs/agent//flow/tasks/configure/configure-linux.md" [Configure]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/tasks/configure/configure-linux.md" {{% /docs/reference %}} diff --git a/docs/sources/flow/setup/install/macos.md b/docs/sources/flow/get-started/install/macos.md similarity index 71% rename from docs/sources/flow/setup/install/macos.md rename to docs/sources/flow/get-started/install/macos.md index 5c61c6c82b95..9903e13ff632 100644 --- a/docs/sources/flow/setup/install/macos.md +++ b/docs/sources/flow/get-started/install/macos.md @@ -1,11 +1,17 @@ --- aliases: -- ../../install/macos/ +- /docs/grafana-cloud/agent/flow/get-started/install/macos/ +- /docs/grafana-cloud/monitor-infrastructure/agent/flow/get-started/install/macos/ +- /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/get-started/install/macos/ +- /docs/grafana-cloud/send-data/agent/flow/get-started/install/macos/ +# Previous docs aliases for backwards compatibility: +- ../../install/macos/ # /docs/agent/latest/flow/install/macos/ - /docs/grafana-cloud/agent/flow/setup/install/macos/ - /docs/grafana-cloud/monitor-infrastructure/agent/flow/setup/install/macos/ - /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/setup/install/macos/ - /docs/grafana-cloud/send-data/agent/flow/setup/install/macos/ -canonical: https://grafana.com/docs/agent/latest/flow/setup/install/macos/ +- ../../setup/install/macos/ # /docs/agent/latest/flow/setup/install/macos/ +canonical: https://grafana.com/docs/agent/latest/flow/get-started/install/macos/ description: Learn how to install Grafana AgentFlow on macOS menuTitle: macOS title: Install Grafana Agent Flow on macOS @@ -66,14 +72,14 @@ brew uninstall grafana-agent-flow ## Next steps -- [Start {{< param "PRODUCT_NAME" >}}][Start] +- [Run {{< param "PRODUCT_NAME" >}}][Run] - [Configure {{< param "PRODUCT_NAME" >}}][Configure] [Homebrew]: https://brew.sh {{% docs/reference %}} -[Start]: "/docs/agent/ -> /docs/agent//flow/setup/start/macos.md" -[Start]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/setup/start/macos.md" +[Run]: "/docs/agent/ -> /docs/agent//flow/get-started/run/macos.md" +[Run]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/get-started/run/macos.md" [Configure]: "/docs/agent/ -> /docs/agent//flow/tasks/configure/configure-macos.md" [Configure]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/tasks/configure/configure-macos.md" {{% /docs/reference %}} diff --git a/docs/sources/flow/setup/install/windows.md b/docs/sources/flow/get-started/install/windows.md similarity index 80% rename from docs/sources/flow/setup/install/windows.md rename to docs/sources/flow/get-started/install/windows.md index 5157967a07e4..2be2fabc6019 100644 --- a/docs/sources/flow/setup/install/windows.md +++ b/docs/sources/flow/get-started/install/windows.md @@ -1,11 +1,17 @@ --- aliases: -- ../../install/windows/ +- /docs/grafana-cloud/agent/flow/get-started/install/windows/ +- /docs/grafana-cloud/monitor-infrastructure/agent/flow/get-started/install/windows/ +- /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/get-started/install/windows/ +- /docs/grafana-cloud/send-data/agent/flow/get-started/install/windows/ +# Previous docs aliases for backwards compatibility: +- ../../install/windows/ # /docs/agent/latest/flow/install/windows/ - /docs/grafana-cloud/agent/flow/setup/install/windows/ - /docs/grafana-cloud/monitor-infrastructure/agent/flow/setup/install/windows/ - /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/setup/install/windows/ - /docs/grafana-cloud/send-data/agent/flow/setup/install/windows/ -canonical: https://grafana.com/docs/agent/latest/flow/setup/install/windows/ +- ../../setup/install/windows/ # /docs/agent/latest/flow/setup/install/windows/ +canonical: https://grafana.com/docs/agent/latest/flow/get-started/install/windows/ description: Learn how to install Grafana Agent Flow on Windows menuTitle: Windows title: Install Grafana Agent Flow on Windows @@ -78,14 +84,14 @@ This includes any configuration files in the installation directory. ## Next steps -- [Start {{< param "PRODUCT_NAME" >}}][Start] +- [Run {{< param "PRODUCT_NAME" >}}][Start] - [Configure {{< param "PRODUCT_NAME" >}}][Configure] [latest]: https://github.com/grafana/agent/releases/latest {{% docs/reference %}} -[Start]: "/docs/agent/ -> /docs/agent//flow/setup/start/windows.md" -[Start]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/setup/start/windows.md" +[Run]: "/docs/agent/ -> /docs/agent//flow/get-started/run/windows.md" +[Run]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/get-started/run/windows.md" [Configure]: "/docs/agent/ -> /docs/agent//flow/tasks/configure/configure-windows.md" [Configure]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/tasks/configure/configure-windows.md" [data collection]: "/docs/agent/ -> /docs/agent//data-collection.md" diff --git a/docs/sources/flow/setup/start/_index.md b/docs/sources/flow/get-started/run/_index.md similarity index 55% rename from docs/sources/flow/setup/start/_index.md rename to docs/sources/flow/get-started/run/_index.md index 0f989a07f56c..f98f8707354f 100644 --- a/docs/sources/flow/setup/start/_index.md +++ b/docs/sources/flow/get-started/run/_index.md @@ -1,24 +1,24 @@ --- aliases: -- /docs/grafana-cloud/agent/flow/setup/start/ -- /docs/grafana-cloud/monitor-infrastructure/agent/flow/setup/start/ -- /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/setup/start/ -- /docs/grafana-cloud/send-data/agent/flow/setup/start/ -- /docs/sources/flow/start/ +- /docs/grafana-cloud/agent/flow/get-started/run/ +- /docs/grafana-cloud/monitor-infrastructure/agent/flow/get-started/run/ +- /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/get-started/run/ +- /docs/grafana-cloud/send-data/agent/flow/get-started/run/ +- /docs/sources/flow/run/ # Previous pages aliases for backwards compatibility: - /docs/grafana-cloud/agent/flow/setup/start-agent/ - /docs/grafana-cloud/monitor-infrastructure/agent/flow/setup/start-agent/ - /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/setup/start-agent/ - /docs/grafana-cloud/send-data/agent/flow/setup/start-agent/ -- ./start-agent/ # /docs/agent/latest/flow/setup/start-agent/ -canonical: https://grafana.com/docs/agent/latest/flow/setup/start/ -description: Learn how to start Grafana Agent Flow -menuTitle: Start -title: Start Grafana Agent Flow +- ../setup/start-agent/ # /docs/agent/latest/flow/setup/start-agent/ +canonical: https://grafana.com/docs/agent/latest/flow/get-started/run/ +description: Learn how to run Grafana Agent Flow +menuTitle: Run +title: Run Grafana Agent Flow weight: 50 --- -# Start {{% param "PRODUCT_NAME" %}} +# Run {{% param "PRODUCT_NAME" %}} Use the following pages to learn how to start, restart, and stop {{< param "PRODUCT_NAME" >}} after it is installed. For installation instructions, refer to [Install {{< param "PRODUCT_NAME" >}}][Install]. @@ -26,6 +26,6 @@ For installation instructions, refer to [Install {{< param "PRODUCT_NAME" >}}][I {{< section >}} {{% docs/reference %}} -[Install]: "/docs/agent/ -> /docs/agent//flow/setup/install/" -[Install]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/setup/install/" +[Install]: "/docs/agent/ -> /docs/agent//flow/get-started/install/" +[Install]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/get-started/install/" {{% /docs/reference %}} diff --git a/docs/sources/flow/setup/start/binary.md b/docs/sources/flow/get-started/run/binary.md similarity index 83% rename from docs/sources/flow/setup/start/binary.md rename to docs/sources/flow/get-started/run/binary.md index 7d931217280a..7f9fda22ff77 100644 --- a/docs/sources/flow/setup/start/binary.md +++ b/docs/sources/flow/get-started/run/binary.md @@ -1,17 +1,17 @@ --- aliases: -- /docs/grafana-cloud/agent/flow/setup/start/binary/ -- /docs/grafana-cloud/monitor-infrastructure/agent/flow/setup/start/binary/ -- /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/setup/start/binary/ -- /docs/grafana-cloud/send-data/agent/flow/setup/start/binary/ -canonical: https://grafana.com/docs/agent/latest/flow/setup/start/binary/ -description: Learn how to start Grafana Agent Flow as a standalone binary + - /docs/grafana-cloud/agent/flow/get-started/run/binary/ + - /docs/grafana-cloud/monitor-infrastructure/agent/flow/get-started/run/binary/ + - /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/get-started/run/binary/ + - /docs/grafana-cloud/send-data/agent/flow/get-started/run/binary/ +canonical: https://grafana.com/docs/agent/latest/flow/get-started/run/binary/ +description: Learn how to run Grafana Agent Flow as a standalone binary menuTitle: Standalone -title: Start Grafana Agent Flow as a standalone binary +title: Run Grafana Agent Flow as a standalone binary weight: 600 --- -# Start {{% param "PRODUCT_NAME" %}} as a standalone binary +# Run {{% param "PRODUCT_NAME" %}} as a standalone binary If you [downloaded][InstallBinary] the standalone binary, you must run {{< param "PRODUCT_NAME" >}} from a terminal or command window. @@ -119,8 +119,8 @@ These steps assume you have a default systemd and {{< param "PRODUCT_NAME" >}} c 1. Use the [Linux][StartLinux] systemd commands to manage your standalone Linux installation of {{< param "PRODUCT_NAME" >}}. {{% docs/reference %}} -[InstallBinary]: "/docs/agent/ -> /docs/agent//flow/setup/install/binary.md" -[InstallBinary]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/flow/setup/install/binary.md" -[StartLinux]: "/docs/agent/ -> /docs/agent//flow/setup/start/linux.md" -[StartLinux]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/flow/setup/start/linux.md" +[InstallBinary]: "/docs/agent/ -> /docs/agent//flow/get-started/install/binary.md" +[InstallBinary]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/flow/get-started/install/binary.md" +[StartLinux]: "/docs/agent/ -> /docs/agent//flow/get-started/run/linux.md" +[StartLinux]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/flow/get-started/run/linux.md" {{% /docs/reference %}} diff --git a/docs/sources/flow/setup/start/linux.md b/docs/sources/flow/get-started/run/linux.md similarity index 77% rename from docs/sources/flow/setup/start/linux.md rename to docs/sources/flow/get-started/run/linux.md index 673f15d2c7a1..1085aaabdf46 100644 --- a/docs/sources/flow/setup/start/linux.md +++ b/docs/sources/flow/get-started/run/linux.md @@ -1,17 +1,17 @@ --- aliases: - - /docs/grafana-cloud/agent/flow/setup/start/linux/ - - /docs/grafana-cloud/monitor-infrastructure/agent/flow/setup/start/linux/ - - /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/setup/start/linux/ - - /docs/grafana-cloud/send-data/agent/flow/setup/start/linux/ -canonical: https://grafana.com/docs/agent/latest/flow/setup/start/linux/ -description: Learn how to start Grafana Agent Flow on Linux + - /docs/grafana-cloud/agent/flow/get-started/run/linux/ + - /docs/grafana-cloud/monitor-infrastructure/agent/flow/get-started/run/linux/ + - /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/get-started/run/linux/ + - /docs/grafana-cloud/send-data/agent/flow/get-started/run/linux/ +canonical: https://grafana.com/docs/agent/latest/flow/get-started/run/linux/ +description: Learn how to run Grafana Agent Flow on Linux menuTitle: Linux -title: Start Grafana Agent Flow on Linux +title: Run Grafana Agent Flow on Linux weight: 300 --- -# Start {{% param "PRODUCT_NAME" %}} on Linux +# Run {{% param "PRODUCT_NAME" %}} on Linux {{< param "PRODUCT_NAME" >}} is [installed][InstallLinux] as a [systemd][] service on Linux. @@ -68,8 +68,8 @@ sudo journalctl -u grafana-agent-flow - [Configure {{< param "PRODUCT_NAME" >}}][Configure] {{% docs/reference %}} -[InstallLinux]: "/docs/agent/ -> /docs/agent//flow/setup/install/linux.md" -[InstallLinux]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/flow/setup/install/linux.md" +[InstallLinux]: "/docs/agent/ -> /docs/agent//flow/get-started/install/linux.md" +[InstallLinux]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/flow/get-started/install/linux.md" [Configure]: "/docs/agent/ -> /docs/agent//flow/tasks/configure/configure-linux.md" [Configure]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/tasks/configure/configure-linux.md" {{% /docs/reference %}} diff --git a/docs/sources/flow/setup/start/macos.md b/docs/sources/flow/get-started/run/macos.md similarity index 80% rename from docs/sources/flow/setup/start/macos.md rename to docs/sources/flow/get-started/run/macos.md index 53fe8b05b22f..8c7a055dd853 100644 --- a/docs/sources/flow/setup/start/macos.md +++ b/docs/sources/flow/get-started/run/macos.md @@ -1,17 +1,17 @@ --- aliases: - - /docs/grafana-cloud/agent/flow/setup/start/macos/ - - /docs/grafana-cloud/monitor-infrastructure/agent/flow/setup/start/macos/ - - /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/setup/start/macos/ - - /docs/grafana-cloud/send-data/agent/flow/setup/start/macos/ -canonical: https://grafana.com/docs/agent/latest/flow/setup/start/macos/ -description: Learn how to start Grafana Agent Flow on macOS + - /docs/grafana-cloud/agent/flow/get-started/run/macos/ + - /docs/grafana-cloud/monitor-infrastructure/agent/flow/get-started/run/macos/ + - /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/get-started/run/macos/ + - /docs/grafana-cloud/send-data/agent/flow/get-started/run/macos/ +canonical: https://grafana.com/docs/agent/latest/flow/get-started/run/macos/ +description: Learn how to run Grafana Agent Flow on macOS menuTitle: macOS -title: Start Grafana Agent Flow on macOS +title: Run Grafana Agent Flow on macOS weight: 400 --- -# Start {{% param "PRODUCT_NAME" %}} on macOS +# Run {{% param "PRODUCT_NAME" %}} on macOS {{< param "PRODUCT_NAME" >}} is [installed][InstallMacOS] as a launchd service on macOS. @@ -60,8 +60,8 @@ refer to your current copy of the {{< param "PRODUCT_NAME" >}} formula to locate - [Configure {{< param "PRODUCT_NAME" >}}][ConfigureMacOS] {{% docs/reference %}} -[InstallMacOS]: "/docs/agent/ -> /docs/agent//flow/setup/install/macos.md" -[InstallMacOS]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/flow/setup/install/macos.md" +[InstallMacOS]: "/docs/agent/ -> /docs/agent//flow/get-started/install/macos.md" +[InstallMacOS]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/flow/get-started/install/macos.md" [ConfigureMacOS]: "/docs/agent/ -> /docs/agent//flow/tasks/configure/configure-macos.md" [ConfigureMacOS]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/tasks/configure/configure-macos.md" [ConfigureService]: "/docs/agent/ -> /docs/agent//flow/tasks/configure/configure-macos.md#configure-the-grafana-agent-flow-service" diff --git a/docs/sources/flow/setup/start/windows.md b/docs/sources/flow/get-started/run/windows.md similarity index 73% rename from docs/sources/flow/setup/start/windows.md rename to docs/sources/flow/get-started/run/windows.md index e586fa075ddc..2ee89710b028 100644 --- a/docs/sources/flow/setup/start/windows.md +++ b/docs/sources/flow/get-started/run/windows.md @@ -1,17 +1,17 @@ --- aliases: - - /docs/grafana-cloud/agent/flow/setup/start/windows/ - - /docs/grafana-cloud/monitor-infrastructure/agent/flow/setup/start/windows/ - - /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/setup/start/windows/ - - /docs/grafana-cloud/send-data/agent/flow/setup/start/windows/ -canonical: https://grafana.com/docs/agent/latest/flow/setup/start/windows/ -description: Learn how to start Grafana Agent Flow on Windows + - /docs/grafana-cloud/agent/flow/get-started/run/windows/ + - /docs/grafana-cloud/monitor-infrastructure/agent/flow/get-started/run/windows/ + - /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/get-started/run/windows/ + - /docs/grafana-cloud/send-data/agent/flow/get-started/run/windows/ +canonical: https://grafana.com/docs/agent/latest/flow/get-started/run/windows/ +description: Learn how to run Grafana Agent Flow on Windows menuTitle: Windows -title: Start Grafana Agent Flow on Windows +title: Run Grafana Agent Flow on Windows weight: 500 --- -# Start {{% param "PRODUCT_NAME" %}} on Windows +# Run {{% param "PRODUCT_NAME" %}} on Windows {{< param "PRODUCT_NAME" >}} is [installed][InstallWindows] as a Windows Service. The service is configured to automatically run on startup. @@ -47,8 +47,8 @@ To view the logs, perform the following steps: - [Configure {{< param "PRODUCT_NAME" >}}][Configure] {{% docs/reference %}} -[InstallWindows]: "/docs/agent/ -> /docs/agent//flow/setup/install/windows.md" -[InstallWindows]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/flow/setup/install/windows.md" +[InstallWindows]: "/docs/agent/ -> /docs/agent//flow/get-started/install/windows.md" +[InstallWindows]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/flow/get-started/install/windows.md" [Configure]: "/docs/agent/ -> /docs/agent//flow/tasks/configure/configure-windows.md" [Configure]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/tasks/configure/configure-windows.md" {{% /docs/reference %}} diff --git a/docs/sources/flow/reference/components/otelcol.exporter.loadbalancing.md b/docs/sources/flow/reference/components/otelcol.exporter.loadbalancing.md index c22c169665b7..4552adce44ce 100644 --- a/docs/sources/flow/reference/components/otelcol.exporter.loadbalancing.md +++ b/docs/sources/flow/reference/components/otelcol.exporter.loadbalancing.md @@ -275,7 +275,7 @@ Name | Type | Description Different {{< param "PRODUCT_NAME" >}} components require different load-balancing strategies. The use of `otelcol.exporter.loadbalancing` is only necessary for [stateful Flow components][stateful-and-stateless-components]. -[stateful-and-stateless-components]: {{< relref "../../setup/deploy-agent.md#stateful-and-stateless-components" >}} +[stateful-and-stateless-components]: {{< relref "../../get-started/deploy-agent.md#stateful-and-stateless-components" >}} ### otelcol.processor.tail_sampling diff --git a/docs/sources/flow/setup/_index.md b/docs/sources/flow/setup/_index.md deleted file mode 100644 index d639fa3eaea1..000000000000 --- a/docs/sources/flow/setup/_index.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -aliases: -- /docs/grafana-cloud/agent/flow/setup/ -- /docs/grafana-cloud/monitor-infrastructure/agent/flow/setup/ -- /docs/grafana-cloud/monitor-infrastructure/integrations/agent/flow/setup/ -- /docs/grafana-cloud/send-data/agent/flow/setup/ -canonical: https://grafana.com/docs/agent/latest/flow/setup/ -description: Learn how to install and configure Grafana Agent Flow -menuTitle: Set up Grafana Agent Flow -title: Set up Grafana Agent Flow -weight: 50 ---- - -# Set up {{% param "PRODUCT_NAME" %}} - -This section includes information that helps you install and configure {{< param "PRODUCT_NAME" >}}. - -{{< section >}} diff --git a/docs/sources/flow/tasks/configure-agent-clustering.md b/docs/sources/flow/tasks/configure-agent-clustering.md index ca67ecd2d608..d8539914fc69 100644 --- a/docs/sources/flow/tasks/configure-agent-clustering.md +++ b/docs/sources/flow/tasks/configure-agent-clustering.md @@ -67,8 +67,8 @@ To configure clustering: [clustering]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/concepts/clustering.md" [beta]: "/docs/agent/ -> /docs/agent//stability.md#beta" [beta]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/stability.md#beta" -[install-helm]: "/docs/agent/ -> /docs/agent//flow/setup/install/kubernetes.md" -[install-helm]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/setup/install/kubernetes.md" +[install-helm]: "/docs/agent/ -> /docs/agent//flow/get-started/install/kubernetes.md" +[install-helm]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/get-started/install/kubernetes.md" [UI]: "/docs/agent/ -> /docs/agent//flow/tasks/debug.md#component-detail-page" [UI]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/tasks/debug.md#component-detail-page" {{% /docs/reference %}} diff --git a/docs/sources/flow/tasks/configure/_index.md b/docs/sources/flow/tasks/configure/_index.md index fc576f8f51a3..c44ea3dc023b 100644 --- a/docs/sources/flow/tasks/configure/_index.md +++ b/docs/sources/flow/tasks/configure/_index.md @@ -31,6 +31,6 @@ This section includes information that helps you configure {{< param "PRODUCT_NA {{< section >}} {{% docs/reference %}} -[Install]: "/docs/agent/ -> /docs/agent//flow/setup/install/" -[Install]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/setup/install/" +[Install]: "/docs/agent/ -> /docs/agent//flow/get-started/install/" +[Install]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/get-started/install/" {{% /docs/reference %}} diff --git a/docs/sources/flow/tasks/debug.md b/docs/sources/flow/tasks/debug.md index 6932d6082f82..331307a58d9b 100644 --- a/docs/sources/flow/tasks/debug.md +++ b/docs/sources/flow/tasks/debug.md @@ -118,8 +118,8 @@ To debug issues when using [clustering][], check for the following symptoms. [logging]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/reference/config-blocks/logging.md" [clustering]: "/docs/agent/ -> /docs/agent//flow/concepts/clustering.md" [clustering]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/concepts/clustering.md" -[install]: "/docs/agent/ -> /docs/agent//flow/setup/install" -[install]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/setup/install" +[install]: "/docs/agent/ -> /docs/agent//flow/get-started/install" +[install]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/get-started/install" [secret]: "/docs/agent/ -> /docs/agent//flow/concepts/config-language/expressions/types_and_values.md#secrets.md" [secret]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/concepts/config-language/expressions/types_and_values.md#secrets.md" [grafana-agent run]: "/docs/agent/ -> /docs/agent//flow/reference/cli/run.md" diff --git a/docs/sources/flow/tasks/estimate-resource-usage.md b/docs/sources/flow/tasks/estimate-resource-usage.md index 6fb8a146f6d9..e7b066d9e8ee 100644 --- a/docs/sources/flow/tasks/estimate-resource-usage.md +++ b/docs/sources/flow/tasks/estimate-resource-usage.md @@ -51,7 +51,7 @@ will broadly apply to other deployment modes. For more information on how to deploy {{% param "PRODUCT_NAME" %}}, see [deploying grafana agent][]. -[deploying grafana agent]: {{< relref "../setup/deploy-agent.md" >}} +[deploying grafana agent]: {{< relref "../get-started/deploy-agent.md" >}} [clustering]: {{< relref "../concepts/clustering.md" >}} ## Loki logs diff --git a/docs/sources/flow/tasks/migrate/from-operator.md b/docs/sources/flow/tasks/migrate/from-operator.md index 306e613bc45a..f035f95484ad 100644 --- a/docs/sources/flow/tasks/migrate/from-operator.md +++ b/docs/sources/flow/tasks/migrate/from-operator.md @@ -283,12 +283,12 @@ The [reference documentation][component documentation] should help convert those {{% docs/reference %}} [clustering]: "/docs/agent/ -> /docs/agent//flow/concepts/clustering" [clustering]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/concepts/clustering" -[deployment guide]: "/docs/agent/ -> /docs/agent//flow/setup/deploy-agent" -[deployment guide]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/flow/setup/deploy-agent" +[deployment guide]: "/docs/agent/ -> /docs/agent//flow/get-started/deploy-agent" +[deployment guide]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/flow/get-started/deploy-agent" [operator guide]: "/docs/agent/ -> /docs/agent//operator/deploy-agent-operator-resources.md#deploy-a-metricsinstance-resource" [operator guide]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/operator/deploy-agent-operator-resources.md#deploy-a-metricsinstance-resource" -[Helm chart]: "/docs/agent/ -> /docs/agent//flow/setup/install/kubernetes" -[Helm chart]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/flow/setup/install/kubernetes" +[Helm chart]: "/docs/agent/ -> /docs/agent//flow/get-started/install/kubernetes" +[Helm chart]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/flow/get-started/install/kubernetes" [remote.kubernetes.secret]: "/docs/agent/ -> /docs/agent//flow/reference/components/remote.kubernetes.secret.md" [remote.kubernetes.secret]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/flow/reference/components/remote.kubernetes.secret.md" [prometheus.remote_write]: "/docs/agent/ -> /docs/agent//flow/reference/components/prometheus.remote_write.md" diff --git a/docs/sources/flow/tasks/migrate/from-prometheus.md b/docs/sources/flow/tasks/migrate/from-prometheus.md index fae212aae6e8..62fef82d3c2d 100644 --- a/docs/sources/flow/tasks/migrate/from-prometheus.md +++ b/docs/sources/flow/tasks/migrate/from-prometheus.md @@ -64,7 +64,7 @@ This conversion will enable you to take full advantage of the many additional fe - _``_: The full path to the Prometheus configuration. - _``_: The full path to output the {{< param "PRODUCT_NAME" >}} configuration. -1. [Start][] {{< param "PRODUCT_NAME" >}} using the new {{< param "PRODUCT_NAME" >}} configuration from _``_: +1. [Run][] {{< param "PRODUCT_NAME" >}} using the new {{< param "PRODUCT_NAME" >}} configuration from _``_: ### Debugging @@ -131,7 +131,7 @@ This allows you to try {{< param "PRODUCT_NAME" >}} without modifying your exist > In this task, you will use the [run][] CLI command to run {{< param "PRODUCT_NAME" >}} > using a Prometheus configuration. -[Start][] {{< param "PRODUCT_NAME" >}} and include the command line flag `--config.format=prometheus`. +[Run][] {{< param "PRODUCT_NAME" >}} and include the command line flag `--config.format=prometheus`. Your configuration file must be a valid Prometheus configuration file rather than a {{< param "PRODUCT_NAME" >}} configuration file. ### Debugging @@ -256,8 +256,8 @@ The following list is specific to the convert command and not {{< param "PRODUCT [convert]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/reference/cli/convert.md" [run]: "/docs/agent/ -> /docs/agent//flow/reference/cli/run.md" [run]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/reference/cli/run.md" -[Start]: "/docs/agent/ -> /docs/agent//flow/setup/start/" -[Start]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/setup/start/" +[Run]: "/docs/agent/ -> /docs/agent//flow/get-started/run/" +[Run]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/get-started/run/" [DebuggingUI]: "/docs/agent/ -> /docs/agent//flow/tasks/debug.md" [DebuggingUI]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/tasks/debug.md" [River]: "/docs/agent/ -> /docs/agent//flow/concepts/config-language/_index.md" diff --git a/docs/sources/flow/tasks/migrate/from-promtail.md b/docs/sources/flow/tasks/migrate/from-promtail.md index bf116e755c7b..182dec857c3b 100644 --- a/docs/sources/flow/tasks/migrate/from-promtail.md +++ b/docs/sources/flow/tasks/migrate/from-promtail.md @@ -64,7 +64,7 @@ This conversion will enable you to take full advantage of the many additional fe * _``_: The full path to the Promtail configuration. * _``_: The full path to output the {{< param "PRODUCT_NAME" >}} configuration. -1. [Start][] {{< param "PRODUCT_NAME" >}} using the new configuration from _``_: +1. [Run][] {{< param "PRODUCT_NAME" >}} using the new configuration from _``_: ### Debugging @@ -127,7 +127,7 @@ This allows you to try {{< param "PRODUCT_NAME" >}} without modifying your exist > In this task, you will use the [run][] CLI command to run {{< param "PRODUCT_NAME" >}} using a Promtail configuration. -[Start][] {{< param "PRODUCT_NAME" >}} and include the command line flag `--config.format=promtail`. +[Run][] {{< param "PRODUCT_NAME" >}} and include the command line flag `--config.format=promtail`. Your configuration file must be a valid Promtail configuration file rather than a {{< param "PRODUCT_NAME" >}} configuration file. ### Debugging @@ -239,8 +239,8 @@ The following list is specific to the convert command and not {{< param "PRODUCT [convert]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/reference/cli/convert.md" [run]: "/docs/agent/ -> /docs/agent//flow/reference/cli/run.md" [run]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/reference/cli/run.md" -[Start]: "/docs/agent/ -> /docs/agent//flow/setup/start/" -[Start]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/setup/start/" +[Run]: "/docs/agent/ -> /docs/agent//flow/get-started/run/" +[Run]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/get-started/run/" [DebuggingUI]: "/docs/agent/ -> /docs/agent//flow/tasks/debug.md" [DebuggingUI]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/tasks/debug.md" [River]: "/docs/agent/ -> /docs/agent//flow/concepts/config-language/_index.md" diff --git a/docs/sources/flow/tasks/migrate/from-static.md b/docs/sources/flow/tasks/migrate/from-static.md index 6f7c30d994a8..ff006b514a5e 100644 --- a/docs/sources/flow/tasks/migrate/from-static.md +++ b/docs/sources/flow/tasks/migrate/from-static.md @@ -67,7 +67,7 @@ This conversion will enable you to take full advantage of the many additional fe * _``_: The full path to the [Static][] configuration. * _`H_`: The full path to output the {{< param "PRODUCT_NAME" >}} configuration. -1. [Start][] {{< param "PRODUCT_NAME" >}} using the new {{< param "PRODUCT_NAME" >}} configuration from _``_: +1. [Run][] {{< param "PRODUCT_NAME" >}} using the new {{< param "PRODUCT_NAME" >}} configuration from _``_: ### Debugging @@ -130,7 +130,7 @@ This allows you to try {{< param "PRODUCT_NAME" >}} without modifying your exist > In this task, you will use the [run][] CLI command to run {{< param "PRODUCT_NAME" >}} using a Static configuration. -[Start][] {{< param "PRODUCT_NAME" >}} and include the command line flag `--config.format=static`. +[Run][] {{< param "PRODUCT_NAME" >}} and include the command line flag `--config.format=static`. Your configuration file must be a valid [Static] configuration file. ### Debugging @@ -374,8 +374,8 @@ The following list is specific to the convert command and not {{< param "PRODUCT [convert]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/reference/cli/convert.md" [run]: "/docs/agent/ -> /docs/agent//flow/reference/cli/run.md" [run]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/reference/cli/run.md" -[Start]: "/docs/agent/ -> /docs/agent//flow/setup/start/" -[Start]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/setup/start/" +[Run]: "/docs/agent/ -> /docs/agent//flow/get-started/run/" +[Run]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/get-started/run/" [DebuggingUI]: "/docs/agent/ -> /docs/agent//flow/tasks/debug.md" [DebuggingUI]: "/docs/grafana-cloud/ -> /docs/grafana-cloud/send-data/agent/flow/tasks/debug.md" [River]: "/docs/agent/ -> /docs/agent//flow/concepts/config-language/" diff --git a/docs/sources/shared/wal-data-retention.md b/docs/sources/shared/wal-data-retention.md index 1d2caf844e17..973af3afb4d6 100644 --- a/docs/sources/shared/wal-data-retention.md +++ b/docs/sources/shared/wal-data-retention.md @@ -111,6 +111,6 @@ To delete the corrupted WAL: [WAL block]: /docs/agent//flow/reference/components/prometheus.remote_write#wal-block [metrics config]: /docs/agent//static/configuration/metrics-config -[Stop]: /docs/agent//flow/setup/start-agent +[Stop]: /docs/agent//flow/get-started/start-agent [wal_directory]: /docs/agent//static/configuration/metrics-config [run]: /docs/agent//flow/reference/cli/run From 19318b615fcad183e96b0ed6d5c05f1857c1844c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=90=E1=BB=97=20Tr=E1=BB=8Dng=20H=E1=BA=A3i?= <41283691+hainenber@users.noreply.github.com> Date: Thu, 11 Jan 2024 22:40:47 +0700 Subject: [PATCH 54/68] feat(exporter/windows): expose physical_disk collector (#5927) * feat(exporter/windows): expose physical_disk collector Signed-off-by: hainenber * fix(exporter/windows): correct river attr name for physical_disk Signed-off-by: hainenber * feat(exporter/windows): set default args for physical_disk attr Signed-off-by: hainenber * feat(exporter/windows): update unit test + integration doc Signed-off-by: hainenber * Update docs/sources/static/configuration/integrations/windows-exporter-config.md Co-authored-by: Clayton Cornell <131809008+clayton-cornell@users.noreply.github.com> * Update docs/sources/static/configuration/integrations/windows-exporter-config.md Co-authored-by: Clayton Cornell <131809008+clayton-cornell@users.noreply.github.com> --------- Signed-off-by: hainenber Co-authored-by: Clayton Cornell <131809008+clayton-cornell@users.noreply.github.com> --- CHANGELOG.md | 3 +++ component/prometheus/exporter/windows/config.go | 16 ++++++++++++++++ .../windows/config_default_windows_test.go | 2 ++ .../exporter/windows/config_windows.go | 7 ++++++- .../prometheus/exporter/windows/windows_test.go | 9 +++++++++ .../internal/build/windows_exporter.go | 4 ++++ .../components/prometheus.exporter.windows.md | 1 + .../integrations/windows-exporter-config.md | 10 ++++++++++ pkg/integrations/windows_exporter/config.go | 7 +++++++ .../windows_exporter/config_windows.go | 7 +++++++ 10 files changed, 65 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a4c13c5d97b7..3253b1909844 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -113,6 +113,9 @@ v0.39.0 (2024-01-09) - `discovery.lightsail` now supports additional parameters for configuring HTTP client settings. (@ptodev) - Add `sample_age_limit` to remote_write config to drop samples older than a specified duration. (@marctc) +- Expose `physical_disk` collector from `windows_exporter` v0.24.0 to + Flow configuration. (@hainenber) + - Handle paths in the Kubelet URL for `discovery.kubelet`. (@petewall) - `loki.source.docker` now deduplicates targets which report the same container diff --git a/component/prometheus/exporter/windows/config.go b/component/prometheus/exporter/windows/config.go index cc4cb20e4b17..44568833c1cd 100644 --- a/component/prometheus/exporter/windows/config.go +++ b/component/prometheus/exporter/windows/config.go @@ -19,6 +19,7 @@ type Arguments struct { MSMQ MSMQConfig `river:"msmq,block,optional"` MSSQL MSSQLConfig `river:"mssql,block,optional"` Network NetworkConfig `river:"network,block,optional"` + PhysicalDisk PhysicalDiskConfig `river:"physical_disk,block,optional"` Process ProcessConfig `river:"process,block,optional"` ScheduledTask ScheduledTaskConfig `river:"scheduled_task,block,optional"` Service ServiceConfig `river:"service,block,optional"` @@ -38,6 +39,7 @@ func (a *Arguments) Convert() *windows_integration.Config { MSSQL: a.MSSQL.Convert(), Network: a.Network.Convert(), Process: a.Process.Convert(), + PhysicalDisk: a.PhysicalDisk.Convert(), ScheduledTask: a.ScheduledTask.Convert(), Service: a.Service.Convert(), SMTP: a.SMTP.Convert(), @@ -230,3 +232,17 @@ func (t LogicalDiskConfig) Convert() windows_integration.LogicalDiskConfig { Exclude: t.Exclude, } } + +// PhysicalDiskConfig handles settings for the windows_exporter physical disk collector +type PhysicalDiskConfig struct { + Include string `river:"include,attr,optional"` + Exclude string `river:"exclude,attr,optional"` +} + +// Convert converts the component's PhysicalDiskConfig to the integration's PhysicalDiskConfig. +func (t PhysicalDiskConfig) Convert() windows_integration.PhysicalDiskConfig { + return windows_integration.PhysicalDiskConfig{ + Include: t.Include, + Exclude: t.Exclude, + } +} diff --git a/component/prometheus/exporter/windows/config_default_windows_test.go b/component/prometheus/exporter/windows/config_default_windows_test.go index 9fddd1d635eb..7242ac42e525 100644 --- a/component/prometheus/exporter/windows/config_default_windows_test.go +++ b/component/prometheus/exporter/windows/config_default_windows_test.go @@ -25,6 +25,8 @@ func TestRiverUnmarshalWithDefaultConfig(t *testing.T) { require.Equal(t, DefaultArguments.MSSQL.EnabledClasses, args.MSSQL.EnabledClasses) require.Equal(t, DefaultArguments.Network.Exclude, args.Network.Exclude) require.Equal(t, DefaultArguments.Network.Include, args.Network.Include) + require.Equal(t, DefaultArguments.PhysicalDisk.Exclude, args.PhysicalDisk.Exclude) + require.Equal(t, DefaultArguments.PhysicalDisk.Include, args.PhysicalDisk.Include) require.Equal(t, DefaultArguments.Process.Exclude, args.Process.Exclude) require.Equal(t, DefaultArguments.Process.Include, args.Process.Include) require.Equal(t, DefaultArguments.ScheduledTask.Exclude, args.ScheduledTask.Exclude) diff --git a/component/prometheus/exporter/windows/config_windows.go b/component/prometheus/exporter/windows/config_windows.go index b634788eda8c..42270f9e241e 100644 --- a/component/prometheus/exporter/windows/config_windows.go +++ b/component/prometheus/exporter/windows/config_windows.go @@ -1,9 +1,10 @@ package windows import ( + "strings" + windows_integration "github.com/grafana/agent/pkg/integrations/windows_exporter" col "github.com/prometheus-community/windows_exporter/pkg/collector" - "strings" ) // DefaultArguments holds non-zero default options for Arguments when it is @@ -44,6 +45,10 @@ var DefaultArguments = Arguments{ Include: col.ConfigDefaults.Net.NicInclude, Exclude: col.ConfigDefaults.Net.NicExclude, }, + PhysicalDisk: PhysicalDiskConfig{ + Exclude: col.ConfigDefaults.PhysicalDisk.DiskExclude, + Include: col.ConfigDefaults.PhysicalDisk.DiskInclude, + }, Process: ProcessConfig{ BlackList: col.ConfigDefaults.Process.ProcessExclude, WhiteList: col.ConfigDefaults.Process.ProcessInclude, diff --git a/component/prometheus/exporter/windows/windows_test.go b/component/prometheus/exporter/windows/windows_test.go index 8b34164f5d7c..6f15ad6e7555 100644 --- a/component/prometheus/exporter/windows/windows_test.go +++ b/component/prometheus/exporter/windows/windows_test.go @@ -34,6 +34,11 @@ var ( service { where_clause = "where" } + + physical_disk { + include = ".+" + exclude = "" + } process { include = ".+" @@ -75,6 +80,8 @@ func TestRiverUnmarshal(t *testing.T) { require.Equal(t, "", args.SMTP.Exclude) require.Equal(t, ".+", args.SMTP.Include) require.Equal(t, "where", args.Service.Where) + require.Equal(t, "", args.PhysicalDisk.Exclude) + require.Equal(t, ".+", args.PhysicalDisk.Include) require.Equal(t, "", args.Process.Exclude) require.Equal(t, ".+", args.Process.Include) require.Equal(t, "", args.Network.Exclude) @@ -102,6 +109,8 @@ func TestConvert(t *testing.T) { require.Equal(t, "", conf.SMTP.Exclude) require.Equal(t, ".+", conf.SMTP.Include) require.Equal(t, "where", conf.Service.Where) + require.Equal(t, "", conf.PhysicalDisk.Exclude) + require.Equal(t, ".+", conf.PhysicalDisk.Include) require.Equal(t, "", conf.Process.Exclude) require.Equal(t, ".+", conf.Process.Include) require.Equal(t, "", conf.Network.Exclude) diff --git a/converter/internal/staticconvert/internal/build/windows_exporter.go b/converter/internal/staticconvert/internal/build/windows_exporter.go index 73aa706e8235..2f0b110a68f0 100644 --- a/converter/internal/staticconvert/internal/build/windows_exporter.go +++ b/converter/internal/staticconvert/internal/build/windows_exporter.go @@ -50,6 +50,10 @@ func toWindowsExporter(config *windows_exporter.Config) *windows.Arguments { Exclude: config.Network.Exclude, Include: config.Network.Include, }, + PhysicalDisk: windows.PhysicalDiskConfig{ + Exclude: config.PhysicalDisk.Exclude, + Include: config.PhysicalDisk.Include, + }, Process: windows.ProcessConfig{ BlackList: config.Process.BlackList, WhiteList: config.Process.WhiteList, diff --git a/docs/sources/flow/reference/components/prometheus.exporter.windows.md b/docs/sources/flow/reference/components/prometheus.exporter.windows.md index 4ad33effdd4a..8042b5458d1c 100644 --- a/docs/sources/flow/reference/components/prometheus.exporter.windows.md +++ b/docs/sources/flow/reference/components/prometheus.exporter.windows.md @@ -254,6 +254,7 @@ Name | Description | Enabled by default [netframework_clrsecurity](https://github.com/prometheus-community/windows_exporter/blob/master/docs/collector.netframework_clrsecurity.md) | .NET Framework Security Check metrics | [net](https://github.com/prometheus-community/windows_exporter/blob/master/docs/collector.net.md) | Network interface I/O | ✓ [os](https://github.com/prometheus-community/windows_exporter/blob/master/docs/collector.os.md) | OS metrics (memory, processes, users) | ✓ +[physical_disk](https://github.com/prometheus-community/windows_exporter/blob/master/docs/collector.physical_disk.md) | Physical disks | ✓ [process](https://github.com/prometheus-community/windows_exporter/blob/master/docs/collector.process.md) | Per-process metrics | [remote_fx](https://github.com/prometheus-community/windows_exporter/blob/master/docs/collector.remote_fx.md) | RemoteFX protocol (RDP) metrics | [scheduled_task](https://github.com/prometheus-community/windows_exporter/blob/master/docs/collector.scheduled_task.md) | Scheduled Tasks metrics | diff --git a/docs/sources/static/configuration/integrations/windows-exporter-config.md b/docs/sources/static/configuration/integrations/windows-exporter-config.md index 53c58b60fe0b..7f12117ebfbc 100644 --- a/docs/sources/static/configuration/integrations/windows-exporter-config.md +++ b/docs/sources/static/configuration/integrations/windows-exporter-config.md @@ -114,6 +114,16 @@ Full reference of options: # Maps to collector.service.services-where in windows_exporter [where_clause: | default=""] + # Configuration for physical disk on Windows + physical_disk: + # Regexp of volumes to include. Disk name must both match include and not match exclude to be included. + # Maps to collector.logical_disk.disk-include in windows_exporter. + [include: | default=".+"] + + # Regexp of volumes to exclude. Disk name must both match include and not match exclude to be included. + # Maps to collector.logical_disk.disk-exclude in windows_exporter. + [exclude: | default=".+"] + # Configuration for Windows Processes process: # Regexp of processes to include. Process name must both match whitelist and not match blacklist to be included. diff --git a/pkg/integrations/windows_exporter/config.go b/pkg/integrations/windows_exporter/config.go index 006bc5426d72..a8bdba73174c 100644 --- a/pkg/integrations/windows_exporter/config.go +++ b/pkg/integrations/windows_exporter/config.go @@ -23,6 +23,7 @@ type Config struct { TextFile TextFileConfig `yaml:"text_file,omitempty"` SMTP SMTPConfig `yaml:"smtp,omitempty"` Service ServiceConfig `yaml:"service,omitempty"` + PhysicalDisk PhysicalDiskConfig `yaml:"physical_disk,omitempty"` Process ProcessConfig `yaml:"process,omitempty"` Network NetworkConfig `yaml:"network,omitempty"` MSSQL MSSQLConfig `yaml:"mssql,omitempty"` @@ -126,3 +127,9 @@ type ScheduledTaskConfig struct { Include string `yaml:"include,omitempty"` Exclude string `yaml:"exclude,omitempty"` } + +// PhysicalDiskConfig handles settings for the windows_exporter physical disk collector +type PhysicalDiskConfig struct { + Include string `yaml:"include,omitempty"` + Exclude string `yaml:"exclude,omitempty"` +} diff --git a/pkg/integrations/windows_exporter/config_windows.go b/pkg/integrations/windows_exporter/config_windows.go index 17fd03d4f80c..657ff5861de4 100644 --- a/pkg/integrations/windows_exporter/config_windows.go +++ b/pkg/integrations/windows_exporter/config_windows.go @@ -22,6 +22,9 @@ func (c *Config) ToWindowsExporterConfig() collector.Config { cfg.Textfile.TextFileDirectories = c.TextFile.TextFileDirectory + cfg.PhysicalDisk.DiskInclude = c.PhysicalDisk.Include + cfg.PhysicalDisk.DiskExclude = c.PhysicalDisk.Exclude + cfg.Process.ProcessExclude = coalesceString(c.Process.Exclude, c.Process.BlackList) cfg.Process.ProcessInclude = coalesceString(c.Process.Include, c.Process.WhiteList) @@ -87,6 +90,10 @@ var DefaultConfig = Config{ Include: collector.ConfigDefaults.Net.NicInclude, Exclude: collector.ConfigDefaults.Net.NicExclude, }, + PhysicalDisk: PhysicalDiskConfig{ + Include: collector.ConfigDefaults.PhysicalDisk.DiskInclude, + Exclude: collector.ConfigDefaults.PhysicalDisk.DiskExclude, + }, Process: ProcessConfig{ BlackList: collector.ConfigDefaults.Process.ProcessExclude, WhiteList: collector.ConfigDefaults.Process.ProcessInclude, From bba4a5d0c7d8e47aad012520ecb0d93e40d37d84 Mon Sep 17 00:00:00 2001 From: Robert Fratto Date: Thu, 11 Jan 2024 11:19:53 -0500 Subject: [PATCH 55/68] example: remove k3d sample environment (#6117) The k3d example environment has been unused in a long time, and no longer works as the Tanka library it depended on has been removed. The docker-compose environment supersedes the k3d environment for simple use cases. --- example/k3d/README.md | 128 ---- example/k3d/assets/alert_firing.png | Bin 163588 -> 0 bytes example/k3d/assets/alerts.png | Bin 84885 -> 0 bytes example/k3d/assets/console_failure.png | Bin 16667 -> 0 bytes example/k3d/assets/logs_alerts.png | Bin 229967 -> 0 bytes example/k3d/assets/logs_flow.mermaid | 9 - example/k3d/assets/logs_flow.png | Bin 103519 -> 0 bytes example/k3d/assets/metrics_flow.png | Bin 24634 -> 0 bytes example/k3d/assets/metrics_flow.uml | 10 - example/k3d/assets/pending_alert.png | Bin 86157 -> 0 bytes example/k3d/assets/traces_flow.mermaid | 8 - example/k3d/assets/traces_flow.png | Bin 222160 -> 0 bytes example/k3d/assets/trigger_change.png | Bin 57710 -> 0 bytes example/k3d/assets/trigger_logs_alerts.png | Bin 33552 -> 0 bytes example/k3d/environment/main.jsonnet | 165 ----- example/k3d/environment/spec.json | 11 - example/k3d/jsonnetfile.json | 76 --- example/k3d/jsonnetfile.lock.json | 112 ---- .../lib/collector/collector-config.libsonnet | 28 - example/k3d/lib/collector/main.libsonnet | 47 -- .../k3d/lib/cortex/cortex-config.libsonnet | 91 --- example/k3d/lib/cortex/main.libsonnet | 64 -- example/k3d/lib/default/loki_config.libsonnet | 41 -- example/k3d/lib/default/main.libsonnet | 26 - example/k3d/lib/default/mixins.libsonnet | 30 - example/k3d/lib/grafana/config.libsonnet | 36 - example/k3d/lib/grafana/datasource.libsonnet | 25 - example/k3d/lib/grafana/main.libsonnet | 132 ---- example/k3d/lib/k.libsonnet | 2 - .../k3d/lib/kube-state-metrics/main.libsonnet | 135 ---- .../load-generator/load-generator-config.json | 630 ------------------ example/k3d/lib/load-generator/main.libsonnet | 54 -- example/k3d/lib/loki/loki-config.libsonnet | 61 -- example/k3d/lib/loki/main.libsonnet | 64 -- example/k3d/lib/node-exporter/main.libsonnet | 35 - example/k3d/lib/prometheus/main.libsonnet | 90 --- example/k3d/scripts/create.bash | 20 - example/k3d/scripts/smoke-test.bash | 142 ---- example/k3d/smoke/main.jsonnet | 512 -------------- example/k3d/smoke/monitoring/main.jsonnet | 61 -- .../prometheus_monitoring.libsonnet | 282 -------- example/k3d/smoke/spec.json | 11 - 42 files changed, 3138 deletions(-) delete mode 100644 example/k3d/README.md delete mode 100644 example/k3d/assets/alert_firing.png delete mode 100644 example/k3d/assets/alerts.png delete mode 100644 example/k3d/assets/console_failure.png delete mode 100644 example/k3d/assets/logs_alerts.png delete mode 100644 example/k3d/assets/logs_flow.mermaid delete mode 100644 example/k3d/assets/logs_flow.png delete mode 100644 example/k3d/assets/metrics_flow.png delete mode 100644 example/k3d/assets/metrics_flow.uml delete mode 100644 example/k3d/assets/pending_alert.png delete mode 100644 example/k3d/assets/traces_flow.mermaid delete mode 100644 example/k3d/assets/traces_flow.png delete mode 100644 example/k3d/assets/trigger_change.png delete mode 100644 example/k3d/assets/trigger_logs_alerts.png delete mode 100644 example/k3d/environment/main.jsonnet delete mode 100644 example/k3d/environment/spec.json delete mode 100644 example/k3d/jsonnetfile.json delete mode 100644 example/k3d/jsonnetfile.lock.json delete mode 100644 example/k3d/lib/collector/collector-config.libsonnet delete mode 100644 example/k3d/lib/collector/main.libsonnet delete mode 100644 example/k3d/lib/cortex/cortex-config.libsonnet delete mode 100644 example/k3d/lib/cortex/main.libsonnet delete mode 100644 example/k3d/lib/default/loki_config.libsonnet delete mode 100644 example/k3d/lib/default/main.libsonnet delete mode 100644 example/k3d/lib/default/mixins.libsonnet delete mode 100644 example/k3d/lib/grafana/config.libsonnet delete mode 100644 example/k3d/lib/grafana/datasource.libsonnet delete mode 100644 example/k3d/lib/grafana/main.libsonnet delete mode 100644 example/k3d/lib/k.libsonnet delete mode 100644 example/k3d/lib/kube-state-metrics/main.libsonnet delete mode 100644 example/k3d/lib/load-generator/load-generator-config.json delete mode 100644 example/k3d/lib/load-generator/main.libsonnet delete mode 100644 example/k3d/lib/loki/loki-config.libsonnet delete mode 100644 example/k3d/lib/loki/main.libsonnet delete mode 100644 example/k3d/lib/node-exporter/main.libsonnet delete mode 100644 example/k3d/lib/prometheus/main.libsonnet delete mode 100755 example/k3d/scripts/create.bash delete mode 100755 example/k3d/scripts/smoke-test.bash delete mode 100644 example/k3d/smoke/main.jsonnet delete mode 100644 example/k3d/smoke/monitoring/main.jsonnet delete mode 100644 example/k3d/smoke/monitoring/prometheus_monitoring.libsonnet delete mode 100644 example/k3d/smoke/spec.json diff --git a/example/k3d/README.md b/example/k3d/README.md deleted file mode 100644 index 10512b2bd92f..000000000000 --- a/example/k3d/README.md +++ /dev/null @@ -1,128 +0,0 @@ -# `k3d` Examples - -## Agent Environment - -The `k3d` example uses `k3d` and `tanka` to produce a Kubernetes environment -that implements a full Grafana Agent environment for testing. - -### Requirements - -- A Unix-y command line (macOS or Linux will do). -- Kubectl -- Docker -- [Tanka >= v0.9.2](https://github.com/grafana/tanka) -- [k3d >= v4.0.0,<= v5.2.2](https://github.com/k3d-io/k3d) -- [jsonnet-bundler >= v0.4.0](https://github.com/jsonnet-bundler/jsonnet-bundler) - -### Getting Started - -Build latest agent images with `make agent-image agentctl-image` in the project root directory if there are local changes to test. - -Run the following to create your cluster: - -```bash -# Create a new k3d cluster -./scripts/create.bash - -# Import images into k3d if they are not available on docker hub -k3d image import -c agent-k3d grafana/agent:main -k3d image import -c agent-k3d grafana/agentctl:main - -# Ensure jsonnet is up to date before applying environment -jb install -tk apply ./environment - -# Navigate to grafana.k3d.localhost:30080 in your browser to view dashboards - -# Delete the k3d cluster when you're done with it -k3d cluster delete agent-k3d -``` - -## Smoke Test Environment - -The smoke test environment is used for end-to-end validation of all three observability signals. - -### Running - -Smoke Test environment is invoked via `/scripts/smoke-test.bash` - -This tool will spin up cluster of Grafana Agent, Cortex, Avalanche, Smoke, [Crow](../../tools/crow/README.md), [Canary](https://grafana.com/docs/loki/latest/operations/loki-canary/) and Vulture instances. The Smoke deployment will then periodically kill instances and check for any failed alerts. At the end of the duration (default 3h) it will end the testing. - -For users who do not have access to the `us.gcr.io/kubernetes-dev` container registry, do the following to run the smoke test: - -* Build the Smoke and Crow images locally (from the root project directory): -``` -make grafana-agent-crow-image agent-smoke-image -``` -* Run the smoke test using `/scripts/smoke-test.bash` script. -* `Smoke` and `Crow` pods will fail because the images are not imported into the cluster. Import them running: -``` -k3d image import -c agent-smoke-test us.gcr.io/kubernetes-dev/grafana/agent-smoke:main -k3d image import -c agent-smoke-test us.gcr.io/kubernetes-dev/grafana/agent-crow:main -``` - -### What to look for? - -These alerts are viewable [here](http://prometheus.k3d.localhost:50080/alerts). - -Prometheus alerts are triggered: -- If any Crow instances are not running or Crow samples are not being propagated correctly. -- If any Canary instances are not running or Canary logs are not being propagated correctly. -- If any Vulture instances are not running or Vulture samples are not being propagated correctly. -- If any Grafana Agents are not running or Grafana Agent limits are outside their norm. - -NOTE: The alerts might be in pending until the system settles down. - -![](./assets/pending_alert.png) - -An alert firing will look similar to the below. - -![](./assets/alert_firing.png) - -If at the end of the test any issues are found they will look similar to the below. - -![](./assets/console_failure.png) - -### How to trigger an alert? - -Changing the avalanche setting for label_count to 1000, located [here](../../production/tanka/grafana-agent/smoke/avalanche/main.libsonnet). This will ensure the [GrafanaAgentMemHigh](http://prometheus.k3d.localhost:50080/graph?g0.expr=ALERTS%7Balertname%3D%22GrafanaAgentMemHigh%22%7D&g0.tab=1&g0.stacked=0&g0.show_exemplars=0.g0.range_input=1h.) alert exceeds the limit. - -![](./assets/trigger_change.png) - -For Loki Canary, the easiest way to trigger an alert is to edit its Daemonset to query for a different label that doesn't exist. -![](./assets/trigger_logs_alerts.png) -![](./assets/logs_alerts.png) - -### Architecture - -By default, a k3d cluster will be created running the following instances - -- agent-single - single instance -- agent-cluster - 3 Grafana Agents in clustered configuration -- crow-cluster - serves the agent cluster -- crow-single - serves the single agent -- cortex -- avalanche - selection of avalanche instances serving traffic -- smoke - scales avalanche replicas and introduces chaos by deleting agent pods during testing -- canary - emits logs and checks if they're stored properly -- loki -- vulture - emits traces and checks if they're stored properly -- tempo - -Crow, Canary and Vulture instances will check to see if the metrics, logs and traces that were scraped respectively, show up in the Cortex/Loki/Tempo instances. They will then emit metrics on the success of those metrics. This success/failure result will trigger an alert if it is incorrect. - -### Metrics Flow - -![](./assets/metrics_flow.png) - -### Logs Flow - -![](./assets/logs_flow.png) - -### Traces Flow - -![](./assets/traces_flow.png) - -### Avalanche - -Avalanche is used to add some additional load on the system and general testing. diff --git a/example/k3d/assets/alert_firing.png b/example/k3d/assets/alert_firing.png deleted file mode 100644 index f134cf8f2b44dbb413480f59bae74acb90bdaf1b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 163588 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,Mh=po{6v~%BWji?QIdX_@Z7;tTf_O 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 diff --git a/example/k3d/assets/alerts.png b/example/k3d/assets/alerts.png deleted file mode 100644 index d76f62cb0bd3d5bd44f202d91b6c44e37f7b1161..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 84885 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