diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index f4bfc16be7..9b1e5a1706 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -1,7 +1,13 @@ name: ci on: - - push - - pull_request + pull_request: + push: + branches: + - 'release-*' + - 'master' + - 'main' + tags: + - 'v*' env: golang-version: '1.16' kind-version: 'v0.10.0' @@ -135,7 +141,7 @@ jobs: run: > EXCLUDE_ALERTMANAGER_TESTS=${{ matrix.alertmanager }} EXCLUDE_PROMETHEUS_TESTS=${{ matrix.prometheus }} - EXCLUDE_THANOS_TESTS=${{ matrix.thanosruler }} + EXCLUDE_THANOSRULER_TESTS=${{ matrix.thanosruler }} make test-e2e publish: runs-on: ubuntu-latest diff --git a/ADOPTERS.md b/ADOPTERS.md index 26c188b44b..d0ecd4870e 100644 --- a/ADOPTERS.md +++ b/ADOPTERS.md @@ -4,8 +4,29 @@ date: 2021-03-08T23:50:39+01:00 draft: false --- + + This document tracks people and use cases for the Prometheus Operator in production. By creating a list of production use cases we hope to build a community of advisors that we can reach out to with experience using various the Prometheus Operator applications, operation environments, and cluster sizes. The Prometheus Operator development team may reach out periodically to check-in on how the Prometheus Operator is working in the field and update this list. +Go ahead and [add your organization](https://github.com/prometheus-operator/prometheus-operator/edit/master/ADOPTERS.md) to the list. + ## Giant Swarm [giantswarm.io](https://www.giantswarm.io/) @@ -59,6 +80,18 @@ Details: - 17k samples/s - 841k active series +## Nozzle + +[nozzle.io](https://nozzle.io) + +Environment: Google Cloud + +Uses [kube-prometheus](https://github.com/prometheus-operator/kube-prometheus): Yes + +Details: +- 100k samples/s +- 1M active series +- ## OpenShift [openshift.com](https://www.openshift.com/) @@ -131,18 +164,3 @@ Uses [kube-prometheus](https://github.com/prometheus-operator/kube-prometheus): Details (optional): - A huge fleet of OpenShift and Kubernetes clusters, each using Prometheus Operator - All managed by [Project Syn](https://syn.tools/), leveraging Commodore Components like [component-rancher-monitoring](https://github.com/projectsyn/component-rancher-monitoring) which re-uses Prometheus Operator - ---- - -## - -https://our-link.com/ - -Environments: AWS, Azure, Google Cloud, Bare Metal, etc - -Uses [kube-prometheus](https://github.com/prometheus-operator/kube-prometheus): Yes | No - -Details (optional): -- HA Pair of Prometheus -- 1000 samples/s (query: `rate(prometheus_tsdb_head_samples_appended_total[5m])`) -- 10k active series (query: `prometheus_tsdb_head_series`) diff --git a/CHANGELOG.md b/CHANGELOG.md index a7f58ea2b5..eaa4517e38 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,22 @@ +## 0.48.1 / 2021-06-01 + +* [BUGFIX] Added an `app` label on Prometheus pods. #4055 + +## 0.48.0 / 2021-05-19 + +Deprecation notice: +app labels will be removed in v0.50. + +* [CHANGE] Replace app label names with app.kubernetes.io/name. #3939 +* [CHANGE] Drop ksonnet as a dependency in jsonnetfile.json. #4002 +* [ENHANCEMENT] Add default container annotation to Alertmanager pod. #3978 +* [ENHANCEMENT] Add default container annotation to Thanos ruler pod. #3981 +* [ENHANCEMENT] Optimize asset secret update logic. #3986 +* [ENHANCEMENT] jsonnet: set default container in prometheus-operator pod. #3979 +* [BUGFIX] Watch configmaps from the Prometheus allowed namespaces only. #3992 +* [BUGFIX] Reconcile resources on namespace updates when using privileged lister/watcher. #3879 +* [BUGFIX] Don't generate broken Alertmanager configuration when `http_config` is defined in the global parameters. #4041 + ## 0.47.1 / 2021-04-30 * [BUGFIX] Avoid reconciliations for Alertmanager statefulset on resource version changes. #3948 diff --git a/Documentation/network-policies.md b/Documentation/network-policies.md index ab3ff26ba4..df5aa329f3 100644 --- a/Documentation/network-policies.md +++ b/Documentation/network-policies.md @@ -66,7 +66,7 @@ spec: podSelector: matchLabels: alertmanager: main - app: alertmanager + app.kubernetes.io/name: alertmanager --- apiVersion: networking.k8s.io/v1 kind: NetworkPolicy @@ -93,7 +93,7 @@ spec: podSelector: matchLabels: alertmanager: main - app: alertmanager + app.kubernetes.io/name: alertmanager ``` @@ -134,7 +134,7 @@ spec: protocol: TCP podSelector: matchLabels: - app: prometheus + app.kubernetes.io/name: prometheus prometheus: k8s ``` diff --git a/Documentation/rbac.md b/Documentation/rbac.md index 5287cee15b..589808e850 100644 --- a/Documentation/rbac.md +++ b/Documentation/rbac.md @@ -28,7 +28,7 @@ metadata: labels: app.kubernetes.io/component: controller app.kubernetes.io/name: prometheus-operator - app.kubernetes.io/version: 0.47.1 + app.kubernetes.io/version: 0.48.1 name: prometheus-operator rules: - apiGroups: @@ -177,7 +177,7 @@ metadata: labels: app.kubernetes.io/component: controller app.kubernetes.io/name: prometheus-operator - app.kubernetes.io/version: 0.47.1 + app.kubernetes.io/version: 0.48.1 name: prometheus-operator namespace: default ``` @@ -194,7 +194,7 @@ metadata: labels: app.kubernetes.io/component: controller app.kubernetes.io/name: prometheus-operator - app.kubernetes.io/version: 0.47.1 + app.kubernetes.io/version: 0.48.1 name: prometheus-operator roleRef: apiGroup: rbac.authorization.k8s.io diff --git a/Documentation/troubleshooting.md b/Documentation/troubleshooting.md index 0ab6d88c01..251547a8ab 100644 --- a/Documentation/troubleshooting.md +++ b/Documentation/troubleshooting.md @@ -50,7 +50,7 @@ When creating/deleting/modifying `ServiceMonitor` objects it is sometimes not as A common problem related to `ServiceMonitor` identification by Prometheus is related to an incorrect tagging, that does not match the `Prometheus` custom resource definition scope, or lack of permission for the Prometheus `ServiceAccount` to *get, list, watch* `Services` and `Endpoints` from the target application being monitored. As a general guideline consider the diagram below, giving an example of a `Deployment` and `Service` called `my-app`, being monitored by Prometheus based on a `ServiceMonitor` named `my-service-monitor`: -![flow diagram](../custom-metrics-elements.png) +![flow diagram](custom-metrics-elements.png) Note: The `ServiceMonitor` references a `Service` (not a `Deployment`, or a `Pod`), by labels *and* by the port name in the `Service`. This *port name* is optional in Kubernetes, but must be specified for the `ServiceMonitor` to work. It is not the same as the port name on the `Pod` or container, although it can be. diff --git a/Documentation/user-guides/getting-started.md b/Documentation/user-guides/getting-started.md index bc2327c6a6..545b331181 100644 --- a/Documentation/user-guides/getting-started.md +++ b/Documentation/user-guides/getting-started.md @@ -264,7 +264,7 @@ Further reading: [bundle]: ../../bundle.yaml [design-doc]: ../design.md [exposing-prom]: exposing-prometheus-and-alertmanager.md -[introducing-operators]: https://coreos.com/blog/introducing-operators.html +[introducing-operators]: https://web.archive.org/web/20210210032403/https://coreos.com/blog/introducing-operators.html [prom-rbac]: ../rbac.md [prometheus-manifest]: ../../example/rbac/prometheus/prometheus.yaml [rbac-auth]: https://kubernetes.io/docs/reference/access-authn-authz/authorization/ diff --git a/Documentation/user-guides/monitoring-kubernetes-ingress.md b/Documentation/user-guides/monitoring-kubernetes-ingress.md index 3b05c833a4..c625b3ee56 100644 --- a/Documentation/user-guides/monitoring-kubernetes-ingress.md +++ b/Documentation/user-guides/monitoring-kubernetes-ingress.md @@ -135,7 +135,7 @@ spec: routePrefix: /prometheus ruleSelector: matchLabels: - app: prometheus-operator + app.kubernetes.io/name: prometheus-operator serviceAccountName: prometheus-operator serviceMonitorSelector: matchLabels: diff --git a/Documentation/user-guides/storage.md b/Documentation/user-guides/storage.md index 51421dcbb5..9c120ca1d2 100644 --- a/Documentation/user-guides/storage.md +++ b/Documentation/user-guides/storage.md @@ -74,7 +74,7 @@ spec: spec: selector: matchLabels: - app: my-example-prometheus + app.kubernetes.io/name: my-example-prometheus resources: requests: storage: 50Gi diff --git a/MAINTAINERS.md b/MAINTAINERS.md index 404325e428..c50b551629 100644 --- a/MAINTAINERS.md +++ b/MAINTAINERS.md @@ -4,7 +4,7 @@ |-----------------------|-----------------------------|--------------------------|---------------------------------------------------|-------------------| | Frederic Branczyk | fbranczyk@gmail.com | `@brancz` | [@brancz](https://github.com/brancz) | Polar Signals | | Lili Cosic | cosiclili@gmail.com | `@lili` | [@lilic](https://github.com/lilic) | Red Hat | -| Matthias Loibl | mail@matthiasloibl.com | `@metalmatze` | [@metalmatze](https://github.com/metalmatze) | Red Hat | +| Matthias Loibl | mail@matthiasloibl.com | `@metalmatze` | [@metalmatze](https://github.com/metalmatze) | Polar Signals | | Paweł Krupa | paulfantom@gmail.com | `@paulfantom` | [@paulfantom](https://github.com/paulfantom) | Red Hat | | Sergiusz Urbaniak | sergiusz.urbaniak@gmail.com | `@sur` | [@s-urbaniak](https://github.com/s-urbaniak) | Red Hat | | Simon Pasquier | pasquier.simon@gmail.com | `@SimonPasquier` | [@simonpasquier](https://github.com/simonpasquier)| Red Hat | diff --git a/RELEASE.md b/RELEASE.md index 8ff166c494..55696c2cbf 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -15,8 +15,9 @@ Release cadence of first pre-releases being cut is 6 weeks. | v0.45 | 2021-01-13 | Lili Cosic (GitHub: @lilic) | | v0.46 | 2021-02-24 | Sergiusz Urbaniak (GitHub: @s-urbaniak) | | v0.47 | 2021-04-07 | Simon Pasquier (GitHub: @simonpasquier) | -| v0.48 | 2021-05-19 | **searching for volunteer** | -| v0.49 | 2021-06-30 | **searching for volunteer** | +| v0.48 | 2021-05-19 | Matthias Loibl (GitHub: @metalmatze) | +| v0.49 | 2021-06-30 | Pawel Krupa (GitHub: @paulfantom) | +| v0.50 | 2021-08-11 | **searching for volunteer** | # How to cut a new release diff --git a/VERSION b/VERSION index 650298f4f7..cffa44cf33 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.47.1 +0.48.1 diff --git a/bundle.yaml b/bundle.yaml index b32270b985..1851134a33 100644 --- a/bundle.yaml +++ b/bundle.yaml @@ -14047,7 +14047,7 @@ metadata: labels: app.kubernetes.io/component: controller app.kubernetes.io/name: prometheus-operator - app.kubernetes.io/version: 0.47.1 + app.kubernetes.io/version: 0.48.1 name: prometheus-operator roleRef: apiGroup: rbac.authorization.k8s.io @@ -14064,7 +14064,7 @@ metadata: labels: app.kubernetes.io/component: controller app.kubernetes.io/name: prometheus-operator - app.kubernetes.io/version: 0.47.1 + app.kubernetes.io/version: 0.48.1 name: prometheus-operator rules: - apiGroups: @@ -14144,7 +14144,7 @@ metadata: labels: app.kubernetes.io/component: controller app.kubernetes.io/name: prometheus-operator - app.kubernetes.io/version: 0.47.1 + app.kubernetes.io/version: 0.48.1 name: prometheus-operator namespace: default spec: @@ -14155,16 +14155,18 @@ spec: app.kubernetes.io/name: prometheus-operator template: metadata: + annotations: + kubectl.kubernetes.io/default-container: prometheus-operator labels: app.kubernetes.io/component: controller app.kubernetes.io/name: prometheus-operator - app.kubernetes.io/version: 0.47.1 + app.kubernetes.io/version: 0.48.1 spec: containers: - args: - --kubelet-service=kube-system/kubelet - - --prometheus-config-reloader=quay.io/prometheus-operator/prometheus-config-reloader:v0.47.1 - image: quay.io/prometheus-operator/prometheus-operator:v0.47.1 + - --prometheus-config-reloader=quay.io/prometheus-operator/prometheus-config-reloader:v0.48.1 + image: quay.io/prometheus-operator/prometheus-operator:v0.48.1 name: prometheus-operator ports: - containerPort: 8080 @@ -14191,7 +14193,7 @@ metadata: labels: app.kubernetes.io/component: controller app.kubernetes.io/name: prometheus-operator - app.kubernetes.io/version: 0.47.1 + app.kubernetes.io/version: 0.48.1 name: prometheus-operator namespace: default --- @@ -14201,7 +14203,7 @@ metadata: labels: app.kubernetes.io/component: controller app.kubernetes.io/name: prometheus-operator - app.kubernetes.io/version: 0.47.1 + app.kubernetes.io/version: 0.48.1 name: prometheus-operator namespace: default spec: diff --git a/cmd/operator/main.go b/cmd/operator/main.go index 626c5616d6..43a5cc08ad 100644 --- a/cmd/operator/main.go +++ b/cmd/operator/main.go @@ -448,7 +448,10 @@ func Main() int { srv := &http.Server{ Handler: mux, TLSConfig: tlsConfig, - ErrorLog: stdlog.New(log.NewStdlibAdapter(logger), "", stdlog.LstdFlags), + // use flags on standard logger to align with base logger and get consistent parsed fields form adapter: + // use shortfile flag to get proper 'caller' field (avoid being wrongly parsed/extracted from message) + // and no datetime related flag to keep 'ts' field from base logger (with controlled format) + ErrorLog: stdlog.New(log.NewStdlibAdapter(logger), "", stdlog.Lshortfile), } if srv.TLSConfig == nil { wg.Go(serve(srv, l, logger)) diff --git a/example/networkpolicies/alertmanager.yaml b/example/networkpolicies/alertmanager.yaml index 3c20ad543f..0c2df23d10 100644 --- a/example/networkpolicies/alertmanager.yaml +++ b/example/networkpolicies/alertmanager.yaml @@ -11,7 +11,7 @@ spec: podSelector: matchLabels: alertmanager: main - app: alertmanager + app.kubernetes.io/name: alertmanager --- apiVersion: networking.k8s.io/v1 kind: NetworkPolicy @@ -38,5 +38,5 @@ spec: podSelector: matchLabels: alertmanager: main - app: alertmanager + app.kubernetes.io/name: alertmanager diff --git a/example/networkpolicies/prometheus.yaml b/example/networkpolicies/prometheus.yaml index 22b65673ad..af0bcc75af 100644 --- a/example/networkpolicies/prometheus.yaml +++ b/example/networkpolicies/prometheus.yaml @@ -9,5 +9,5 @@ spec: protocol: TCP podSelector: matchLabels: - app: prometheus - prometheus: k8s \ No newline at end of file + app.kubernetes.io/name: prometheus + prometheus: k8s diff --git a/example/non-rbac/prometheus-operator.yaml b/example/non-rbac/prometheus-operator.yaml index f22cd88727..8789fec055 100644 --- a/example/non-rbac/prometheus-operator.yaml +++ b/example/non-rbac/prometheus-operator.yaml @@ -4,7 +4,7 @@ metadata: labels: app.kubernetes.io/component: controller app.kubernetes.io/name: prometheus-operator - app.kubernetes.io/version: 0.47.1 + app.kubernetes.io/version: 0.48.1 name: prometheus-operator namespace: default spec: @@ -15,16 +15,18 @@ spec: app.kubernetes.io/name: prometheus-operator template: metadata: + annotations: + kubectl.kubernetes.io/default-container: prometheus-operator labels: app.kubernetes.io/component: controller app.kubernetes.io/name: prometheus-operator - app.kubernetes.io/version: 0.47.1 + app.kubernetes.io/version: 0.48.1 spec: containers: - args: - --kubelet-service=kube-system/kubelet - - --prometheus-config-reloader=quay.io/prometheus-operator/prometheus-config-reloader:v0.47.1 - image: quay.io/prometheus-operator/prometheus-operator:v0.47.1 + - --prometheus-config-reloader=quay.io/prometheus-operator/prometheus-config-reloader:v0.48.1 + image: quay.io/prometheus-operator/prometheus-operator:v0.48.1 name: prometheus-operator ports: - containerPort: 8080 diff --git a/example/rbac/prometheus-operator/prometheus-operator-cluster-role-binding.yaml b/example/rbac/prometheus-operator/prometheus-operator-cluster-role-binding.yaml index baf49b2d81..e4f5652663 100644 --- a/example/rbac/prometheus-operator/prometheus-operator-cluster-role-binding.yaml +++ b/example/rbac/prometheus-operator/prometheus-operator-cluster-role-binding.yaml @@ -4,7 +4,7 @@ metadata: labels: app.kubernetes.io/component: controller app.kubernetes.io/name: prometheus-operator - app.kubernetes.io/version: 0.47.1 + app.kubernetes.io/version: 0.48.1 name: prometheus-operator roleRef: apiGroup: rbac.authorization.k8s.io diff --git a/example/rbac/prometheus-operator/prometheus-operator-cluster-role.yaml b/example/rbac/prometheus-operator/prometheus-operator-cluster-role.yaml index 7335dbb30a..574ab5c227 100644 --- a/example/rbac/prometheus-operator/prometheus-operator-cluster-role.yaml +++ b/example/rbac/prometheus-operator/prometheus-operator-cluster-role.yaml @@ -4,7 +4,7 @@ metadata: labels: app.kubernetes.io/component: controller app.kubernetes.io/name: prometheus-operator - app.kubernetes.io/version: 0.47.1 + app.kubernetes.io/version: 0.48.1 name: prometheus-operator rules: - apiGroups: diff --git a/example/rbac/prometheus-operator/prometheus-operator-deployment.yaml b/example/rbac/prometheus-operator/prometheus-operator-deployment.yaml index f1ac6ab0a9..50b63eac66 100644 --- a/example/rbac/prometheus-operator/prometheus-operator-deployment.yaml +++ b/example/rbac/prometheus-operator/prometheus-operator-deployment.yaml @@ -4,7 +4,7 @@ metadata: labels: app.kubernetes.io/component: controller app.kubernetes.io/name: prometheus-operator - app.kubernetes.io/version: 0.47.1 + app.kubernetes.io/version: 0.48.1 name: prometheus-operator namespace: default spec: @@ -15,16 +15,18 @@ spec: app.kubernetes.io/name: prometheus-operator template: metadata: + annotations: + kubectl.kubernetes.io/default-container: prometheus-operator labels: app.kubernetes.io/component: controller app.kubernetes.io/name: prometheus-operator - app.kubernetes.io/version: 0.47.1 + app.kubernetes.io/version: 0.48.1 spec: containers: - args: - --kubelet-service=kube-system/kubelet - - --prometheus-config-reloader=quay.io/prometheus-operator/prometheus-config-reloader:v0.47.1 - image: quay.io/prometheus-operator/prometheus-operator:v0.47.1 + - --prometheus-config-reloader=quay.io/prometheus-operator/prometheus-config-reloader:v0.48.1 + image: quay.io/prometheus-operator/prometheus-operator:v0.48.1 name: prometheus-operator ports: - containerPort: 8080 diff --git a/example/rbac/prometheus-operator/prometheus-operator-service-account.yaml b/example/rbac/prometheus-operator/prometheus-operator-service-account.yaml index 5c6420f7b9..62befd117e 100644 --- a/example/rbac/prometheus-operator/prometheus-operator-service-account.yaml +++ b/example/rbac/prometheus-operator/prometheus-operator-service-account.yaml @@ -4,6 +4,6 @@ metadata: labels: app.kubernetes.io/component: controller app.kubernetes.io/name: prometheus-operator - app.kubernetes.io/version: 0.47.1 + app.kubernetes.io/version: 0.48.1 name: prometheus-operator namespace: default diff --git a/example/rbac/prometheus-operator/prometheus-operator-service-monitor.yaml b/example/rbac/prometheus-operator/prometheus-operator-service-monitor.yaml index 25d8c4294b..845089d3b1 100644 --- a/example/rbac/prometheus-operator/prometheus-operator-service-monitor.yaml +++ b/example/rbac/prometheus-operator/prometheus-operator-service-monitor.yaml @@ -4,7 +4,7 @@ metadata: labels: app.kubernetes.io/component: controller app.kubernetes.io/name: prometheus-operator - app.kubernetes.io/version: 0.47.1 + app.kubernetes.io/version: 0.48.1 name: prometheus-operator namespace: default spec: @@ -15,4 +15,4 @@ spec: matchLabels: app.kubernetes.io/component: controller app.kubernetes.io/name: prometheus-operator - app.kubernetes.io/version: 0.47.1 + app.kubernetes.io/version: 0.48.1 diff --git a/example/rbac/prometheus-operator/prometheus-operator-service.yaml b/example/rbac/prometheus-operator/prometheus-operator-service.yaml index 4b773bf14c..ae66b156b6 100644 --- a/example/rbac/prometheus-operator/prometheus-operator-service.yaml +++ b/example/rbac/prometheus-operator/prometheus-operator-service.yaml @@ -4,7 +4,7 @@ metadata: labels: app.kubernetes.io/component: controller app.kubernetes.io/name: prometheus-operator - app.kubernetes.io/version: 0.47.1 + app.kubernetes.io/version: 0.48.1 name: prometheus-operator namespace: default spec: diff --git a/example/thanos/prometheus-service.yaml b/example/thanos/prometheus-service.yaml index 8f7bd4a97c..3a3209f9ff 100644 --- a/example/thanos/prometheus-service.yaml +++ b/example/thanos/prometheus-service.yaml @@ -2,7 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: - app: prometheus + app.kubernetes.io/name: prometheus prometheus: self name: prometheus-self namespace: default diff --git a/example/thanos/prometheus-servicemonitor.yaml b/example/thanos/prometheus-servicemonitor.yaml index 08390565f5..cd588618ff 100644 --- a/example/thanos/prometheus-servicemonitor.yaml +++ b/example/thanos/prometheus-servicemonitor.yaml @@ -2,7 +2,7 @@ apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: labels: - app: prometheus + app.kubernetes.io/name: prometheus prometheus: self name: prometheus-self namespace: default @@ -12,4 +12,4 @@ spec: port: web selector: matchLabels: - app: prometheus + app.kubernetes.io/name: prometheus diff --git a/example/thanos/prometheus.yaml b/example/thanos/prometheus.yaml index 6d0e85ea5b..ceff02a2a8 100644 --- a/example/thanos/prometheus.yaml +++ b/example/thanos/prometheus.yaml @@ -13,6 +13,6 @@ spec: role: prometheus-rulefiles serviceMonitorSelector: matchLabels: - app: prometheus + app.kubernetes.io/name: prometheus thanos: version: v0.11.2 diff --git a/example/thanos/query-deployment.yaml b/example/thanos/query-deployment.yaml index c4d497cbd8..8dd8f87635 100644 --- a/example/thanos/query-deployment.yaml +++ b/example/thanos/query-deployment.yaml @@ -2,18 +2,18 @@ apiVersion: apps/v1 kind: Deployment metadata: labels: - app: thanos-query + app.kubernetes.io/name: thanos-query name: thanos-query namespace: default spec: replicas: 1 selector: matchLabels: - app: thanos-query + app.kubernetes.io/name: thanos-query template: metadata: labels: - app: thanos-query + app.kubernetes.io/name: thanos-query spec: containers: - args: diff --git a/example/thanos/query-service.yaml b/example/thanos/query-service.yaml index 79c7e618af..51830a3bf6 100644 --- a/example/thanos/query-service.yaml +++ b/example/thanos/query-service.yaml @@ -2,7 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: - app: thanos-query + app.kubernetes.io/name: thanos-query name: thanos-query namespace: default spec: @@ -11,4 +11,4 @@ spec: port: 10902 targetPort: http selector: - app: thanos-query + app.kubernetes.io/name: thanos-query diff --git a/example/thanos/sidecar-service.yaml b/example/thanos/sidecar-service.yaml index 5988e2ac30..8b802fa08b 100644 --- a/example/thanos/sidecar-service.yaml +++ b/example/thanos/sidecar-service.yaml @@ -2,7 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: - app: thanos-sidecar + app.kubernetes.io/name: thanos-sidecar name: thanos-sidecar namespace: default spec: diff --git a/example/thanos/thanos-ruler-service.yaml b/example/thanos/thanos-ruler-service.yaml index d51d09353a..c641318ded 100644 --- a/example/thanos/thanos-ruler-service.yaml +++ b/example/thanos/thanos-ruler-service.yaml @@ -2,7 +2,7 @@ apiVersion: v1 kind: Service metadata: labels: - app: thanos-ruler + app.kubernetes.io/name: thanos-ruler name: thanos-ruler namespace: default spec: @@ -14,4 +14,4 @@ spec: port: 10902 targetPort: web selector: - app: thanos-ruler + app.kubernetes.io/name: thanos-ruler diff --git a/example/thanos/thanos-ruler.yaml b/example/thanos/thanos-ruler.yaml index 1f0db19ad3..47b0be2297 100644 --- a/example/thanos/thanos-ruler.yaml +++ b/example/thanos/thanos-ruler.yaml @@ -2,7 +2,7 @@ apiVersion: monitoring.coreos.com/v1 kind: ThanosRuler metadata: labels: - app: thanos-ruler + app.kubernetes.io/name: thanos-ruler name: thanos-ruler namespace: default spec: diff --git a/go.mod b/go.mod index 647055d824..92d88172b8 100644 --- a/go.mod +++ b/go.mod @@ -18,14 +18,14 @@ require ( github.com/oklog/run v1.1.0 github.com/pkg/errors v0.9.1 github.com/prometheus-community/prom-label-proxy v0.2.0 - github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.47.1 - github.com/prometheus-operator/prometheus-operator/pkg/client v0.47.1 - github.com/prometheus/alertmanager v0.21.1-0.20201106142418-c39b78780054 + github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.48.1 + github.com/prometheus-operator/prometheus-operator/pkg/client v0.48.1 + github.com/prometheus/alertmanager v0.21.1-0.20210422101724-8176f78a70e1 github.com/prometheus/client_golang v1.10.0 - github.com/prometheus/common v0.20.0 - github.com/prometheus/prometheus v1.8.2-0.20210215121130-6f488061dfb4 + github.com/prometheus/common v0.21.0 + github.com/prometheus/prometheus v1.8.2-0.20210421143221-52df5ef7a3be github.com/stretchr/testify v1.7.0 - github.com/thanos-io/thanos v0.19.0 + github.com/thanos-io/thanos v0.20.1 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c google.golang.org/protobuf v1.26.0 gopkg.in/alecthomas/kingpin.v2 v2.2.6 diff --git a/go.sum b/go.sum index 6266ae9bc9..a23a9956fb 100644 --- a/go.sum +++ b/go.sum @@ -19,6 +19,8 @@ cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOY cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= +cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= @@ -55,6 +57,7 @@ github.com/Azure/azure-sdk-for-go v45.1.0+incompatible/go.mod h1:9XXNKU+eRnpl9mo github.com/Azure/azure-sdk-for-go v46.4.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/azure-sdk-for-go v48.2.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/azure-sdk-for-go v51.2.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/azure-sdk-for-go v52.5.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/azure-storage-blob-go v0.8.0/go.mod h1:lPI3aLPpuLTeUwh1sViKXFxwl2B6teiRqI0deQUvsw0= github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= github.com/Azure/go-autorest v11.2.8+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= @@ -177,6 +180,7 @@ github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/ github.com/aws/aws-sdk-go v1.35.5/go.mod h1:tlPOdRjfxPBpNIwqDj61rmsnA85v9jc0Ps9+muhnW+k= github.com/aws/aws-sdk-go v1.35.31/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= github.com/aws/aws-sdk-go v1.37.8/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= +github.com/aws/aws-sdk-go v1.38.3/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= github.com/baiyubin/aliyun-sts-go-sdk v0.0.0-20180326062324-cfa1a18b161f/go.mod h1:AuiFmCCPBSrqvVMvuqFuk0qogytodnVFVSN5CeJB8Gc= github.com/beevik/ntp v0.2.0/go.mod h1:hIHWr+l3+/clUnF44zdK+CWW7fO8dR5cIylAQ76NRpg= @@ -204,7 +208,9 @@ github.com/cenkalti/backoff v0.0.0-20181003080854-62661b46c409/go.mod h1:90ReRw6 github.com/cenkalti/backoff v1.0.0/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= github.com/cenkalti/backoff/v4 v4.0.2/go.mod h1:eEew/i+1Q6OrCDZh3WiXYv3+nJwBASZ8Bog/87DQnVg= +github.com/cenkalti/backoff/v4 v4.1.0/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/certifi/gocertifi v0.0.0-20191021191039-0944d244cd40/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= github.com/cespare/xxhash v0.0.0-20181017004759-096ff4a8a059/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= @@ -223,10 +229,14 @@ github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4 github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/cockroachdb/cockroach-go v0.0.0-20181001143604-e0a95dfd547c/go.mod h1:XGLbWH/ujMcbPbhZq52Nv6UrCghb1yGn//133kEsvDk= github.com/cockroachdb/datadriven v0.0.0-20190531201743-edce55837238/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= +github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo= +github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA= +github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= github.com/containerd/containerd v1.2.7/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= github.com/containerd/containerd v1.3.4/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= @@ -242,6 +252,7 @@ github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7 github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/pkg v0.0.0-20180108230652-97fdf19511ea/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= @@ -253,12 +264,15 @@ github.com/cortexproject/cortex v1.5.1-0.20201111110551-ba512881b076/go.mod h1:z github.com/cortexproject/cortex v1.6.1-0.20210108144208-6c2dab103f20/go.mod h1:fOsaeeFSyWrjd9nFJO8KVUpsikcxnYsjEzQyjURBoQk= github.com/cortexproject/cortex v1.6.1-0.20210215155036-dfededd9f331/go.mod h1:8bRHNDawVx8te5lIqJ+/AcNTyfosYNC34Qah7+jX/8c= github.com/cortexproject/cortex v1.7.1-0.20210224085859-66d6fb5b0d42/go.mod h1:u2dxcHInYbe45wxhLoWVdlFJyDhXewsMcxtnbq/QbH4= +github.com/cortexproject/cortex v1.7.1-0.20210316085356-3fedc1108a49/go.mod h1:/DBOW8TzYBTE/U+O7Whs7i7E2eeeZl1iRVDtIqxn5kg= +github.com/cortexproject/cortex v1.8.1-0.20210422151339-cf1c444e0905/go.mod h1:xxm4/CLvTmDxwE7yXwtClR4dIvkG4S09o5DygPOgc1U= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/cucumber/godog v0.8.1/go.mod h1:vSh3r/lM+psC1BPXvdkSEuNjmXfpVqrMGYAElF6hxnA= github.com/cznic/b v0.0.0-20180115125044-35e9bbe41f07/go.mod h1:URriBxXwVq5ijiJ12C7iIZqlA69nTlI+LgI6/pwftG8= github.com/cznic/fileutil v0.0.0-20180108211300-6a051e75936f/go.mod h1:8S58EK26zhXSxzv7NQFpnliaOQsmDUxvoQO3rt154Vg= github.com/cznic/golex v0.0.0-20170803123110-4ab7c5e190e4/go.mod h1:+bmmJDNmKlhWNG+gwWCkaBoTy39Fs+bzRxVBzoTQbIc= @@ -289,6 +303,8 @@ github.com/digitalocean/godo v1.42.1/go.mod h1:p7dOjjtSBqCTUksqtA5Fd3uaKs9kyTq2x github.com/digitalocean/godo v1.46.0/go.mod h1:p7dOjjtSBqCTUksqtA5Fd3uaKs9kyTq2xcz76ulEJRU= github.com/digitalocean/godo v1.52.0/go.mod h1:p7dOjjtSBqCTUksqtA5Fd3uaKs9kyTq2xcz76ulEJRU= github.com/digitalocean/godo v1.57.0/go.mod h1:p7dOjjtSBqCTUksqtA5Fd3uaKs9kyTq2xcz76ulEJRU= +github.com/digitalocean/godo v1.58.0/go.mod h1:p7dOjjtSBqCTUksqtA5Fd3uaKs9kyTq2xcz76ulEJRU= +github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= github.com/docker/distribution v2.7.0+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug= github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= @@ -297,6 +313,7 @@ github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r github.com/docker/docker v0.7.3-0.20190817195342-4760db040282/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v17.12.0-ce-rc1.0.20200706150819-a40b877fbb9e+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/docker v20.10.3+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v20.10.5+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= @@ -326,6 +343,7 @@ github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymF github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/evanphx/json-patch v0.0.0-20200808040245-162e5629780b/go.mod h1:NAJj0yf/KaRKURN6nyi7A9IZydMivZEm9oQLWNjfKDc= github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= @@ -349,6 +367,7 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsouza/fake-gcs-server v1.7.0/go.mod h1:5XIRs4YvwNbNoz+1JF8j6KLAyDh7RHGAyAK3EP2EsNk= +github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= @@ -390,8 +409,9 @@ github.com/go-openapi/errors v0.19.4/go.mod h1:qX0BLWsyaKfvhluLejVpVNwNRdXZhEbTA github.com/go-openapi/errors v0.19.6/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= github.com/go-openapi/errors v0.19.7/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= github.com/go-openapi/errors v0.19.8/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= -github.com/go-openapi/errors v0.19.9 h1:9SnKdGhiPZHF3ttwFMiCBEb8jQ4IDdrK+5+a0oTygA4= github.com/go-openapi/errors v0.19.9/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/errors v0.20.0 h1:Sxpo9PjEHDzhs3FbnGNonvDgWcMW2U7wGTcDDSFSceM= +github.com/go-openapi/errors v0.20.0/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= github.com/go-openapi/jsonpointer v0.17.2/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M= @@ -429,8 +449,9 @@ github.com/go-openapi/runtime v0.19.3/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29g github.com/go-openapi/runtime v0.19.4/go.mod h1:X277bwSUBxVlCYR3r7xgZZGKVvBd/29gLDlFGtJ8NL4= github.com/go-openapi/runtime v0.19.15/go.mod h1:dhGWCTKRXlAfGnQG0ONViOZpjfg0m2gUt9nTQPQZuoo= github.com/go-openapi/runtime v0.19.16/go.mod h1:5P9104EJgYcizotuXhEuUrzVc+j1RiSjahULvYmlv98= -github.com/go-openapi/runtime v0.19.24 h1:TqagMVlRAOTwllE/7hNKx6rQ10O6T8ZzeJdMjSTKaD4= github.com/go-openapi/runtime v0.19.24/go.mod h1:Lm9YGCeecBnUUkFTxPC4s1+lwrkJ0pthx8YvyjCfkgk= +github.com/go-openapi/runtime v0.19.26 h1:K/6PoVNj5WJXUnMk+VEbELeXjtBkCS1UxTDa04tdXE0= +github.com/go-openapi/runtime v0.19.26/go.mod h1:BvrQtn6iVb2QmiVXRsFAm6ZCAZBpbVKFfN6QWCp582M= github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= github.com/go-openapi/spec v0.17.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= github.com/go-openapi/spec v0.17.2/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI= @@ -493,6 +514,7 @@ github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-zookeeper/zk v1.0.2/go.mod h1:nOB03cncLtlp4t+UAkGSV+9beXP/akpekBwL+UX1Qcw= github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY= github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg= @@ -524,7 +546,9 @@ github.com/gocql/gocql v0.0.0-20190301043612-f6df8288f9b4/go.mod h1:4Fw1eo5iaEhD github.com/gocql/gocql v0.0.0-20200121121104-95d072f1b5bb/go.mod h1:DL0ekTmBSTdlNF25Orwt/JMzqIq3EJ4MVa/J/uK64OY= github.com/gocql/gocql v0.0.0-20200526081602-cd04bd7f22a7/go.mod h1:DL0ekTmBSTdlNF25Orwt/JMzqIq3EJ4MVa/J/uK64OY= github.com/godbus/dbus v0.0.0-20190402143921-271e53dc4968/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= +github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= github.com/gogo/protobuf v1.0.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= @@ -556,6 +580,7 @@ github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -577,8 +602,9 @@ github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8l github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.2/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.3-0.20201103224600-674baa8c7fc3 h1:ur2rms48b3Ep1dxh7aUV2FZEQ8jEVO2F6ILKx8ofkAg= github.com/golang/snappy v0.0.3-0.20201103224600-674baa8c7fc3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.3 h1:fHPg5GQYlCeLIPB9BZqMVR5nR9A+IM5zcgeTdjMYmLA= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/gomodule/redigo v1.8.4/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0= github.com/gomodule/redigo v2.0.0+incompatible/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= github.com/google/btree v0.0.0-20180124185431-e89373fe6b4a/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -593,6 +619,7 @@ github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= @@ -620,7 +647,10 @@ github.com/google/pprof v0.0.0-20201007051231-1066cbb265c7/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201117184057-ae444373da19/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210208152844-1612e9be7af6/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210323184331-8eee2492667d/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -646,6 +676,7 @@ github.com/gophercloud/gophercloud v0.12.0/go.mod h1:gmC5oQqMDOMO1t1gq5DquX/yAU8 github.com/gophercloud/gophercloud v0.13.0/go.mod h1:VX0Ibx85B60B5XOrZr6kaNwrmPUzcmMpwxvQ1WQIIWM= github.com/gophercloud/gophercloud v0.14.0/go.mod h1:VX0Ibx85B60B5XOrZr6kaNwrmPUzcmMpwxvQ1WQIIWM= github.com/gophercloud/gophercloud v0.15.0/go.mod h1:VX0Ibx85B60B5XOrZr6kaNwrmPUzcmMpwxvQ1WQIIWM= +github.com/gophercloud/gophercloud v0.16.0/go.mod h1:wRtmUelyIIv3CSSDI47aUwbs075O6i+LY+pXsKCBsb4= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20191106031601-ce3c9ade29de/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= @@ -659,6 +690,10 @@ github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:Fecb github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= github.com/grpc-ecosystem/go-grpc-middleware v1.1.0/go.mod h1:f5nM7jw/oeRSadq3xCzHAvxcr8HZnzsqU6ILg/0NiiE= +github.com/grpc-ecosystem/go-grpc-middleware v1.2.2/go.mod h1:EaizFBKfUKtMIF5iaDEhniwNedqGo9FuLFzppDr3uwI= +github.com/grpc-ecosystem/go-grpc-middleware/providers/kit/v2 v2.0.0-20201002093600-73cf2ae9d891/go.mod h1:516cTXxZzi4NBUBbKcwmO4Eqbb6GHAEd3o4N+GYyCBY= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-20200501113911-9a95f0fdbfea/go.mod h1:GugMBs30ZSAkckqXEAIEGyYdDH6EgqowG8ppA3Zt+AY= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.0.0-rc.2.0.20201207153454-9f6bf00c00a7/go.mod h1:GhphxcdlaRyAuBSvo6rV71BvQcvB/vuX8ugCyybuS2k= github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= github.com/grpc-ecosystem/grpc-gateway v1.4.1/go.mod h1:RSKVYQBd5MCa4OVpNdGskqpgL2+G+NZTnrVHpWWfpdw= github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= @@ -669,6 +704,7 @@ github.com/grpc-ecosystem/grpc-gateway v1.14.4/go.mod h1:6CwZWGDSPRJidgKAtJVvND6 github.com/grpc-ecosystem/grpc-gateway v1.14.6/go.mod h1:zdiPV4Yse/1gnckTHtghG4GkDEdKCRJduHpTxT3/jcw= github.com/grpc-ecosystem/grpc-gateway v1.15.0/go.mod h1:vO11I9oWA+KsxmfFQPhLnnIb1VDE24M+pdxZFiuZcA8= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/grpc-ecosystem/grpc-opentracing v0.0.0-20180507213350-8e809c8a8645/go.mod h1:6iZfnjpejD4L/4DwD7NryNaJyCQdzwWwH2MWhCA90Kw= github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= @@ -731,6 +767,7 @@ github.com/hashicorp/serf v0.9.5/go.mod h1:UWDWwZeL5cuWDJdl0C6wrvrUwEqtQ4ZKBKKEN github.com/hetznercloud/hcloud-go v1.21.1/go.mod h1:xng8lbDUg+xM1dgc0yGHX5EeqbwIq7UYlMWMTx3SQVg= github.com/hetznercloud/hcloud-go v1.22.0/go.mod h1:xng8lbDUg+xM1dgc0yGHX5EeqbwIq7UYlMWMTx3SQVg= github.com/hetznercloud/hcloud-go v1.23.1/go.mod h1:xng8lbDUg+xM1dgc0yGHX5EeqbwIq7UYlMWMTx3SQVg= +github.com/hetznercloud/hcloud-go v1.24.0/go.mod h1:3YmyK8yaZZ48syie6xpm3dt26rtB6s65AisBHylXYFA= github.com/hodgesds/perf-utils v0.0.8/go.mod h1:F6TfvsbtrF88i++hou29dTXlI2sfsJv+gRZDtmTJkAs= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= @@ -767,6 +804,7 @@ github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfC github.com/joeshaw/multierror v0.0.0-20140124173710-69b34d4ec901/go.mod h1:Z86h9688Y0wesXCyonoVr47MasHilkuLMqGhRZ4Hpak= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/jpillora/backoff v0.0.0-20180909062703-3050d21c67d7/go.mod h1:2iMrUgbbvHEiQClaW2NsSzMyGHqN+rDFqY705q49KG0= @@ -889,6 +927,7 @@ github.com/miekg/dns v1.1.30/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7 github.com/miekg/dns v1.1.31/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= github.com/miekg/dns v1.1.35/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= github.com/miekg/dns v1.1.38/go.mod h1:KNUDUusw/aVsxyTYZM1oqvCicbwhgbNgztCETuNZ7xM= +github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= github.com/minio/md5-simd v1.1.0/go.mod h1:XpBqgZULrMYD3R+M28PcmP0CkI7PEMzB3U77ZrKZ0Gw= github.com/minio/minio-go/v6 v6.0.44/go.mod h1:qD0lajrGW49lKZLtXKtCB4X/qkMf0a5tBvN2PaZg7Gg= github.com/minio/minio-go/v6 v6.0.56/go.mod h1:KQMM+/44DSlSGSQWSfRrAZ12FVMmpWNuX37i2AX0jfI= @@ -986,6 +1025,7 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8 github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= github.com/opentracing-contrib/go-grpc v0.0.0-20180928155321-4b5a12d3ff02/go.mod h1:JNdpVEzCpXBgIiv4ds+TzhN1hrtxq6ClLrTlT9OQRSc= +github.com/opentracing-contrib/go-grpc v0.0.0-20210225150812-73cb765af46e/go.mod h1:DYR5Eij8rJl8h7gblRrOZ8g0kW1umSpKqYIBTgeDtLo= github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= github.com/opentracing-contrib/go-stdlib v0.0.0-20190519235532-cf7a6c988dc9/go.mod h1:PLldrQSroqzH70Xl+1DQcGnefIbqsKR7UDaiux3zV+w= github.com/opentracing-contrib/go-stdlib v1.0.0/go.mod h1:qtI1ogk+2JhVPIXVc6q+NHziSmy2W5GbdQZFUHADCBU= @@ -1033,8 +1073,10 @@ github.com/prometheus/alertmanager v0.19.0/go.mod h1:Eyp94Yi/T+kdeb2qvq66E3RGuph github.com/prometheus/alertmanager v0.20.0/go.mod h1:9g2i48FAyZW6BtbsnvHtMHQXl2aVtrORKwKVCQ+nbrg= github.com/prometheus/alertmanager v0.21.0/go.mod h1:h7tJ81NA0VLWvWEayi1QltevFkLF3KxmC/malTcT8Go= github.com/prometheus/alertmanager v0.21.1-0.20200911160112-1fdff6b3f939/go.mod h1:imXRHOP6QTsE0fFsIsAV/cXimS32m7gVZOiUj11m6Ig= -github.com/prometheus/alertmanager v0.21.1-0.20201106142418-c39b78780054 h1:NgCRBfzDpyIhX6Pjh7XSWPHUC8T5dA1yVuK/gwXM7Jw= github.com/prometheus/alertmanager v0.21.1-0.20201106142418-c39b78780054/go.mod h1:imXRHOP6QTsE0fFsIsAV/cXimS32m7gVZOiUj11m6Ig= +github.com/prometheus/alertmanager v0.21.1-0.20210310093010-0f9cab6991e6/go.mod h1:MTqVn+vIupE0dzdgo+sMcNCp37SCAi8vPrvKTTnTz9g= +github.com/prometheus/alertmanager v0.21.1-0.20210422101724-8176f78a70e1 h1:i7S+d1wua/WE/ipFcX2hSUN6Fqn+8+pMQPjFTBxGWFE= +github.com/prometheus/alertmanager v0.21.1-0.20210422101724-8176f78a70e1/go.mod h1:gsEqwD5BHHW9RNKvCuPOrrTMiP5I+faJUyLXvnivHik= github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= @@ -1078,8 +1120,10 @@ github.com/prometheus/common v0.12.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16 github.com/prometheus/common v0.14.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= github.com/prometheus/common v0.15.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= github.com/prometheus/common v0.18.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= -github.com/prometheus/common v0.20.0 h1:pfeDeUdQcIxOMutNjCejsEFp7qeP+/iltHSSmLpE+hU= github.com/prometheus/common v0.20.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= +github.com/prometheus/common v0.21.0 h1:SMvI2JVldvfUvRVlP64jkIJEC6WiGHJcN2e5tB+ztF8= +github.com/prometheus/common v0.21.0/go.mod h1:U+gB1OBLb1lF3O42bTCL+FK18tX9Oar16Clt/msog/s= +github.com/prometheus/exporter-toolkit v0.5.0/go.mod h1:OCkM4805mmisBhLmVFw858QYi3v0wKdY6/UxrT0pZVg= github.com/prometheus/exporter-toolkit v0.5.1/go.mod h1:OCkM4805mmisBhLmVFw858QYi3v0wKdY6/UxrT0pZVg= github.com/prometheus/node_exporter v1.0.0-rc.0.0.20200428091818-01054558c289/go.mod h1:FGbBv5OPKjch+jNUJmEQpMZytIdyW0NdBtWFcfSKusc= github.com/prometheus/procfs v0.0.0-20180612222113-7d6f385de8be/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= @@ -1112,8 +1156,11 @@ github.com/prometheus/prometheus v1.8.2-0.20201028100903-3245b3267b24/go.mod h1: github.com/prometheus/prometheus v1.8.2-0.20201029103703-63be30dceed9/go.mod h1:MDRkz271loM/PrYN+wUNEaTMDGSP760MQzB0yEjdgSQ= github.com/prometheus/prometheus v1.8.2-0.20201119142752-3ad25a6dc3d9/go.mod h1:1MDE/bXgu4gqd5w/otko6WQpXZX9vu8QX4KbitCmaPg= github.com/prometheus/prometheus v1.8.2-0.20201119181812-c8f810083d3f/go.mod h1:1MDE/bXgu4gqd5w/otko6WQpXZX9vu8QX4KbitCmaPg= -github.com/prometheus/prometheus v1.8.2-0.20210215121130-6f488061dfb4 h1:EbUBvqL6oYUwL6IAI4OzxM9GYbRE+/N+maV/w5+v6Ac= github.com/prometheus/prometheus v1.8.2-0.20210215121130-6f488061dfb4/go.mod h1:NAYujktP0dmSSpeV155mtnwX2pndLpVVK/Ps68R01TA= +github.com/prometheus/prometheus v1.8.2-0.20210315220929-1cba1741828b/go.mod h1:MS/bpdil77lPbfQeKk6OqVQ9OLnpN3Rszd0hka0EOWE= +github.com/prometheus/prometheus v1.8.2-0.20210324152458-c7a62b95cea0/go.mod h1:sf7j/iAbhZahjeC0s3wwMmp5dksrJ/Za1UKdR+j6Hmw= +github.com/prometheus/prometheus v1.8.2-0.20210421143221-52df5ef7a3be h1:Kt84gUEhCC04CEqQxML1W+wzpydx1t3rmaEq1H971ZM= +github.com/prometheus/prometheus v1.8.2-0.20210421143221-52df5ef7a3be/go.mod h1:WbIKsp4vWCoPHis5qQfd0QimLOR7qe79roXN5O8U8bs= github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= github.com/rafaeljusto/redigomock v0.0.0-20190202135759-257e089e14a1/go.mod h1:JaY6n2sDr+z2WTsXkOmNRUfDy6FN0L6Nk7x06ndm4tY= github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= @@ -1138,6 +1185,7 @@ github.com/santhosh-tekuri/jsonschema v1.2.4/go.mod h1:TEAUOeZSmIxTTuHatJzrvARHi github.com/satori/go.uuid v0.0.0-20160603004225-b111a074d5ef/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= 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.7.0.20210223165440-c65ae3540d44/go.mod h1:CJJ5VAbozOl0yEw7nHB9+7BXTJbIn6h7W+f6Gau5IP8= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= github.com/segmentio/fasthash v0.0.0-20180216231524-a72b379d632e/go.mod h1:tm/wZFQ8e24NYaBGIlnO2WGCAi67re4HHuOm0sftE/M= github.com/segmentio/kafka-go v0.1.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo= @@ -1171,6 +1219,7 @@ github.com/smartystreets/assertions v1.0.1/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUr github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/soheilhy/cmux v0.1.5-0.20210205191134-5ec6847320e5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/soundcloud/go-runit v0.0.0-20150630195641-06ad41a06c4a/go.mod h1:LeFCbQYJ3KJlPs/FvPz2dy1tkpxyeNESVyCNNzRXFR0= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= @@ -1214,14 +1263,17 @@ github.com/thanos-io/thanos v0.13.1-0.20201030101306-47f9a225cc52/go.mod h1:OqqX github.com/thanos-io/thanos v0.13.1-0.20210108102609-f85e4003ba51/go.mod h1:kPvI4H0AynFiHDN95ZB28/k70ZPGCx+pBrRh6RZPimw= github.com/thanos-io/thanos v0.13.1-0.20210204123931-82545cdd16fe/go.mod h1:ZLDGYRNkgM+FCwYNOD+6tOV+DE2fpjzfV6iqXyOgFIw= github.com/thanos-io/thanos v0.13.1-0.20210224074000-659446cab117/go.mod h1:kdqFpzdkveIKpNNECVJd75RPvgsAifQgJymwCdfev1w= -github.com/thanos-io/thanos v0.19.0 h1:7rprG47MzD3JGEIHmsjoxrXt3Pv52lGKTNYZdzoIpGA= -github.com/thanos-io/thanos v0.19.0/go.mod h1:+mXfPepU1VrKw/fMfG2LIKF0NunOTZll452nGEFALhw= +github.com/thanos-io/thanos v0.13.1-0.20210226164558-03dace0a1aa1/go.mod h1:gMCy4oCteKTT7VuXVvXLTPGzzjovX1VPE5p+HgL1hyU= +github.com/thanos-io/thanos v0.13.1-0.20210401085038-d7dff0c84d17/go.mod h1:zU8KqE+6A+HksK4wiep8e/3UvCZLm+Wrw9AqZGaAm9k= +github.com/thanos-io/thanos v0.20.1 h1:PSLmJUoO/BAbwnXgmX2K6z2jPEAFRp8cJqgCm9uYRe8= +github.com/thanos-io/thanos v0.20.1/go.mod h1:zvSf4uKtey4KjSVcalV/5oUuGthaTzI8kVDrO42I8II= github.com/tidwall/pretty v0.0.0-20180105212114-65a9db5fad51/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= github.com/tinylib/msgp v1.0.2/go.mod h1:+d+yLhGm8mzTaHzB+wgMYrodPfmZrzkirds8fDWklFE= github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tmc/grpc-websocket-proxy v0.0.0-20200427203606-3cfed13b9966/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/uber/jaeger-client-go v2.15.0+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= github.com/uber/jaeger-client-go v2.20.1+incompatible/go.mod h1:WVhlPFC8FDjOFMMWRy2pZqQJSXxYSwNYOkTr/Z6d3Kk= @@ -1244,6 +1296,7 @@ github.com/weaveworks/common v0.0.0-20200625145055-4b1847531bc9/go.mod h1:c98fKi github.com/weaveworks/common v0.0.0-20200914083218-61ffdd448099/go.mod h1:hz10LOsAdzC3K/iXaKoFxOKTDRgxJl+BTGX1GY+TzO4= github.com/weaveworks/common v0.0.0-20201119133501-0619918236ec/go.mod h1:ykzWac1LtVfOxdCK+jD754at1Ws9dKCwFeUzkFBffPs= github.com/weaveworks/common v0.0.0-20210112142934-23c8d7fa6120/go.mod h1:ykzWac1LtVfOxdCK+jD754at1Ws9dKCwFeUzkFBffPs= +github.com/weaveworks/common v0.0.0-20210419092856-009d1eebd624/go.mod h1:ykzWac1LtVfOxdCK+jD754at1Ws9dKCwFeUzkFBffPs= github.com/weaveworks/promrus v1.2.0/go.mod h1:SaE82+OJ91yqjrE1rsvBWVzNZKcHYFtMUyS1+Ogs/KA= github.com/willf/bitset v1.1.3/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= github.com/xanzy/go-gitlab v0.15.0/go.mod h1:8zdQa/ri1dfn8eS3Ir1SyfvOKlw7WBJ8DVThkpGiXrs= @@ -1261,9 +1314,13 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/gopher-lua v0.0.0-20200816102855-ee81675732da/go.mod h1:E1AXubJBdNmFERAOucpDIxNzeGfLzg0mYh+UfMWdChA= gitlab.com/nyarla/go-crypt v0.0.0-20160106005555-d9a5dc2b789b/go.mod h1:T3BPAOm2cqquPa0MKWeNkmOM5RQsRhkrwMWonFMN7fE= go.elastic.co/apm v1.5.0/go.mod h1:OdB9sPtM6Vt7oz3VXt7+KR96i9li74qrxBGHTQygFvk= +go.elastic.co/apm v1.11.0/go.mod h1:qoOSi09pnzJDh5fKnfY7bPmQgl8yl2tULdOu03xhui0= go.elastic.co/apm/module/apmhttp v1.5.0/go.mod h1:1FbmNuyD3ddauwzgVwFB0fqY6KbZt3JkV187tGCYYhY= +go.elastic.co/apm/module/apmhttp v1.11.0/go.mod h1:5JFMIxdeS4vJy+D1PPPjINuX6hZ3AHalZXoOgyqZAkk= go.elastic.co/apm/module/apmot v1.5.0/go.mod h1:d2KYwhJParTpyw2WnTNy8geNlHKKFX+4oK3YLlsesWE= +go.elastic.co/apm/module/apmot v1.11.0/go.mod h1:Qnbt3w1DvUd/5QugAF1AJ3mR4AG86EcJFBnAGW77EmU= go.elastic.co/fastjson v1.0.0/go.mod h1:PmeUOMMtLHQr9ZS9J9owrAVg0FkaZDRZJEFTTGHtchs= +go.elastic.co/fastjson v1.1.0/go.mod h1:boNGISWMjQsUPy/t6yqt2/1Wx4YNPSe+mZjlyw9vKKI= go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= go.etcd.io/bbolt v1.3.5-0.20200615073812-232d8fc87f50/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= @@ -1273,6 +1330,13 @@ go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mI go.etcd.io/etcd v0.5.0-alpha.5.0.20200520232829-54ba9589114f/go.mod h1:skWido08r9w6Lq/w70DO5XYIKMu4QFu1+4VsqLQuJy8= go.etcd.io/etcd v0.5.0-alpha.5.0.20200819165624-17cef6e3e9d5/go.mod h1:skWido08r9w6Lq/w70DO5XYIKMu4QFu1+4VsqLQuJy8= go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg= +go.etcd.io/etcd/api/v3 v3.5.0-alpha.0/go.mod h1:mPcW6aZJukV6Aa81LSKpBjQXTWlXB5r74ymPoSWa3Sw= +go.etcd.io/etcd/client/v2 v2.305.0-alpha.0/go.mod h1:kdV+xzCJ3luEBSIeQyB/OEKkWKd8Zkux4sbDeANrosU= +go.etcd.io/etcd/client/v3 v3.5.0-alpha.0/go.mod h1:wKt7jgDgf/OfKiYmCq5WFGxOFAkVMLxiiXgLDFhECr8= +go.etcd.io/etcd/client/v3 v3.5.0-alpha.0.0.20210225194612-fa82d11a958a/go.mod h1:wKt7jgDgf/OfKiYmCq5WFGxOFAkVMLxiiXgLDFhECr8= +go.etcd.io/etcd/pkg/v3 v3.5.0-alpha.0/go.mod h1:tV31atvwzcybuqejDoY3oaNRTtlD2l/Ot78Pc9w7DMY= +go.etcd.io/etcd/raft/v3 v3.5.0-alpha.0/go.mod h1:FAwse6Zlm5v4tEWZaTjmNhe17Int4Oxbu7+2r0DiD3w= +go.etcd.io/etcd/server/v3 v3.5.0-alpha.0.0.20210225194612-fa82d11a958a/go.mod h1:tsKetYpt980ZTpzl/gb+UOJj9RkIyCb1u4wjzMg90BQ= go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.0.4/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.1.0/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= @@ -1293,6 +1357,7 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opentelemetry.io/otel v0.11.0/go.mod h1:G8UCk+KooF2HLkgo8RHX9epABH/aRGYET7gQOqBVdB0= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -1314,6 +1379,7 @@ go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= go.uber.org/zap v1.14.1/go.mod h1:Mb2vm2krFEG5DV0W9qcHBYFtp/Wku1cvYaqPsS/WYfc= +go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= golang.org/x/crypto v0.0.0-20180608092829-8ac0e0d97ce4/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= 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= @@ -1343,6 +1409,7 @@ golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201208171446-5f87f3452ae9/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/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= @@ -1358,6 +1425,7 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/exp v0.0.0-20200331195152-e8c3332aa8e5/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= golang.org/x/exp v0.0.0-20200821190819-94841d0725da/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= 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= @@ -1383,8 +1451,9 @@ golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzB 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= -golang.org/x/mod v0.4.0 h1:8pl+sMODzuvGJkmj2W4kZihvVb5mKm8pB/X44PIQHv8= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.1 h1:Kvvh58BN8Y9/lBi7hTekvtMpm07eUZ0ck5pRHpsMWrY= +golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -1412,6 +1481,7 @@ golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190921015927-1a5e07d1ff72/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191002035440-2ec189313ef0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -1443,8 +1513,10 @@ golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210224082022-3d97a244fca7 h1:OgUuv8lsRpBibGNbSizVwKWlysjaNzmC9gYMhPVfqFM= 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-20210324051636-2c4c8ecb7826 h1:lNRDRnwZWawoPHDS50ebYHTOHjctRMLSrUSQFcAHiW4= +golang.org/x/net v0.0.0-20210324051636-2c4c8ecb7826/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1455,8 +1527,12 @@ golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210210192628-66670185b0cd h1:2arJsLyTCJGek+eeptQ3z49Rqndm0f+zvvpwNIXWNIA= golang.org/x/oauth2 v0.0.0-20210210192628-66670185b0cd/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210323180902-22b0adad7558 h1:D7nTwh4J0i+5mW4Zjzn5omvlr6YBcWywE6KOcatyNxY= +golang.org/x/oauth2 v0.0.0-20210323180902-22b0adad7558/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1555,6 +1631,7 @@ golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200918174421-af09f7315aff/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201008064518-c1f3e3309c71/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201009025420-dfb3f7c4e634/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201015000850-e3ed0017c211/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1563,9 +1640,15 @@ golang.org/x/sys v0.0.0-20201214210602-f9fddec55a1e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210309074719-68d13333faf2 h1:46ULzRKLh1CwgRq2dC5SlBzEqqNCi8rreOZnNrbqcIY= +golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210314195730-07df6a141424/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210324051608-47abb6519492 h1:Paq34FxTluEPvVyayQqMPgHm+vTOrIifmcYxFBx9TLg= +golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE= @@ -1656,6 +1739,7 @@ golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWc golang.org/x/tools v0.0.0-20200422205258-72e4a01eba43/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200509030707-2212a7e161a5/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200513201620-d5fe73897c97/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= @@ -1669,6 +1753,7 @@ golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20200822203824-307de81be3f4/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201014170642-d1624618ad65/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= golang.org/x/tools v0.0.0-20201020161133-226fd2f889ca/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201119054027-25dc3e1ccc3c/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= @@ -1712,6 +1797,9 @@ google.golang.org/api v0.32.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= google.golang.org/api v0.39.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= +google.golang.org/api v0.42.0/go.mod h1:+Oj4s6ch2SEGtPjGqfUfZonBH0GjQH89gTeKKAEGZKI= 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.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -1751,6 +1839,7 @@ google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200420144010-e5e8543f8aeb/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= @@ -1770,6 +1859,10 @@ google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210312152112-fc591d9ea70f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/grpc v1.14.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= @@ -1796,6 +1889,8 @@ google.golang.org/grpc v1.32.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1875,6 +1970,7 @@ k8s.io/api v0.18.8/go.mod h1:d/CXqwWv+Z2XEG1LgceeDmHQwpUJhROPx16SlxJgERY= k8s.io/api v0.19.2/go.mod h1:IQpK0zFQ1xc5iNIQPqzgoOwuFugaYHK4iCknlAQP9nI= k8s.io/api v0.19.4/go.mod h1:SbtJ2aHCItirzdJ36YslycFNzWADYH3tgOhvBEFtZAk= k8s.io/api v0.20.2/go.mod h1:d7n6Ehyzx+S+cE3VhTGfVNNqtGc/oL9DCdYYahlurV8= +k8s.io/api v0.20.5/go.mod h1:FQjAceXnVaWDeov2YUWhOb6Yt+5UjErkp6UO3nczO1Y= k8s.io/api v0.21.0 h1:gu5iGF4V6tfVCQ/R+8Hc0h7H1JuEhzyEi9S4R5LM8+Y= k8s.io/api v0.21.0/go.mod h1:+YbrhBBGgsxbF6o6Kj4KJPJnBmAKuXDeS3E18bgHNVU= k8s.io/apiextensions-apiserver v0.18.3/go.mod h1:TMsNGs7DYpMXd+8MOCX8KzPOCx8fnZMoIGB24m03+JE= @@ -1890,6 +1986,7 @@ k8s.io/apimachinery v0.18.8/go.mod h1:6sQd+iHEqmOtALqOFjSWp2KZ9F0wlU/nWm0ZgsYWMi k8s.io/apimachinery v0.19.2/go.mod h1:DnPGDnARWFvYa3pMHgSxtbZb7gpzzAZ1pTfaUNDVlmA= k8s.io/apimachinery v0.19.4/go.mod h1:DnPGDnARWFvYa3pMHgSxtbZb7gpzzAZ1pTfaUNDVlmA= k8s.io/apimachinery v0.20.2/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= +k8s.io/apimachinery v0.20.5/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= k8s.io/apimachinery v0.21.0 h1:3Fx+41if+IRavNcKOz09FwEXDBG6ORh6iMsTSelhkMA= k8s.io/apimachinery v0.21.0/go.mod h1:jbreFvJo3ov9rj7eWT7+sYiRx+qZuCYXwWT1bcDswPY= k8s.io/apiserver v0.18.3/go.mod h1:tHQRmthRPLUtwqsOnJJMoI8SW3lnoReZeE861lH8vUw= diff --git a/jsonnet/prometheus-operator/jsonnetfile.json b/jsonnet/prometheus-operator/jsonnetfile.json index c5b89fc205..9757fe1126 100644 --- a/jsonnet/prometheus-operator/jsonnetfile.json +++ b/jsonnet/prometheus-operator/jsonnetfile.json @@ -1,14 +1,4 @@ { "dependencies": [ - { - "name": "ksonnet", - "source": { - "git": { - "remote": "https://github.com/ksonnet/ksonnet-lib", - "subdir": "" - } - }, - "version": "master" - } ] -} \ No newline at end of file +} diff --git a/jsonnet/prometheus-operator/prometheus-operator.libsonnet b/jsonnet/prometheus-operator/prometheus-operator.libsonnet index 78a68c6293..d927207d9f 100644 --- a/jsonnet/prometheus-operator/prometheus-operator.libsonnet +++ b/jsonnet/prometheus-operator/prometheus-operator.libsonnet @@ -151,7 +151,12 @@ function(params) { replicas: 1, selector: { matchLabels: po.config.selectorLabels }, template: { - metadata: { labels: po.config.commonLabels }, + metadata: { + labels: po.config.commonLabels, + annotations: { + "kubectl.kubernetes.io/default-container": container.name, + } + }, spec: { containers: [container], nodeSelector: { diff --git a/jsonnet/thanos/config.libsonnet b/jsonnet/thanos/config.libsonnet index d3b9077ab5..f06999e7b8 100644 --- a/jsonnet/thanos/config.libsonnet +++ b/jsonnet/thanos/config.libsonnet @@ -32,11 +32,11 @@ local service(name, namespace, labels, selector, ports) = { }, commonLabels: { prometheus: 'self', - app: 'prometheus', + 'app.kubernetes.io/name': 'prometheus', }, - queryLabels: { app: 'thanos-query' }, - sidecarLabels: { app: 'thanos-sidecar' }, - rulerLabels: { app: 'thanos-ruler' }, + queryLabels: { 'app.kubernetes.io/name': 'thanos-query' }, + sidecarLabels: { 'app.kubernetes.io/name': 'thanos-sidecar' }, + rulerLabels: { 'app.kubernetes.io/name': 'thanos-ruler' }, }, }, @@ -66,7 +66,7 @@ local service(name, namespace, labels, selector, ports) = { replicas: 2, serviceMonitorSelector: { matchLabels: { - app: 'prometheus', + 'app.kubernetes.io/name': 'prometheus', }, }, ruleSelector: { @@ -145,7 +145,7 @@ local service(name, namespace, labels, selector, ports) = { ], selector: { matchLabels: { - app: 'prometheus', + 'app.kubernetes.io/name': 'prometheus', }, }, }, diff --git a/pkg/alertmanager/amcfg.go b/pkg/alertmanager/amcfg.go index 5c9ea88e62..deba2af3d2 100644 --- a/pkg/alertmanager/amcfg.go +++ b/pkg/alertmanager/amcfg.go @@ -29,7 +29,6 @@ import ( monitoringv1alpha1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1alpha1" "github.com/prometheus-operator/prometheus-operator/pkg/assets" "github.com/prometheus/alertmanager/config" - commoncfg "github.com/prometheus/common/config" "gopkg.in/yaml.v2" "k8s.io/apimachinery/pkg/types" ) @@ -826,8 +825,8 @@ func (cg *configGenerator) convertHTTPConfig(ctx context.Context, in monitoringv return out, nil } -func (cg *configGenerator) convertTLSConfig(ctx context.Context, in *monitoringv1.SafeTLSConfig, crKey types.NamespacedName) commoncfg.TLSConfig { - out := commoncfg.TLSConfig{ +func (cg *configGenerator) convertTLSConfig(ctx context.Context, in *monitoringv1.SafeTLSConfig, crKey types.NamespacedName) tlsConfig { + out := tlsConfig{ ServerName: in.ServerName, InsecureSkipVerify: in.InsecureSkipVerify, } diff --git a/pkg/alertmanager/operator.go b/pkg/alertmanager/operator.go index cc5e6b64b9..9ca0b204af 100644 --- a/pkg/alertmanager/operator.go +++ b/pkg/alertmanager/operator.go @@ -310,6 +310,15 @@ func (c *Operator) addHandlers() { DeleteFunc: c.handleStatefulSetDelete, UpdateFunc: c.handleStatefulSetUpdate, }) + + // The controller needs to watch the namespaces in which the + // alertmanagerconfigs live because a label change on a namespace may + // trigger a configuration change. + // It doesn't need to watch on addition/deletion though because it's + // already covered by the event handlers on alertmanagerconfigs. + c.nsAlrtCfgInf.AddEventHandler(cache.ResourceEventHandlerFuncs{ + UpdateFunc: c.handleNamespaceUpdate, + }) } func (c *Operator) handleAlertmanagerConfigAdd(obj interface{}) { @@ -673,6 +682,47 @@ func (c *Operator) handleStatefulSetUpdate(oldo, curo interface{}) { } } +func (c *Operator) handleNamespaceUpdate(oldo, curo interface{}) { + old := oldo.(*v1.Namespace) + cur := curo.(*v1.Namespace) + + level.Debug(c.logger).Log("msg", "update handler", "namespace", cur.GetName(), "old", old.ResourceVersion, "cur", cur.ResourceVersion) + + // Periodic resync may resend the Namespace without changes + // in-between. + if old.ResourceVersion == cur.ResourceVersion { + return + } + + level.Debug(c.logger).Log("msg", "Namespace updated", "namespace", cur.GetName()) + c.metrics.TriggerByCounter("Namespace", "update").Inc() + + // Check for Alertmanager instances selecting AlertmanagerConfigs in the namespace. + err := c.alrtInfs.ListAll(labels.Everything(), func(obj interface{}) { + a := obj.(*monitoringv1.Alertmanager) + + sync, err := k8sutil.LabelSelectionHasChanged(old.Labels, cur.Labels, a.Spec.AlertmanagerConfigNamespaceSelector) + if err != nil { + level.Error(c.logger).Log( + "err", err, + "name", a.Name, + "namespace", a.Namespace, + ) + return + } + + if sync { + c.enqueue(a) + } + }) + if err != nil { + level.Error(c.logger).Log( + "msg", "listing all Alertmanager instances from cache failed", + "err", err, + ) + } +} + func (c *Operator) sync(ctx context.Context, key string) error { aobj, err := c.alrtInfs.Get(key) @@ -881,25 +931,9 @@ func (c *Operator) createOrUpdateGeneratedConfigSecret(ctx context.Context, am * } generatedConfigSecret.Data[alertmanagerConfigFile] = conf - _, err := sClient.Get(ctx, generatedConfigSecret.Name, metav1.GetOptions{}) + err := k8sutil.CreateOrUpdateSecret(ctx, sClient, generatedConfigSecret) if err != nil { - if !apierrors.IsNotFound(err) { - return errors.Wrapf( - err, - "failed to check whether generated config secret already exists for Alertmanager %v in namespace %v", - am.Name, - am.Namespace, - ) - } - _, err = sClient.Create(ctx, generatedConfigSecret, metav1.CreateOptions{}) - level.Debug(c.logger).Log("msg", "created generated config secret", "secretname", generatedConfigSecret.Name) - } else { - err = k8sutil.UpdateSecret(ctx, sClient, generatedConfigSecret) - level.Debug(c.logger).Log("msg", "updated generated config secret", "secretname", generatedConfigSecret.Name) - } - - if err != nil { - return errors.Wrapf(err, "failed to update generated config secret for Alertmanager %v in namespace %v", am.Name, am.Namespace) + return errors.Wrap(err, "failed to update generated config secret") } return nil @@ -1367,26 +1401,9 @@ func (c *Operator) createOrUpdateTLSAssetSecret(ctx context.Context, am *monitor tlsAssetsSecret.Data[key.String()] = []byte(asset) } - _, err := sClient.Get(ctx, tlsAssetsSecret.Name, metav1.GetOptions{}) - if err != nil { - if !apierrors.IsNotFound(err) { - return errors.Wrapf( - err, - "failed to check whether tls assets secret already exists for Alertmanager %v in namespace %v", - am.Name, - am.Namespace, - ) - } - _, err = sClient.Create(ctx, tlsAssetsSecret, metav1.CreateOptions{}) - level.Debug(c.logger).Log("msg", "created tlsAssetsSecret", "secretname", tlsAssetsSecret.Name) - - } else { - err = k8sutil.UpdateSecret(ctx, sClient, tlsAssetsSecret) - level.Debug(c.logger).Log("msg", "updated tlsAssetsSecret", "secretname", tlsAssetsSecret.Name) - } - + err := k8sutil.CreateOrUpdateSecret(ctx, sClient, tlsAssetsSecret) if err != nil { - return errors.Wrapf(err, "failed to create TLS assets secret for Alertmanager %v in namespace %v", am.Name, am.Namespace) + return errors.Wrap(err, "failed to create TLS assets secret for Alertmanager") } return nil @@ -1409,8 +1426,8 @@ func checkAlertmanagerSpecDeprecation(key string, a *monitoringv1.Alertmanager, func ListOptions(name string) metav1.ListOptions { return metav1.ListOptions{ LabelSelector: fields.SelectorFromSet(fields.Set(map[string]string{ - "app": "alertmanager", - "alertmanager": name, + "app.kubernetes.io/name": "alertmanager", + "alertmanager": name, })).String(), } } diff --git a/pkg/alertmanager/operator_test.go b/pkg/alertmanager/operator_test.go index ca2b62ff20..241a4c80ec 100644 --- a/pkg/alertmanager/operator_test.go +++ b/pkg/alertmanager/operator_test.go @@ -819,8 +819,8 @@ func TestCheckAlertmanagerConfig(t *testing.T) { func TestListOptions(t *testing.T) { for i := 0; i < 1000; i++ { o := ListOptions("test") - if o.LabelSelector != "app=alertmanager,alertmanager=test" && o.LabelSelector != "alertmanager=test,app=alertmanager" { - t.Fatalf("LabelSelector not computed correctly\n\nExpected: \"app=alertmanager,alertmanager=test\"\n\nGot: %#+v", o.LabelSelector) + if o.LabelSelector != "app.kubernetes.io/name=alertmanager,alertmanager=test" && o.LabelSelector != "alertmanager=test,app.kubernetes.io/name=alertmanager" { + t.Fatalf("LabelSelector not computed correctly\n\nExpected: \"app.kubernetes.io/name=alertmanager,alertmanager=test\"\n\nGot: %#+v", o.LabelSelector) } } } diff --git a/pkg/alertmanager/statefulset.go b/pkg/alertmanager/statefulset.go index 272cb028c1..d609463766 100644 --- a/pkg/alertmanager/statefulset.go +++ b/pkg/alertmanager/statefulset.go @@ -194,7 +194,7 @@ func makeStatefulSetService(p *monitoringv1.Alertmanager, config Config) *v1.Ser }, }, Selector: map[string]string{ - "app": "alertmanager", + "app.kubernetes.io/name": "alertmanager", }, }, } @@ -312,9 +312,10 @@ func makeStatefulSetSpec(a *monitoringv1.Alertmanager, config Config) (*appsv1.S podAnnotations := map[string]string{} podLabels := map[string]string{} podSelectorLabels := map[string]string{ + // TODO(paulfantom): remove `app` label after 0.50 release "app": "alertmanager", "app.kubernetes.io/name": "alertmanager", - "app.kubernetes.io/version": amVersion, + "app.kubernetes.io/version": version.String(), "app.kubernetes.io/managed-by": "prometheus-operator", "app.kubernetes.io/instance": a.Name, "alertmanager": a.Name, @@ -335,6 +336,8 @@ func makeStatefulSetSpec(a *monitoringv1.Alertmanager, config Config) (*appsv1.S podLabels[k] = v } + podAnnotations["kubectl.kubernetes.io/default-container"] = "alertmanager" + var clusterPeerDomain string if config.ClusterDomain != "" { clusterPeerDomain = fmt.Sprintf("%s.%s.svc.%s.", governingServiceName, a.Namespace, config.ClusterDomain) diff --git a/pkg/alertmanager/statefulset_test.go b/pkg/alertmanager/statefulset_test.go index 65c37add19..38d56c71e3 100644 --- a/pkg/alertmanager/statefulset_test.go +++ b/pkg/alertmanager/statefulset_test.go @@ -52,13 +52,27 @@ func TestStatefulSetLabelingAndAnnotations(t *testing.T) { "kubectl.kubernetes.io/last-applied-configuration": "something", "kubectl.kubernetes.io/something": "something", } + // kubectl annotations must not be on the statefulset so kubectl does // not manage the generated object - expectedAnnotations := map[string]string{ + expectedStatefulSetAnnotations := map[string]string{ "prometheus-operator-input-hash": "", "testannotation": "testannotationvalue", } + expectedStatefulSetLabels := map[string]string{ + "testlabel": "testlabelvalue", + } + + expectedPodLabels := map[string]string{ + "alertmanager": "", + "app": "alertmanager", + "app.kubernetes.io/name": "alertmanager", + "app.kubernetes.io/version": strings.TrimPrefix(operator.DefaultAlertmanagerVersion, "v"), + "app.kubernetes.io/managed-by": "prometheus-operator", + "app.kubernetes.io/instance": "", + } + sset, err := makeStatefulSet(&monitoringv1.Alertmanager{ ObjectMeta: metav1.ObjectMeta{ Labels: labels, @@ -68,15 +82,20 @@ func TestStatefulSetLabelingAndAnnotations(t *testing.T) { require.NoError(t, err) - if !reflect.DeepEqual(labels, sset.Labels) { - t.Log(pretty.Compare(labels, sset.Labels)) + if !reflect.DeepEqual(expectedStatefulSetLabels, sset.Labels) { + t.Log(pretty.Compare(expectedStatefulSetLabels, sset.Labels)) t.Fatal("Labels are not properly being propagated to the StatefulSet") } - if !reflect.DeepEqual(expectedAnnotations, sset.Annotations) { - t.Log(pretty.Compare(expectedAnnotations, sset.Annotations)) + if !reflect.DeepEqual(expectedStatefulSetAnnotations, sset.Annotations) { + t.Log(pretty.Compare(expectedStatefulSetAnnotations, sset.Annotations)) t.Fatal("Annotations are not properly being propagated to the StatefulSet") } + + if !reflect.DeepEqual(expectedPodLabels, sset.Spec.Template.ObjectMeta.Labels) { + t.Log(pretty.Compare(expectedPodLabels, sset.Spec.Template.ObjectMeta.Labels)) + t.Fatal("Labels are not properly being propagated to the Pod") + } } func TestStatefulSetStoragePath(t *testing.T) { @@ -126,11 +145,11 @@ func TestPodLabelsAnnotations(t *testing.T) { }, }, defaultTestConfig, "") require.NoError(t, err) - if _, ok := sset.Spec.Template.ObjectMeta.Labels["testlabel"]; !ok { - t.Fatal("Pod labes are not properly propagated") + if val, ok := sset.Spec.Template.ObjectMeta.Labels["testlabel"]; !ok || val != "testvalue" { + t.Fatal("Pod labels are not properly propagated") } - if !reflect.DeepEqual(annotations, sset.Spec.Template.ObjectMeta.Annotations) { - t.Fatal("Pod annotaitons are not properly propagated") + if val, ok := sset.Spec.Template.ObjectMeta.Annotations["testannotation"]; !ok || val != "testvalue" { + t.Fatal("Pod annotations are not properly propagated") } } diff --git a/pkg/alertmanager/types.go b/pkg/alertmanager/types.go index 7fa4f6bc56..cfae984fa9 100644 --- a/pkg/alertmanager/types.go +++ b/pkg/alertmanager/types.go @@ -18,7 +18,6 @@ import ( "time" "github.com/prometheus/alertmanager/config" - commoncfg "github.com/prometheus/common/config" "github.com/prometheus/common/model" ) @@ -41,7 +40,7 @@ type globalConfig struct { // if it has not been updated. ResolveTimeout *model.Duration `yaml:"resolve_timeout,omitempty" json:"resolve_timeout,omitempty"` - HTTPConfig *commoncfg.HTTPClientConfig `yaml:"http_config,omitempty" json:"http_config,omitempty"` + HTTPConfig *httpClientConfig `yaml:"http_config,omitempty" json:"http_config,omitempty"` SMTPFrom string `yaml:"smtp_from,omitempty" json:"smtp_from,omitempty"` SMTPHello string `yaml:"smtp_hello,omitempty" json:"smtp_hello,omitempty"` @@ -177,11 +176,19 @@ type slackConfig struct { } type httpClientConfig struct { - BasicAuth *basicAuth `yaml:"basic_auth,omitempty"` - BearerToken string `yaml:"bearer_token,omitempty"` - BearerTokenFile string `yaml:"bearer_token_file,omitempty"` - ProxyURL string `yaml:"proxy_url,omitempty"` - TLSConfig commoncfg.TLSConfig `yaml:"tls_config,omitempty"` + BasicAuth *basicAuth `yaml:"basic_auth,omitempty"` + BearerToken string `yaml:"bearer_token,omitempty"` + BearerTokenFile string `yaml:"bearer_token_file,omitempty"` + ProxyURL string `yaml:"proxy_url,omitempty"` + TLSConfig tlsConfig `yaml:"tls_config,omitempty"` +} + +type tlsConfig struct { + CAFile string `yaml:"ca_file,omitempty"` + CertFile string `yaml:"cert_file,omitempty"` + KeyFile string `yaml:"key_file,omitempty"` + ServerName string `yaml:"server_name,omitempty"` + InsecureSkipVerify bool `yaml:"insecure_skip_verify"` } type basicAuth struct { @@ -232,20 +239,20 @@ type slackConfirmationField struct { } type emailConfig struct { - VSendResolved *bool `yaml:"send_resolved,omitempty" json:"send_resolved,omitempty"` - To string `yaml:"to,omitempty" json:"to,omitempty"` - From string `yaml:"from,omitempty" json:"from,omitempty"` - Hello string `yaml:"hello,omitempty" json:"hello,omitempty"` - Smarthost config.HostPort `yaml:"smarthost,omitempty" json:"smarthost,omitempty"` - AuthUsername string `yaml:"auth_username,omitempty" json:"auth_username,omitempty"` - AuthPassword string `yaml:"auth_password,omitempty" json:"auth_password,omitempty"` - AuthSecret string `yaml:"auth_secret,omitempty" json:"auth_secret,omitempty"` - AuthIdentity string `yaml:"auth_identity,omitempty" json:"auth_identity,omitempty"` - Headers map[string]string `yaml:"headers,omitempty" json:"headers,omitempty"` - HTML string `yaml:"html,omitempty" json:"html,omitempty"` - Text string `yaml:"text,omitempty" json:"text,omitempty"` - RequireTLS *bool `yaml:"require_tls,omitempty" json:"require_tls,omitempty"` - TLSConfig commoncfg.TLSConfig `yaml:"tls_config,omitempty" json:"tls_config,omitempty"` + VSendResolved *bool `yaml:"send_resolved,omitempty" json:"send_resolved,omitempty"` + To string `yaml:"to,omitempty" json:"to,omitempty"` + From string `yaml:"from,omitempty" json:"from,omitempty"` + Hello string `yaml:"hello,omitempty" json:"hello,omitempty"` + Smarthost config.HostPort `yaml:"smarthost,omitempty" json:"smarthost,omitempty"` + AuthUsername string `yaml:"auth_username,omitempty" json:"auth_username,omitempty"` + AuthPassword string `yaml:"auth_password,omitempty" json:"auth_password,omitempty"` + AuthSecret string `yaml:"auth_secret,omitempty" json:"auth_secret,omitempty"` + AuthIdentity string `yaml:"auth_identity,omitempty" json:"auth_identity,omitempty"` + Headers map[string]string `yaml:"headers,omitempty" json:"headers,omitempty"` + HTML string `yaml:"html,omitempty" json:"html,omitempty"` + Text string `yaml:"text,omitempty" json:"text,omitempty"` + RequireTLS *bool `yaml:"require_tls,omitempty" json:"require_tls,omitempty"` + TLSConfig tlsConfig `yaml:"tls_config,omitempty" json:"tls_config,omitempty"` } type pushoverConfig struct { diff --git a/pkg/k8sutil/k8sutil.go b/pkg/k8sutil/k8sutil.go index c9f1f41543..7f9137f568 100644 --- a/pkg/k8sutil/k8sutil.go +++ b/pkg/k8sutil/k8sutil.go @@ -28,6 +28,7 @@ import ( "github.com/hashicorp/go-version" "github.com/pkg/errors" v1 "k8s.io/api/core/v1" + apiequality "k8s.io/apimachinery/pkg/api/equality" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/validation" @@ -175,20 +176,34 @@ func UpdateStatefulSet(ctx context.Context, sstClient clientappsv1.StatefulSetIn return nil } -// UpdateSecret merges metadata of existing Secret with new one and updates it. -func UpdateSecret(ctx context.Context, secretClient clientv1.SecretInterface, secret *v1.Secret) error { - existingSecret, err := secretClient.Get(ctx, secret.Name, metav1.GetOptions{}) +// CreateOrUpdateSecret merges metadata of existing Secret with new one and updates it. +func CreateOrUpdateSecret(ctx context.Context, secretClient clientv1.SecretInterface, desired *v1.Secret) error { + existingSecret, err := secretClient.Get(ctx, desired.Name, metav1.GetOptions{}) if err != nil { - return errors.Wrap(err, "getting secret object failed") + if !apierrors.IsNotFound(err) { + return errors.Wrapf( + err, + "failed to check whether secret %q in namespace %q already exists", + desired.Name, + desired.Namespace, + ) + } + _, err = secretClient.Create(ctx, desired, metav1.CreateOptions{}) + return errors.Wrapf(err, "failed to create secret %q in namespace %q", desired.Name, desired.Namespace) } - - mergeMetadata(&secret.ObjectMeta, existingSecret.ObjectMeta) - - _, err = secretClient.Update(ctx, secret, metav1.UpdateOptions{}) - if err != nil { - return err + mutated := existingSecret.DeepCopyObject().(*v1.Secret) + mergeMetadata(&desired.ObjectMeta, mutated.ObjectMeta) + if apiequality.Semantic.DeepEqual(existingSecret, desired) { + return nil + } + if _, err = secretClient.Update(ctx, desired, metav1.UpdateOptions{}); err != nil { + return errors.Wrapf( + err, + "failed to update secret %q in namespace %q", + desired.Name, + desired.Namespace, + ) } - return nil } diff --git a/pkg/k8sutil/k8sutil_test.go b/pkg/k8sutil/k8sutil_test.go index 7484baa6c8..245e57dbb2 100644 --- a/pkg/k8sutil/k8sutil_test.go +++ b/pkg/k8sutil/k8sutil_test.go @@ -261,7 +261,7 @@ func TestMergeMetadata(t *testing.T) { } }) - t.Run("UpdateSecret", func(t *testing.T) { + t.Run("CreateOrUpdateSecret", func(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { secret := &corev1.Secret{ @@ -287,7 +287,7 @@ func TestMergeMetadata(t *testing.T) { t.Fatal(err) } - err = UpdateSecret(context.TODO(), sClient, secret) + err = CreateOrUpdateSecret(context.TODO(), sClient, secret) if err != nil { t.Fatal(err) } diff --git a/pkg/k8sutil/labels.go b/pkg/k8sutil/labels.go new file mode 100644 index 0000000000..b177cb6dbc --- /dev/null +++ b/pkg/k8sutil/labels.go @@ -0,0 +1,44 @@ +// Copyright 2021 The prometheus-operator Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package k8sutil + +import ( + "reflect" + + "github.com/pkg/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" +) + +// LabelSelectionHasChanged returns true if the selector doesn't yield the same results +// for the old and current labels. +func LabelSelectionHasChanged(old, current map[string]string, selector *metav1.LabelSelector) (bool, error) { + // If the labels haven't changed, the selector won't return different results. + if reflect.DeepEqual(old, current) { + return false, nil + } + + sel, err := metav1.LabelSelectorAsSelector(selector) + if err != nil { + return false, errors.Wrapf(err, "failed to convert selector %q", selector.String()) + } + + // The selector doesn't restrict the selection thus old and current labels always match. + if sel.Empty() { + return false, nil + } + + return sel.Matches(labels.Set(old)) != sel.Matches(labels.Set(current)), nil +} diff --git a/pkg/k8sutil/labels_test.go b/pkg/k8sutil/labels_test.go new file mode 100644 index 0000000000..25b35d315f --- /dev/null +++ b/pkg/k8sutil/labels_test.go @@ -0,0 +1,130 @@ +// Copyright 2021 The prometheus-operator Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package k8sutil + +import ( + "testing" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func TestLabelSelectionHasChanged(t *testing.T) { + for _, tc := range []struct { + name string + + old map[string]string + current map[string]string + selector *metav1.LabelSelector + + expected bool + expectedErr bool + }{ + { + name: "no label change", + old: map[string]string{ + "app": "foo", + }, + current: map[string]string{ + "app": "foo", + }, + selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"app": "foo"}, + }, + }, + { + name: "old matches and current doesn't match", + old: map[string]string{ + "app": "foo", + }, + current: map[string]string{ + "app": "bar", + }, + selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"app": "foo"}, + }, + expected: true, + }, + { + name: "old doesn't match and current matches", + old: map[string]string{ + "app": "bar", + }, + current: map[string]string{ + "app": "foo", + }, + selector: &metav1.LabelSelector{ + MatchLabels: map[string]string{"app": "foo"}, + }, + expected: true, + }, + { + name: "match-all label selector", + old: map[string]string{ + "app": "foo", + }, + current: map[string]string{ + "app": "bar", + }, + selector: &metav1.LabelSelector{}, + }, + { + name: "match-nothing label selector", + old: map[string]string{ + "app": "foo", + }, + current: map[string]string{ + "app": "bar", + }, + selector: nil, + }, + { + name: "invalid label selector", + old: map[string]string{ + "app": "foo", + }, + current: map[string]string{ + "app": "bar", + }, + selector: &metav1.LabelSelector{ + MatchExpressions: []metav1.LabelSelectorRequirement{ + { + Key: "foo", + Operator: metav1.LabelSelectorOperator("invalid"), + }, + }, + }, + expectedErr: true, + }, + } { + t.Run(tc.name, func(t *testing.T) { + changed, err := LabelSelectionHasChanged(tc.old, tc.current, tc.selector) + + if tc.expectedErr { + if err == nil { + t.Error("expected error, got nil") + } + return + } + + if err != nil { + t.Errorf("expected no error, got %v", err) + } + + if tc.expected != changed { + t.Errorf("expected %v, got %v", tc.expected, changed) + } + }) + } +} diff --git a/pkg/prometheus/operator.go b/pkg/prometheus/operator.go index 9823b3de88..4671a48ae9 100644 --- a/pkg/prometheus/operator.go +++ b/pkg/prometheus/operator.go @@ -87,7 +87,7 @@ type Operator struct { kubeletSyncEnabled bool config operator.Config - configGenerator *configGenerator + configGenerator *ConfigGenerator } // New creates a new controller. @@ -140,7 +140,7 @@ func New(ctx context.Context, conf operator.Config, logger log.Logger, r prometh kubeletObjectNamespace: kubeletObjectNamespace, kubeletSyncEnabled: kubeletSyncEnabled, config: conf, - configGenerator: newConfigGenerator(logger), + configGenerator: NewConfigGenerator(logger), metrics: operator.NewMetrics("prometheus", r), nodeAddressLookupErrors: prometheus.NewCounter(prometheus.CounterOpts{ Name: "prometheus_operator_node_address_lookup_errors_total", @@ -237,7 +237,7 @@ func New(ctx context.Context, conf operator.Config, logger log.Logger, r prometh c.cmapInfs, err = informers.NewInformersForResource( informers.NewKubeInformerFactories( - c.config.Namespaces.AllowList, + c.config.Namespaces.PrometheusAllowList, c.config.Namespaces.DenyList, c.kclient, resyncPeriod, @@ -400,6 +400,15 @@ func (c *Operator) addHandlers() { DeleteFunc: c.handleStatefulSetDelete, UpdateFunc: c.handleStatefulSetUpdate, }) + + // The controller needs to watch the namespaces in which the service/pod + // monitors and rules live because a label change on a namespace may + // trigger a configuration change. + // It doesn't need to watch on addition/deletion though because it's + // already covered by the event handlers on service/pod monitors and rules. + c.nsMonInf.AddEventHandler(cache.ResourceEventHandlerFuncs{ + UpdateFunc: c.handleMonitorNamespaceUpdate, + }) } // Run the controller. @@ -1139,6 +1148,58 @@ func (c *Operator) handleStatefulSetUpdate(oldo, curo interface{}) { } } +func (c *Operator) handleMonitorNamespaceUpdate(oldo, curo interface{}) { + old := oldo.(*v1.Namespace) + cur := curo.(*v1.Namespace) + + level.Debug(c.logger).Log("msg", "update handler", "namespace", cur.GetName(), "old", old.ResourceVersion, "cur", cur.ResourceVersion) + + // Periodic resync may resend the Namespace without changes + // in-between. + if old.ResourceVersion == cur.ResourceVersion { + return + } + + level.Debug(c.logger).Log("msg", "Monitor namespace updated", "namespace", cur.GetName()) + c.metrics.TriggerByCounter("Namespace", "update").Inc() + + // Check for Prometheus instances selecting ServiceMonitors, PodMonitors, + // Probes and PrometheusRules in the namespace. + err := c.promInfs.ListAll(labels.Everything(), func(obj interface{}) { + p := obj.(*monitoringv1.Prometheus) + + for name, selector := range map[string]*metav1.LabelSelector{ + "PodMonitors": p.Spec.PodMonitorNamespaceSelector, + "Probes": p.Spec.ProbeNamespaceSelector, + "PrometheusRules": p.Spec.RuleNamespaceSelector, + "ServiceMonitors": p.Spec.ServiceMonitorNamespaceSelector, + } { + + sync, err := k8sutil.LabelSelectionHasChanged(old.Labels, cur.Labels, selector) + if err != nil { + level.Error(c.logger).Log( + "err", err, + "name", p.Name, + "namespace", p.Namespace, + "subresource", name, + ) + return + } + + if sync { + c.enqueue(p) + return + } + } + }) + if err != nil { + level.Error(c.logger).Log( + "msg", "listing all Prometheus instances from cache failed", + "err", err, + ) + } +} + func (c *Operator) sync(ctx context.Context, key string) error { pobj, err := c.promInfs.Get(key) @@ -1324,8 +1385,8 @@ func createSSetInputHash(p monitoringv1.Prometheus, c operator.Config, ruleConfi func ListOptions(name string) metav1.ListOptions { return metav1.ListOptions{ LabelSelector: fields.SelectorFromSet(fields.Set(map[string]string{ - "app": "prometheus", - "prometheus": name, + "app.kubernetes.io/name": "prometheus", + "prometheus": name, })).String(), } } @@ -1501,7 +1562,7 @@ func (c *Operator) createOrUpdateConfigurationSecret(ctx context.Context, p *mon } // Update secret based on the most recent configuration. - conf, err := c.configGenerator.generateConfig( + conf, err := c.configGenerator.GenerateConfig( p, smons, pmons, @@ -1529,29 +1590,8 @@ func (c *Operator) createOrUpdateConfigurationSecret(ctx context.Context, p *mon } s.Data[configFilename] = buf.Bytes() - curSecret, err := sClient.Get(ctx, s.Name, metav1.GetOptions{}) - if apierrors.IsNotFound(err) { - level.Debug(c.logger).Log("msg", "creating configuration") - _, err = sClient.Create(ctx, s, metav1.CreateOptions{}) - return err - } - - var ( - generatedConf = s.Data[configFilename] - curConfig, curConfigFound = curSecret.Data[configFilename] - ) - if curConfigFound { - if bytes.Equal(curConfig, generatedConf) { - level.Debug(c.logger).Log("msg", "updating Prometheus configuration secret skipped, no configuration change") - return nil - } - level.Debug(c.logger).Log("msg", "current Prometheus configuration has changed") - } else { - level.Debug(c.logger).Log("msg", "no current Prometheus configuration secret found", "currentConfigFound", curConfigFound) - } - level.Debug(c.logger).Log("msg", "updating Prometheus configuration secret") - return k8sutil.UpdateSecret(ctx, sClient, s) + return k8sutil.CreateOrUpdateSecret(ctx, sClient, s) } func (c *Operator) createOrUpdateTLSAssetSecret(ctx context.Context, p *monitoringv1.Prometheus, store *assets.Store) error { @@ -1580,26 +1620,9 @@ func (c *Operator) createOrUpdateTLSAssetSecret(ctx context.Context, p *monitori tlsAssetsSecret.Data[key.String()] = []byte(asset) } - _, err := sClient.Get(ctx, tlsAssetsSecret.Name, metav1.GetOptions{}) - if err != nil { - if !apierrors.IsNotFound(err) { - return errors.Wrapf( - err, - "failed to check whether tls assets secret already exists for Prometheus %v in namespace %v", - p.Name, - p.Namespace, - ) - } - _, err = sClient.Create(ctx, tlsAssetsSecret, metav1.CreateOptions{}) - level.Debug(c.logger).Log("msg", "created tlsAssetsSecret", "secretname", tlsAssetsSecret.Name) - - } else { - err = k8sutil.UpdateSecret(ctx, sClient, tlsAssetsSecret) - level.Debug(c.logger).Log("msg", "updated tlsAssetsSecret", "secretname", tlsAssetsSecret.Name) - } - + err := k8sutil.CreateOrUpdateSecret(ctx, sClient, tlsAssetsSecret) if err != nil { - return errors.Wrapf(err, "failed to create TLS assets secret for Prometheus %v in namespace %v", p.Name, p.Namespace) + return errors.Wrap(err, "failed to create TLS assets secret for Prometheus") } return nil diff --git a/pkg/prometheus/operator_test.go b/pkg/prometheus/operator_test.go index 1646f1fa7e..20fab409c2 100644 --- a/pkg/prometheus/operator_test.go +++ b/pkg/prometheus/operator_test.go @@ -29,8 +29,8 @@ import ( func TestListOptions(t *testing.T) { for i := 0; i < 1000; i++ { o := ListOptions("test") - if o.LabelSelector != "app=prometheus,prometheus=test" && o.LabelSelector != "prometheus=test,app=prometheus" { - t.Fatalf("LabelSelector not computed correctly\n\nExpected: \"app=prometheus,prometheus=test\"\n\nGot: %#+v", o.LabelSelector) + if o.LabelSelector != "app.kubernetes.io/name=prometheus,prometheus=test" && o.LabelSelector != "prometheus=test,app.kubernetes.io/name=prometheus" { + t.Fatalf("LabelSelector not computed correctly\n\nExpected: \"app.kubernetes.io/name=prometheus,prometheus=test\"\n\nGot: %#+v", o.LabelSelector) } } } diff --git a/pkg/prometheus/promcfg.go b/pkg/prometheus/promcfg.go index 289241465e..41ca1f4f40 100644 --- a/pkg/prometheus/promcfg.go +++ b/pkg/prometheus/promcfg.go @@ -43,12 +43,14 @@ var ( invalidLabelCharRE = regexp.MustCompile(`[^a-zA-Z0-9_]`) ) -type configGenerator struct { +// ConfigGenerator is used to create Prometheus configurations from operator resources. +type ConfigGenerator struct { logger log.Logger } -func newConfigGenerator(logger log.Logger) *configGenerator { - cg := &configGenerator{ +// NewConfigGenerator creates a ConfigGenerator instance using the provided Logger. +func NewConfigGenerator(logger log.Logger) *ConfigGenerator { + cg := &ConfigGenerator{ logger: logger, } return cg @@ -153,7 +155,8 @@ func buildExternalLabels(p *v1.Prometheus) yaml.MapSlice { return stringMapToMapSlice(m) } -func (cg *configGenerator) generateConfig( +// GenerateConfig creates a serialized YAML representation of a Prometheus configuration using the provided resources. +func (cg *ConfigGenerator) GenerateConfig( p *v1.Prometheus, sMons map[string]*v1.ServiceMonitor, pMons map[string]*v1.PodMonitor, @@ -428,7 +431,7 @@ func initRelabelings() []yaml.MapSlice { } } -func (cg *configGenerator) generatePodMonitorConfig( +func (cg *ConfigGenerator) generatePodMonitorConfig( version semver.Version, m *v1.PodMonitor, ep v1.PodMetricsEndpoint, @@ -669,7 +672,7 @@ func (cg *configGenerator) generatePodMonitorConfig( return cfg } -func (cg *configGenerator) generateProbeConfig( +func (cg *ConfigGenerator) generateProbeConfig( version semver.Version, m *v1.Probe, apiserverConfig *v1.APIServerConfig, @@ -892,7 +895,7 @@ func (cg *configGenerator) generateProbeConfig( return cfg } -func (cg *configGenerator) generateServiceMonitorConfig( +func (cg *ConfigGenerator) generateServiceMonitorConfig( version semver.Version, m *v1.ServiceMonitor, ep v1.Endpoint, @@ -1241,7 +1244,7 @@ func getNamespacesFromNamespaceSelector(nsel *v1.NamespaceSelector, namespace st return nsel.MatchNames } -func (cg *configGenerator) generateK8SSDConfig(namespaces []string, apiserverConfig *v1.APIServerConfig, basicAuthSecrets map[string]assets.BasicAuthCredentials, role string) yaml.MapItem { +func (cg *ConfigGenerator) generateK8SSDConfig(namespaces []string, apiserverConfig *v1.APIServerConfig, basicAuthSecrets map[string]assets.BasicAuthCredentials, role string) yaml.MapItem { k8sSDConfig := yaml.MapSlice{ { Key: "role", @@ -1298,7 +1301,7 @@ func (cg *configGenerator) generateK8SSDConfig(namespaces []string, apiserverCon } } -func (cg *configGenerator) generateAlertmanagerConfig(version semver.Version, am v1.AlertmanagerEndpoints, apiserverConfig *v1.APIServerConfig, basicAuthSecrets map[string]assets.BasicAuthCredentials) yaml.MapSlice { +func (cg *ConfigGenerator) generateAlertmanagerConfig(version semver.Version, am v1.AlertmanagerEndpoints, apiserverConfig *v1.APIServerConfig, basicAuthSecrets map[string]assets.BasicAuthCredentials) yaml.MapSlice { if am.Scheme == "" { am.Scheme = "http" } @@ -1359,7 +1362,7 @@ func (cg *configGenerator) generateAlertmanagerConfig(version semver.Version, am return cfg } -func (cg *configGenerator) generateRemoteReadConfig(version semver.Version, p *v1.Prometheus, basicAuthSecrets map[string]assets.BasicAuthCredentials) yaml.MapItem { +func (cg *ConfigGenerator) generateRemoteReadConfig(version semver.Version, p *v1.Prometheus, basicAuthSecrets map[string]assets.BasicAuthCredentials) yaml.MapItem { cfgs := []yaml.MapSlice{} @@ -1421,7 +1424,7 @@ func (cg *configGenerator) generateRemoteReadConfig(version semver.Version, p *v } } -func (cg *configGenerator) generateRemoteWriteConfig(version semver.Version, p *v1.Prometheus, basicAuthSecrets map[string]assets.BasicAuthCredentials) yaml.MapItem { +func (cg *ConfigGenerator) generateRemoteWriteConfig(version semver.Version, p *v1.Prometheus, basicAuthSecrets map[string]assets.BasicAuthCredentials) yaml.MapItem { cfgs := []yaml.MapSlice{} diff --git a/pkg/prometheus/promcfg_test.go b/pkg/prometheus/promcfg_test.go index ff69ed095c..c80a567e80 100644 --- a/pkg/prometheus/promcfg_test.go +++ b/pkg/prometheus/promcfg_test.go @@ -190,8 +190,8 @@ alerting: } for _, tc := range testcases { - cg := &configGenerator{} - cfg, err := cg.generateConfig( + cg := &ConfigGenerator{} + cfg, err := cg.GenerateConfig( &monitoringv1.Prometheus{ ObjectMeta: metav1.ObjectMeta{}, Spec: monitoringv1.PrometheusSpec{ @@ -326,7 +326,7 @@ func TestNamespaceSetCorrectly(t *testing.T) { `, }, } - cg := &configGenerator{} + cg := &ConfigGenerator{} for _, tc := range testcases { selectedNamespaces := getNamespacesFromNamespaceSelector(&tc.ServiceMonitor.Spec.NamespaceSelector, tc.ServiceMonitor.Namespace, tc.IgnoreNamespaceSelectors) @@ -357,7 +357,7 @@ func TestNamespaceSetCorrectlyForPodMonitor(t *testing.T) { }, } - cg := &configGenerator{} + cg := &ConfigGenerator{} selectedNamespaces := getNamespacesFromNamespaceSelector(&pm.Spec.NamespaceSelector, pm.Namespace, false) c := cg.generateK8SSDConfig(selectedNamespaces, nil, nil, kubernetesSDRolePod) s, err := yaml.Marshal(yaml.MapSlice{c}) @@ -379,8 +379,8 @@ func TestNamespaceSetCorrectlyForPodMonitor(t *testing.T) { } func TestProbeStaticTargetsConfigGeneration(t *testing.T) { - cg := &configGenerator{} - cfg, err := cg.generateConfig( + cg := &ConfigGenerator{} + cfg, err := cg.GenerateConfig( &monitoringv1.Prometheus{ ObjectMeta: metav1.ObjectMeta{ Name: "test", @@ -496,8 +496,8 @@ alerting: } func TestProbeStaticTargetsConfigGenerationWithLabelEnforce(t *testing.T) { - cg := &configGenerator{} - cfg, err := cg.generateConfig( + cg := &ConfigGenerator{} + cfg, err := cg.GenerateConfig( &monitoringv1.Prometheus{ ObjectMeta: metav1.ObjectMeta{ Name: "test", @@ -607,8 +607,8 @@ alerting: } func TestProbeStaticTargetsConfigGenerationWithJobName(t *testing.T) { - cg := &configGenerator{} - cfg, err := cg.generateConfig( + cg := &ConfigGenerator{} + cfg, err := cg.GenerateConfig( &monitoringv1.Prometheus{ ObjectMeta: metav1.ObjectMeta{ Name: "test", @@ -713,8 +713,8 @@ alerting: } func TestProbeIngressSDConfigGeneration(t *testing.T) { - cg := &configGenerator{} - cfg, err := cg.generateConfig( + cg := &ConfigGenerator{} + cfg, err := cg.GenerateConfig( &monitoringv1.Prometheus{ ObjectMeta: metav1.ObjectMeta{ Name: "test", @@ -842,8 +842,8 @@ alerting: } func TestProbeIngressSDConfigGenerationWithLabelEnforce(t *testing.T) { - cg := &configGenerator{} - cfg, err := cg.generateConfig( + cg := &ConfigGenerator{} + cfg, err := cg.GenerateConfig( &monitoringv1.Prometheus{ ObjectMeta: metav1.ObjectMeta{ Name: "test", @@ -989,7 +989,7 @@ func TestK8SSDConfigGeneration(t *testing.T) { }, } - cg := &configGenerator{} + cg := &ConfigGenerator{} testcases := []struct { apiserverConfig *monitoringv1.APIServerConfig @@ -1055,8 +1055,8 @@ func TestK8SSDConfigGeneration(t *testing.T) { } func TestAlertmanagerBearerToken(t *testing.T) { - cg := &configGenerator{} - cfg, err := cg.generateConfig( + cg := &ConfigGenerator{} + cfg, err := cg.GenerateConfig( &monitoringv1.Prometheus{ ObjectMeta: metav1.ObjectMeta{ Name: "test", @@ -1133,8 +1133,8 @@ alerting: } func TestAlertmanagerAPIVersion(t *testing.T) { - cg := &configGenerator{} - cfg, err := cg.generateConfig( + cg := &ConfigGenerator{} + cfg, err := cg.GenerateConfig( &monitoringv1.Prometheus{ ObjectMeta: metav1.ObjectMeta{ Name: "test", @@ -1212,8 +1212,8 @@ alerting: } func TestAlertmanagerTimeoutConfig(t *testing.T) { - cg := &configGenerator{} - cfg, err := cg.generateConfig( + cg := &ConfigGenerator{} + cfg, err := cg.GenerateConfig( &monitoringv1.Prometheus{ ObjectMeta: metav1.ObjectMeta{ Name: "test", @@ -1293,8 +1293,8 @@ alerting: } func TestAdditionalAlertRelabelConfigs(t *testing.T) { - cg := &configGenerator{} - cfg, err := cg.generateConfig( + cg := &ConfigGenerator{} + cfg, err := cg.GenerateConfig( &monitoringv1.Prometheus{ ObjectMeta: metav1.ObjectMeta{ Name: "test", @@ -1374,8 +1374,8 @@ alerting: } func TestNoEnforcedNamespaceLabelServiceMonitor(t *testing.T) { - cg := &configGenerator{} - cfg, err := cg.generateConfig( + cg := &ConfigGenerator{} + cfg, err := cg.GenerateConfig( &monitoringv1.Prometheus{ ObjectMeta: metav1.ObjectMeta{ Name: "test", @@ -1536,8 +1536,8 @@ alerting: } } func TestEnforcedNamespaceLabelPodMonitor(t *testing.T) { - cg := &configGenerator{} - cfg, err := cg.generateConfig( + cg := &ConfigGenerator{} + cfg, err := cg.GenerateConfig( &monitoringv1.Prometheus{ ObjectMeta: metav1.ObjectMeta{ Name: "test", @@ -1680,8 +1680,8 @@ alerting: } func TestEnforcedNamespaceLabelServiceMonitor(t *testing.T) { - cg := &configGenerator{} - cfg, err := cg.generateConfig( + cg := &ConfigGenerator{} + cfg, err := cg.GenerateConfig( &monitoringv1.Prometheus{ ObjectMeta: metav1.ObjectMeta{ Name: "test", @@ -1833,8 +1833,8 @@ alerting: } func TestAdditionalAlertmanagers(t *testing.T) { - cg := &configGenerator{} - cfg, err := cg.generateConfig( + cg := &ConfigGenerator{} + cfg, err := cg.GenerateConfig( &monitoringv1.Prometheus{ ObjectMeta: metav1.ObjectMeta{ Name: "test", @@ -1912,8 +1912,8 @@ alerting: } func TestSettingHonorTimestampsInServiceMonitor(t *testing.T) { - cg := &configGenerator{} - cfg, err := cg.generateConfig( + cg := &ConfigGenerator{} + cfg, err := cg.GenerateConfig( &monitoringv1.Prometheus{ ObjectMeta: metav1.ObjectMeta{ Name: "test", @@ -2054,8 +2054,8 @@ alerting: } func TestSettingHonorTimestampsInPodMonitor(t *testing.T) { - cg := &configGenerator{} - cfg, err := cg.generateConfig( + cg := &ConfigGenerator{} + cfg, err := cg.GenerateConfig( &monitoringv1.Prometheus{ ObjectMeta: metav1.ObjectMeta{ Name: "test", @@ -2177,8 +2177,8 @@ alerting: } func TestHonorTimestampsOverriding(t *testing.T) { - cg := &configGenerator{} - cfg, err := cg.generateConfig( + cg := &ConfigGenerator{} + cfg, err := cg.GenerateConfig( &monitoringv1.Prometheus{ ObjectMeta: metav1.ObjectMeta{ Name: "test", @@ -2320,8 +2320,8 @@ alerting: } func TestSettingHonorLabels(t *testing.T) { - cg := &configGenerator{} - cfg, err := cg.generateConfig( + cg := &ConfigGenerator{} + cfg, err := cg.GenerateConfig( &monitoringv1.Prometheus{ ObjectMeta: metav1.ObjectMeta{ Name: "test", @@ -2460,8 +2460,8 @@ alerting: } func TestHonorLabelsOverriding(t *testing.T) { - cg := &configGenerator{} - cfg, err := cg.generateConfig( + cg := &ConfigGenerator{} + cfg, err := cg.GenerateConfig( &monitoringv1.Prometheus{ ObjectMeta: metav1.ObjectMeta{ Name: "test", @@ -2601,8 +2601,8 @@ alerting: } func TestTargetLabels(t *testing.T) { - cg := &configGenerator{} - cfg, err := cg.generateConfig( + cg := &ConfigGenerator{} + cfg, err := cg.GenerateConfig( &monitoringv1.Prometheus{ ObjectMeta: metav1.ObjectMeta{ Name: "test", @@ -2741,8 +2741,8 @@ alerting: } func TestPodTargetLabels(t *testing.T) { - cg := &configGenerator{} - cfg, err := cg.generateConfig( + cg := &ConfigGenerator{} + cfg, err := cg.GenerateConfig( &monitoringv1.Prometheus{ ObjectMeta: metav1.ObjectMeta{ Name: "test", @@ -2880,8 +2880,8 @@ alerting: } func TestPodTargetLabelsFromPodMonitor(t *testing.T) { - cg := &configGenerator{} - cfg, err := cg.generateConfig( + cg := &ConfigGenerator{} + cfg, err := cg.GenerateConfig( &monitoringv1.Prometheus{ ObjectMeta: metav1.ObjectMeta{ Name: "test", @@ -3000,8 +3000,8 @@ alerting: } func TestEmptyEndointPorts(t *testing.T) { - cg := &configGenerator{} - cfg, err := cg.generateConfig( + cg := &ConfigGenerator{} + cfg, err := cg.GenerateConfig( &monitoringv1.Prometheus{ ObjectMeta: metav1.ObjectMeta{ Name: "test", @@ -3120,9 +3120,9 @@ alerting: } func generateTestConfig(version string) ([]byte, error) { - cg := &configGenerator{} + cg := &ConfigGenerator{} replicas := int32(1) - return cg.generateConfig( + return cg.GenerateConfig( &monitoringv1.Prometheus{ ObjectMeta: metav1.ObjectMeta{ Name: "test", @@ -3754,7 +3754,7 @@ alerting: }, } { t.Run(fmt.Sprintf("enforcedlimit(%d) limit(%d)", tc.enforcedLimit, tc.limit), func(t *testing.T) { - cg := &configGenerator{} + cg := &ConfigGenerator{} prometheus := monitoringv1.Prometheus{ ObjectMeta: metav1.ObjectMeta{ @@ -3796,7 +3796,7 @@ alerting: serviceMonitor.Spec.SampleLimit = uint64(tc.limit) } - cfg, err := cg.generateConfig( + cfg, err := cg.GenerateConfig( &prometheus, map[string]*monitoringv1.ServiceMonitor{ "testservicemonitor1": &serviceMonitor, @@ -4025,7 +4025,7 @@ alerting: }, } { t.Run(fmt.Sprintf("%s enforcedlimit(%d) limit(%d)", tc.version, tc.enforcedLimit, tc.limit), func(t *testing.T) { - cg := &configGenerator{} + cg := &ConfigGenerator{} prometheus := monitoringv1.Prometheus{ ObjectMeta: metav1.ObjectMeta{ @@ -4067,7 +4067,7 @@ alerting: serviceMonitor.Spec.TargetLimit = uint64(tc.limit) } - cfg, err := cg.generateConfig( + cfg, err := cg.GenerateConfig( &prometheus, map[string]*monitoringv1.ServiceMonitor{ "testservicemonitor1": &serviceMonitor, @@ -4198,7 +4198,7 @@ remote_write: }, } { t.Run(fmt.Sprintf("version=%s", tc.version), func(t *testing.T) { - cg := &configGenerator{} + cg := &ConfigGenerator{} prometheus := monitoringv1.Prometheus{ ObjectMeta: metav1.ObjectMeta{ @@ -4216,7 +4216,7 @@ remote_write: }, } - cfg, err := cg.generateConfig( + cfg, err := cg.GenerateConfig( &prometheus, nil, nil, diff --git a/pkg/prometheus/statefulset.go b/pkg/prometheus/statefulset.go index fd97018892..d3262f6a3f 100644 --- a/pkg/prometheus/statefulset.go +++ b/pkg/prometheus/statefulset.go @@ -293,7 +293,7 @@ func makeStatefulSetService(p *monitoringv1.Prometheus, config operator.Config) }, }, Selector: map[string]string{ - "app": "prometheus", + "app.kubernetes.io/name": "prometheus", }, }, } @@ -596,6 +596,7 @@ func makeStatefulSetSpec(p monitoringv1.Prometheus, c *operator.Config, shard in podAnnotations := map[string]string{} podLabels := map[string]string{} podSelectorLabels := map[string]string{ + // TODO(fpetkovski): remove `app` label after 0.50 release "app": "prometheus", "app.kubernetes.io/name": "prometheus", "app.kubernetes.io/version": version.String(), @@ -622,6 +623,8 @@ func makeStatefulSetSpec(p monitoringv1.Prometheus, c *operator.Config, shard in podLabels[k] = v } + podAnnotations["kubectl.kubernetes.io/default-container"] = "prometheus" + finalSelectorLabels := c.Labels.Merge(podSelectorLabels) finalLabels := c.Labels.Merge(podLabels) diff --git a/pkg/prometheus/statefulset_test.go b/pkg/prometheus/statefulset_test.go index eb1863036c..6d26371310 100644 --- a/pkg/prometheus/statefulset_test.go +++ b/pkg/prometheus/statefulset_test.go @@ -120,11 +120,11 @@ func TestPodLabelsAnnotations(t *testing.T) { }, }, defaultTestConfig, nil, "", 0) require.NoError(t, err) - if _, ok := sset.Spec.Template.ObjectMeta.Labels["testlabel"]; !ok { - t.Fatal("Pod labes are not properly propagated") + if val, ok := sset.Spec.Template.ObjectMeta.Labels["testlabel"]; !ok || val != "testvalue" { + t.Fatal("Pod labels are not properly propagated") } - if !reflect.DeepEqual(annotations, sset.Spec.Template.ObjectMeta.Annotations) { - t.Fatal("Pod annotaitons are not properly propagated") + if val, ok := sset.Spec.Template.ObjectMeta.Annotations["testannotation"]; !ok || val != "testvalue" { + t.Fatal("Pod annotations are not properly propagated") } } func TestPodLabelsShouldNotBeSelectorLabels(t *testing.T) { diff --git a/pkg/thanos/operator.go b/pkg/thanos/operator.go index 1f9ed57ed7..11f8af40c1 100644 --- a/pkg/thanos/operator.go +++ b/pkg/thanos/operator.go @@ -290,6 +290,15 @@ func (o *Operator) addHandlers() { DeleteFunc: o.handleStatefulSetDelete, UpdateFunc: o.handleStatefulSetUpdate, }) + + // The controller needs to watch the namespaces in which the rules live + // because a label change on a namespace may trigger a configuration + // change. + // It doesn't need to watch on addition/deletion though because it's + // already covered by the event handlers on rules. + o.nsRuleInf.AddEventHandler(cache.ResourceEventHandlerFuncs{ + UpdateFunc: o.handleNamespaceUpdate, + }) } // Run the controller. @@ -570,12 +579,52 @@ func (o *Operator) processNextWorkItem(ctx context.Context) bool { } o.metrics.ReconcileErrorsCounter().Inc() - utilruntime.HandleError(errors.Wrap(err, fmt.Sprintf("Sync %q failed", key))) + utilruntime.HandleError(errors.Wrapf(err, "Sync %q failed", key)) o.queue.AddRateLimited(key) return true } +func (o *Operator) handleNamespaceUpdate(oldo, curo interface{}) { + old := oldo.(*v1.Namespace) + cur := curo.(*v1.Namespace) + + level.Debug(o.logger).Log("msg", "update handler", "namespace", cur.GetName(), "old", old.ResourceVersion, "cur", cur.ResourceVersion) + + // Periodic resync may resend the Namespace without changes in-between. + if old.ResourceVersion == cur.ResourceVersion { + return + } + + level.Debug(o.logger).Log("msg", "Namespace updated", "namespace", cur.GetName()) + o.metrics.TriggerByCounter("Namespace", "update").Inc() + + // Check for ThanosRuler instances selecting PrometheusRules in the namespace. + err := o.thanosRulerInfs.ListAll(labels.Everything(), func(obj interface{}) { + tr := obj.(*monitoringv1.ThanosRuler) + + sync, err := k8sutil.LabelSelectionHasChanged(old.Labels, cur.Labels, tr.Spec.RuleNamespaceSelector) + if err != nil { + level.Error(o.logger).Log( + "err", err, + "name", tr.Name, + "namespace", tr.Namespace, + ) + return + } + + if sync { + o.enqueue(tr) + } + }) + if err != nil { + level.Error(o.logger).Log( + "msg", "listing all ThanosRuler instances from cache failed", + "err", err, + ) + } +} + func (o *Operator) sync(ctx context.Context, key string) error { trobj, err := o.thanosRulerInfs.Get(key) if apierrors.IsNotFound(err) { @@ -711,8 +760,8 @@ func createSSetInputHash(tr monitoringv1.ThanosRuler, c Config, ruleConfigMapNam func ListOptions(name string) metav1.ListOptions { return metav1.ListOptions{ LabelSelector: fields.SelectorFromSet(fields.Set(map[string]string{ - "app": thanosRulerLabel, - thanosRulerLabel: name, + "app.kubernetes.io/name": thanosRulerLabel, + thanosRulerLabel: name, })).String(), } } @@ -793,7 +842,8 @@ func (o *Operator) enqueueForNamespace(store cache.Store, nsName string) { } if !exists { level.Error(o.logger).Log( - "msg", fmt.Sprintf("get namespace to enqueue ThanosRuler instances failed: namespace %q does not exist", nsName), + "msg", "get namespace to enqueue ThanosRuler instances failed: namespace does not exist", + "namespace", nsName, ) return } @@ -812,8 +862,10 @@ func (o *Operator) enqueueForNamespace(store cache.Store, nsName string) { ruleNSSelector, err := metav1.LabelSelectorAsSelector(tr.Spec.RuleNamespaceSelector) if err != nil { level.Error(o.logger).Log( - "msg", fmt.Sprintf("failed to convert RuleNamespaceSelector of %q to selector", tr.Name), - "err", err, + "err", errors.Wrap(err, "failed to convert RuleNamespaceSelector"), + "name", tr.Name, + "namespace", tr.Namespace, + "selector", tr.Spec.RuleNamespaceSelector, ) return } diff --git a/pkg/thanos/operator_test.go b/pkg/thanos/operator_test.go index 4bb773e52d..fd4e3aca2f 100644 --- a/pkg/thanos/operator_test.go +++ b/pkg/thanos/operator_test.go @@ -21,8 +21,8 @@ import ( func TestListOptions(t *testing.T) { for i := 0; i < 1000; i++ { o := ListOptions("test") - if o.LabelSelector != "app=thanos-ruler,thanos-ruler=test" && o.LabelSelector != "thanos-ruler=test,app=thanos-ruler" { - t.Fatalf("LabelSelector not computed correctly\n\nExpected: \"app=thanos-ruler,thanos-ruler=test\"\n\nGot: %#+v", o.LabelSelector) + if o.LabelSelector != "app.kubernetes.io/name=thanos-ruler,thanos-ruler=test" && o.LabelSelector != "thanos-ruler=test,app.kubernetes.io/name=thanos-ruler" { + t.Fatalf("LabelSelector not computed correctly\n\nExpected: \"app.kubernetes.io/name=thanos-ruler,thanos-ruler=test\"\n\nGot: %#+v", o.LabelSelector) } } } diff --git a/pkg/thanos/statefulset.go b/pkg/thanos/statefulset.go index 297d3bae22..bcc56f33d0 100644 --- a/pkg/thanos/statefulset.go +++ b/pkg/thanos/statefulset.go @@ -351,6 +351,7 @@ func makeStatefulSetSpec(tr *monitoringv1.ThanosRuler, config Config, ruleConfig } } } + // TODO(paulfantom): remove `app` label after 0.50 release podLabels["app"] = thanosRulerLabel podLabels["app.kubernetes.io/name"] = thanosRulerLabel podLabels["app.kubernetes.io/managed-by"] = "prometheus-operator" @@ -358,6 +359,8 @@ func makeStatefulSetSpec(tr *monitoringv1.ThanosRuler, config Config, ruleConfig podLabels[thanosRulerLabel] = tr.Name finalLabels := config.Labels.Merge(podLabels) + podAnnotations["kubectl.kubernetes.io/default-container"] = "thanos-ruler" + storageVolName := volumeName(tr.Name) if tr.Spec.Storage != nil { if tr.Spec.Storage.VolumeClaimTemplate.Name != "" { @@ -480,7 +483,7 @@ func makeStatefulSetService(tr *monitoringv1.ThanosRuler, config Config) *v1.Ser }, }, Selector: map[string]string{ - "app": "thanos-ruler", + "app.kubernetes.io/name": thanosRulerLabel, }, }, } diff --git a/pkg/thanos/statefulset_test.go b/pkg/thanos/statefulset_test.go index 68f96387dd..0cf111b54f 100644 --- a/pkg/thanos/statefulset_test.go +++ b/pkg/thanos/statefulset_test.go @@ -101,10 +101,10 @@ func TestPodLabelsAnnotations(t *testing.T) { }, }, defaultTestConfig, nil, "") require.NoError(t, err) - if _, ok := sset.Spec.Template.ObjectMeta.Labels["testlabel"]; !ok { + if val, ok := sset.Spec.Template.ObjectMeta.Labels["testlabel"]; !ok || val != "testvalue" { t.Fatal("Pod labels are not properly propagated") } - if !reflect.DeepEqual(annotations, sset.Spec.Template.ObjectMeta.Annotations) { + if val, ok := sset.Spec.Template.ObjectMeta.Annotations["testannotation"]; !ok || val != "testvalue" { t.Fatal("Pod annotations are not properly propagated") } } diff --git a/test/e2e/alertmanager_instance_namespaces_test.go b/test/e2e/alertmanager_instance_namespaces_test.go index 7319ec29f2..584009fbe8 100644 --- a/test/e2e/alertmanager_instance_namespaces_test.go +++ b/test/e2e/alertmanager_instance_namespaces_test.go @@ -19,11 +19,9 @@ import ( "fmt" "strings" "testing" - "time" api_errors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/util/wait" monitoringv1alpha1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1alpha1" testFramework "github.com/prometheus-operator/prometheus-operator/test/framework" @@ -154,7 +152,8 @@ func testAlertmanagerInstanceNamespacesAllowList(t *testing.T) { }, } - _, err = framework.MonClientV1.Alertmanagers(allowedNs).Create(context.TODO(), am, metav1.CreateOptions{}) + // Create an Alertmanager resource in the "allowedNs" namespace which must *not* be reconciled. + _, err = framework.MonClientV1.Alertmanagers(allowedNs).Create(context.TODO(), am.DeepCopy(), metav1.CreateOptions{}) if err != nil { t.Fatal(err) } @@ -197,28 +196,49 @@ func testAlertmanagerInstanceNamespacesAllowList(t *testing.T) { } // Check that the AlertmanagerConfig resource in the "allowed" namespace is reconciled but not the one in "instance". - var pollError error - err = wait.Poll(10*time.Second, time.Minute*5, func() (bool, error) { - amStatus, err := framework.GetAlertmanagerStatus(instanceNs, "alertmanager-instance-0") - if err != nil { - pollError = fmt.Errorf("failed to query Alertmanager: %s", err) - return false, nil - } + err = framework.PollAlertmanagerConfiguration(instanceNs, "instance", + func(config string) error { + if !strings.Contains(config, "void") { + return fmt.Errorf("expected generated configuration to contain %q but got %q", "void", config) + } - if !strings.Contains(*amStatus.Config.Original, "void") { - pollError = fmt.Errorf("expected generated configuration to contain %q but got %q", "void", *amStatus.Config.Original) - return false, nil - } - - if strings.Contains(*amStatus.Config.Original, instanceNs) { - pollError = fmt.Errorf("expected generated configuration to not contain %q but got %q", instanceNs, *amStatus.Config.Original) - return false, nil - } + return nil + }, + func(config string) error { + if strings.Contains(config, instanceNs) { + return fmt.Errorf("expected generated configuration to not contain %q but got %q", instanceNs, config) + } - return true, nil - }) + return nil + }, + ) if err != nil { - t.Fatalf("failed to wait for alertmanager config: %v: %v", err, pollError) + t.Fatalf("failed to wait for alertmanager config: %v", err) } + + // FIXME(simonpasquier): the unprivileged namespace lister/watcher + // isn't notified of updates properly so the code below fails. + // Uncomment the test once the lister/watcher is fixed. + // + // Remove the selecting label on the "allowed" namespace and check that + // the alertmanager configuration is updated. + // See https://github.com/prometheus-operator/prometheus-operator/issues/3847 + //if err := testFramework.RemoveLabelsFromNamespace(framework.KubeClient, allowedNs, "monitored"); err != nil { + // t.Fatal(err) + //} + + //err = framework.PollAlertmanagerConfiguration(instanceNs, "instance", + // func(config string) error { + // if strings.Contains(config, "void") { + // return fmt.Errorf("expected generated configuration to not contain %q but got %q", "void", config) + // } + + // return nil + // }, + //) + + //if err != nil { + // t.Fatalf("failed to wait for alertmanager config: %v", err) + //} } diff --git a/test/e2e/alertmanager_test.go b/test/e2e/alertmanager_test.go index 798821d449..a9516f9291 100644 --- a/test/e2e/alertmanager_test.go +++ b/test/e2e/alertmanager_test.go @@ -359,6 +359,7 @@ func testAMReloadConfig(t *testing.T) { firstConfig := ` global: resolve_timeout: 5m + http_config: {} route: group_by: ['job'] group_wait: 30s @@ -513,13 +514,13 @@ func testAMZeroDowntimeRollingDeployment(t *testing.T) { Replicas: &whReplicas, Selector: &metav1.LabelSelector{ MatchLabels: map[string]string{ - "app": "alertmanager-webhook", + "app.kubernetes.io/name": "alertmanager-webhook", }, }, Template: v1.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ Labels: map[string]string{ - "app": "alertmanager-webhook", + "app.kubernetes.io/name": "alertmanager-webhook", }, }, Spec: v1.PodSpec{ @@ -553,7 +554,7 @@ func testAMZeroDowntimeRollingDeployment(t *testing.T) { }, }, Selector: map[string]string{ - "app": "alertmanager-webhook", + "app.kubernetes.io/name": "alertmanager-webhook", }, }, } @@ -566,7 +567,7 @@ func testAMZeroDowntimeRollingDeployment(t *testing.T) { err := testFramework.WaitForPodsReady(framework.KubeClient, ns, time.Minute*5, 1, metav1.ListOptions{ LabelSelector: fields.SelectorFromSet(fields.Set(map[string]string{ - "app": "alertmanager-webhook", + "app.kubernetes.io/name": "alertmanager-webhook", })).String(), }, ) @@ -669,7 +670,7 @@ inhibit_rules: opts := metav1.ListOptions{ LabelSelector: fields.SelectorFromSet(fields.Set(map[string]string{ - "app": "alertmanager-webhook", + "app.kubernetes.io/name": "alertmanager-webhook", })).String(), } pl, err := framework.KubeClient.CoreV1().Pods(ns).List(context.TODO(), opts) @@ -725,11 +726,20 @@ func testAlertmanagerConfigCRD(t *testing.T) { ctx := framework.NewTestCtx(t) defer ctx.Cleanup(t) ns := ctx.CreateNamespace(t, framework.KubeClient) + configNs := ctx.CreateNamespace(t, framework.KubeClient) ctx.SetupPrometheusRBAC(t, ns, framework.KubeClient) alertmanager := framework.MakeBasicAlertmanager("amconfig-crd", 1) alertmanager.Spec.AlertmanagerConfigSelector = &metav1.LabelSelector{} - if _, err := framework.CreateAlertmanagerAndWaitUntilReady(ns, alertmanager); err != nil { + alertmanager.Spec.AlertmanagerConfigNamespaceSelector = &metav1.LabelSelector{ + MatchLabels: map[string]string{"monitored": "true"}, + } + alertmanager, err := framework.CreateAlertmanagerAndWaitUntilReady(ns, alertmanager) + if err != nil { + t.Fatal(err) + } + + if err := testFramework.AddLabelsToNamespace(framework.KubeClient, configNs, map[string]string{"monitored": "true"}); err != nil { t.Fatal(err) } @@ -744,7 +754,7 @@ func testAlertmanagerConfigCRD(t *testing.T) { testingSecretKey: []byte("1234abc"), }, } - if _, err := framework.KubeClient.CoreV1().Secrets(ns).Create(context.TODO(), testingKeySecret, metav1.CreateOptions{}); err != nil { + if _, err := framework.KubeClient.CoreV1().Secrets(configNs).Create(context.TODO(), testingKeySecret, metav1.CreateOptions{}); err != nil { t.Fatal(err) } @@ -756,7 +766,7 @@ func testAlertmanagerConfigCRD(t *testing.T) { "api-key": []byte("1234abc"), }, } - if _, err := framework.KubeClient.CoreV1().Secrets(ns).Create(context.TODO(), apiKeySecret, metav1.CreateOptions{}); err != nil { + if _, err := framework.KubeClient.CoreV1().Secrets(configNs).Create(context.TODO(), apiKeySecret, metav1.CreateOptions{}); err != nil { t.Fatal(err) } @@ -768,15 +778,14 @@ func testAlertmanagerConfigCRD(t *testing.T) { "api-url": []byte("http://slack.example.com"), }, } - if _, err := framework.KubeClient.CoreV1().Secrets(ns).Create(context.TODO(), slackAPIURLSecret, metav1.CreateOptions{}); err != nil { + if _, err := framework.KubeClient.CoreV1().Secrets(configNs).Create(context.TODO(), slackAPIURLSecret, metav1.CreateOptions{}); err != nil { t.Fatal(err) } // A valid AlertmanagerConfig resource with many receivers. configCR := &monitoringv1alpha1.AlertmanagerConfig{ ObjectMeta: metav1.ObjectMeta{ - Name: "e2e-test-amconfig-many-receivers", - Namespace: ns, + Name: "e2e-test-amconfig-many-receivers", }, Spec: monitoringv1alpha1.AlertmanagerConfigSpec{ Route: &monitoringv1alpha1.Route{ @@ -889,15 +898,14 @@ func testAlertmanagerConfigCRD(t *testing.T) { }, } - if _, err := framework.MonClientV1alpha1.AlertmanagerConfigs(ns).Create(context.TODO(), configCR, metav1.CreateOptions{}); err != nil { + if _, err := framework.MonClientV1alpha1.AlertmanagerConfigs(configNs).Create(context.TODO(), configCR, metav1.CreateOptions{}); err != nil { t.Fatal(err) } // Another AlertmanagerConfig object with nested routes. configCR = &monitoringv1alpha1.AlertmanagerConfig{ ObjectMeta: metav1.ObjectMeta{ - Name: "e2e-test-amconfig-sub-routes", - Namespace: ns, + Name: "e2e-test-amconfig-sub-routes", }, Spec: monitoringv1alpha1.AlertmanagerConfigSpec{ Route: &monitoringv1alpha1.Route{ @@ -952,7 +960,7 @@ func testAlertmanagerConfigCRD(t *testing.T) { }, } - if _, err := framework.MonClientV1alpha1.AlertmanagerConfigs(ns).Create(context.TODO(), configCR, metav1.CreateOptions{}); err != nil { + if _, err := framework.MonClientV1alpha1.AlertmanagerConfigs(configNs).Create(context.TODO(), configCR, metav1.CreateOptions{}); err != nil { t.Fatal(err) } @@ -960,8 +968,7 @@ func testAlertmanagerConfigCRD(t *testing.T) { // should be rejected by the operator. configCR = &monitoringv1alpha1.AlertmanagerConfig{ ObjectMeta: metav1.ObjectMeta{ - Name: "e2e-test-amconfig-missing-secret", - Namespace: ns, + Name: "e2e-test-amconfig-missing-secret", }, Spec: monitoringv1alpha1.AlertmanagerConfigSpec{ Route: &monitoringv1alpha1.Route{ @@ -982,7 +989,7 @@ func testAlertmanagerConfigCRD(t *testing.T) { }, } - if _, err := framework.MonClientV1alpha1.AlertmanagerConfigs(ns).Create(context.TODO(), configCR, metav1.CreateOptions{}); err != nil { + if _, err := framework.MonClientV1alpha1.AlertmanagerConfigs(configNs).Create(context.TODO(), configCR, metav1.CreateOptions{}); err != nil { t.Fatal(err) } @@ -990,8 +997,7 @@ func testAlertmanagerConfigCRD(t *testing.T) { // It should be rejected by the operator. configCR = &monitoringv1alpha1.AlertmanagerConfig{ ObjectMeta: metav1.ObjectMeta{ - Name: "e2e-test-amconfig-invalid-route", - Namespace: ns, + Name: "e2e-test-amconfig-invalid-route", }, Spec: monitoringv1alpha1.AlertmanagerConfigSpec{ Route: &monitoringv1alpha1.Route{ @@ -1015,24 +1021,22 @@ func testAlertmanagerConfigCRD(t *testing.T) { }, } - if _, err := framework.MonClientV1alpha1.AlertmanagerConfigs(ns).Create(context.TODO(), configCR, metav1.CreateOptions{}); err != nil { + if _, err := framework.MonClientV1alpha1.AlertmanagerConfigs(configNs).Create(context.TODO(), configCR, metav1.CreateOptions{}); err != nil { t.Fatal(err) } // Wait for the change above to take effect. var lastErr error - err := wait.Poll(5*time.Second, 2*time.Minute, func() (bool, error) { - cfgSecret, err := framework.KubeClient.CoreV1().Secrets(ns).Get(context.TODO(), "alertmanager-amconfig-crd-generated", metav1.GetOptions{}) - if apierrors.IsNotFound(err) { - lastErr = errors.New("Generated configuration secret not found") - return false, nil - } + amConfigSecretName := fmt.Sprintf("alertmanager-%s-generated", alertmanager.Name) + err = wait.Poll(5*time.Second, 2*time.Minute, func() (bool, error) { + cfgSecret, err := framework.KubeClient.CoreV1().Secrets(ns).Get(context.TODO(), amConfigSecretName, metav1.GetOptions{}) if err != nil { - return false, err + lastErr = errors.Wrap(err, "failed to get generated configuration secret") + return false, nil } if cfgSecret.Data["alertmanager.yaml"] == nil { - lastErr = errors.New("'alertmanager.yaml' key is missing") + lastErr = errors.New("'alertmanager.yaml' key is missing in generated configuration secret") return false, nil } @@ -1113,17 +1117,65 @@ receivers: webhook_configs: - url: http://test.url templates: [] -`, ns, ns, ns, ns, ns, ns, ns, ns, ns) +`, configNs, configNs, configNs, configNs, configNs, configNs, configNs, configNs, configNs) if diff := cmp.Diff(string(cfgSecret.Data["alertmanager.yaml"]), expected); diff != "" { - t.Log("got(-), want(+):\n" + diff) + lastErr = errors.Errorf("got(-), want(+):\n%s", diff) return false, nil } return true, nil }) if err != nil { - t.Fatalf("%v: %v", err, lastErr) + t.Fatalf("waiting for generated alertmanager configuration: %v: %v", err, lastErr) + } + + // Remove the selecting label from the namespace holding the + // AlertmanagerConfig resources and wait until the Alertmanager + // configuration gets regenerated. + // See https://github.com/prometheus-operator/prometheus-operator/issues/3847 + if err := testFramework.RemoveLabelsFromNamespace(framework.KubeClient, configNs, "monitored"); err != nil { + t.Fatal(err) + } + + err = wait.Poll(5*time.Second, 2*time.Minute, func() (bool, error) { + cfgSecret, err := framework.KubeClient.CoreV1().Secrets(ns).Get(context.TODO(), amConfigSecretName, metav1.GetOptions{}) + if err != nil { + lastErr = errors.Wrap(err, "failed to get generated configuration secret") + return false, nil + } + + if cfgSecret.Data["alertmanager.yaml"] == nil { + lastErr = errors.New("'alertmanager.yaml' key is missing in generated configuration secret") + return false, nil + } + expected := `global: + resolve_timeout: 5m +route: + receiver: "null" + group_by: + - job + routes: + - receiver: "null" + match: + alertname: DeadMansSwitch + group_wait: 30s + group_interval: 5m + repeat_interval: 12h +receivers: +- name: "null" +templates: [] +` + + if diff := cmp.Diff(string(cfgSecret.Data["alertmanager.yaml"]), expected); diff != "" { + lastErr = errors.Errorf("got(-), want(+):\n%s", diff) + return false, nil + } + + return true, nil + }) + if err != nil { + t.Fatalf("waiting for alertmanager configuration: %v: %v", err, lastErr) } } diff --git a/test/e2e/denylist_test.go b/test/e2e/denylist_test.go index be256edfd2..90e85be2ab 100644 --- a/test/e2e/denylist_test.go +++ b/test/e2e/denylist_test.go @@ -211,7 +211,7 @@ func testDenyThanosRuler(t *testing.T) { } for _, denied := range deniedNamespaces { - tr := framework.MakeBasicThanosRuler("denied", 1) + tr := framework.MakeBasicThanosRuler("denied", 1, "http://test.example.com") _, err = framework.MonClientV1.ThanosRulers(denied).Create(context.TODO(), tr, metav1.CreateOptions{}) if err != nil { t.Fatalf("creating %v Prometheus instances failed (%v): %v", tr.Spec.Replicas, tr.Name, err) @@ -221,7 +221,7 @@ func testDenyThanosRuler(t *testing.T) { for _, allowed := range allowedNamespaces { ctx.SetupPrometheusRBAC(t, allowed, framework.KubeClient) - if _, err := framework.CreateThanosRulerAndWaitUntilReady(allowed, framework.MakeBasicThanosRuler("allowed", 1)); err != nil { + if _, err := framework.CreateThanosRulerAndWaitUntilReady(allowed, framework.MakeBasicThanosRuler("allowed", 1, "http://test.example.com")); err != nil { t.Fatal(err) } } diff --git a/test/e2e/main_test.go b/test/e2e/main_test.go index 3daac702f7..ae94c86cfe 100644 --- a/test/e2e/main_test.go +++ b/test/e2e/main_test.go @@ -206,8 +206,9 @@ func testAllNSPrometheus(t *testing.T) { func testAllNSThanosRuler(t *testing.T) { skipThanosRulerTests(t) testFuncs := map[string]func(t *testing.T){ - "ThanosRulerCreateDeleteCluster": testTRCreateDeleteCluster, - "ThanosRulerPreserveUserAddedMetadata": testTRPreserveUserAddedMetadata, + "ThanosRulerCreateDeleteCluster": testThanosRulerCreateDeleteCluster, + "ThanosRulerPrometheusRuleInDifferentNamespace": testThanosRulerPrometheusRuleInDifferentNamespace, + "ThanosRulerPreserveUserAddedMetadata": testTRPreserveUserAddedMetadata, } for name, f := range testFuncs { t.Run(name, f) diff --git a/test/e2e/prometheus_instance_namespaces_test.go b/test/e2e/prometheus_instance_namespaces_test.go index 0d9ac56088..4396a8e1c1 100644 --- a/test/e2e/prometheus_instance_namespaces_test.go +++ b/test/e2e/prometheus_instance_namespaces_test.go @@ -295,6 +295,21 @@ func testPrometheusInstanceNamespacesAllowList(t *testing.T) { if err := framework.WaitForActiveTargets(instanceNs, "prometheus-instance", 1); err != nil { t.Fatal(err) } + + // FIXME(simonpasquier): the unprivileged namespace lister/watcher + // isn't notified of updates properly so the code below fails. + // Uncomment the test once the lister/watcher is fixed. + // + // Remove the selecting label on the "allowed" namespace and check that + // the target is removed. + // See https://github.com/prometheus-operator/prometheus-operator/issues/3847 + //if err := testFramework.RemoveLabelsFromNamespace(framework.KubeClient, allowedNs, "monitored"); err != nil { + // t.Fatal(err) + //} + + //if err := framework.WaitForActiveTargets(instanceNs, "prometheus-instance", 0); err != nil { + // t.Fatal(err) + //} } // this is not ideal, as we cannot really find out if prometheus operator did not reconcile the denied prometheus. diff --git a/test/e2e/prometheus_test.go b/test/e2e/prometheus_test.go index 4a44e20817..127e3e0097 100644 --- a/test/e2e/prometheus_test.go +++ b/test/e2e/prometheus_test.go @@ -1423,7 +1423,7 @@ func testPromMultiplePrometheusRulesDifferentNS(t *testing.T) { ns string }{{"first-alert", alertNSOne}, {"second-alert", alertNSTwo}} - ruleFilesNamespaceSelector := map[string]string{"prometheus": rootNS} + ruleFilesNamespaceSelector := map[string]string{"monitored": "true"} for _, file := range ruleFiles { err := testFramework.AddLabelsToNamespace(framework.KubeClient, file.ns, ruleFilesNamespaceSelector) @@ -1462,6 +1462,28 @@ func testPromMultiplePrometheusRulesDifferentNS(t *testing.T) { t.Fatal(err) } } + + // Remove the selecting label from the namespaces holding PrometheusRules + // and wait until the rules are removed from Prometheus. + // See https://github.com/prometheus-operator/prometheus-operator/issues/3847 + for _, file := range ruleFiles { + if err := testFramework.RemoveLabelsFromNamespace(framework.KubeClient, file.ns, "monitored"); err != nil { + t.Fatal(err) + } + } + + for _, file := range ruleFiles { + var loopError error + err = wait.Poll(time.Second, 5*framework.DefaultTimeout, func() (bool, error) { + var firing bool + firing, loopError = framework.CheckPrometheusFiringAlert(file.ns, pSVC.Name, file.alertName) + return !firing, nil + }) + + if err != nil { + t.Fatalf("waiting for alert %q in namespace %s to stop firing: %v: %v", file.alertName, file.ns, err, loopError) + } + } } func testPromRulesExceedingConfigMapLimit(t *testing.T) { diff --git a/test/e2e/thanosruler_test.go b/test/e2e/thanosruler_test.go index c3f71c1fd6..5995bef84b 100644 --- a/test/e2e/thanosruler_test.go +++ b/test/e2e/thanosruler_test.go @@ -16,22 +16,27 @@ package e2e import ( "context" + "fmt" "testing" + "time" + testFramework "github.com/prometheus-operator/prometheus-operator/test/framework" "google.golang.org/protobuf/proto" + v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/wait" ) -func testTRCreateDeleteCluster(t *testing.T) { - +func testThanosRulerCreateDeleteCluster(t *testing.T) { ctx := framework.NewTestCtx(t) defer ctx.Cleanup(t) + ns := ctx.CreateNamespace(t, framework.KubeClient) ctx.SetupPrometheusRBAC(t, ns, framework.KubeClient) name := "test" - if _, err := framework.CreateThanosRulerAndWaitUntilReady(ns, framework.MakeBasicThanosRuler(name, 1)); err != nil { + if _, err := framework.CreateThanosRulerAndWaitUntilReady(ns, framework.MakeBasicThanosRuler(name, 1, "http://test.example.com")); err != nil { t.Fatal(err) } @@ -40,6 +45,82 @@ func testTRCreateDeleteCluster(t *testing.T) { } } +func testThanosRulerPrometheusRuleInDifferentNamespace(t *testing.T) { + ctx := framework.NewTestCtx(t) + defer ctx.Cleanup(t) + + thanosNamespace := ctx.CreateNamespace(t, framework.KubeClient) + ctx.SetupPrometheusRBAC(t, thanosNamespace, framework.KubeClient) + + name := "test" + + // Create a Prometheus resource because Thanos ruler needs a query API. + prometheus, err := framework.CreatePrometheusAndWaitUntilReady(thanosNamespace, framework.MakeBasicPrometheus(thanosNamespace, name, name, 1)) + if err != nil { + t.Fatal(err) + } + + svc := framework.MakePrometheusService(prometheus.Name, name, v1.ServiceTypeClusterIP) + if _, err := testFramework.CreateServiceAndWaitUntilReady(framework.KubeClient, thanosNamespace, svc); err != nil { + t.Fatal(err) + } + + thanos := framework.MakeBasicThanosRuler(name, 1, fmt.Sprintf("http://%s:%d/", svc.Name, svc.Spec.Ports[0].Port)) + thanos.Spec.RuleSelector = &metav1.LabelSelector{} + thanos.Spec.RuleNamespaceSelector = &metav1.LabelSelector{ + MatchLabels: map[string]string{ + "monitored": "true", + }, + } + thanos.Spec.EvaluationInterval = "1s" + + if _, err := framework.CreateThanosRulerAndWaitUntilReady(thanosNamespace, thanos); err != nil { + t.Fatal(err) + } + + ruleNamespace := ctx.CreateNamespace(t, framework.KubeClient) + if err := testFramework.AddLabelsToNamespace(framework.KubeClient, ruleNamespace, map[string]string{ + "monitored": "true", + }); err != nil { + t.Fatal(err) + } + + const testAlert = "alert1" + _, err = framework.MakeAndCreateFiringRule(ruleNamespace, "rule1", testAlert) + if err != nil { + t.Fatal(err) + } + + thanosService := framework.MakeThanosRulerService(thanos.Name, "not-relevant", v1.ServiceTypeClusterIP) + if finalizerFn, err := testFramework.CreateServiceAndWaitUntilReady(framework.KubeClient, thanosNamespace, thanosService); err != nil { + t.Fatalf("creating Thanos ruler service failed: %v", err) + } else { + ctx.AddFinalizerFn(finalizerFn) + } + + if err := framework.WaitForThanosFiringAlert(thanosNamespace, thanosService.Name, testAlert); err != nil { + t.Fatal(err) + } + + // Remove the selecting label from ruleNamespace and wait until the rule is + // removed from the Thanos ruler. + // See https://github.com/prometheus-operator/prometheus-operator/issues/3847 + if err := testFramework.RemoveLabelsFromNamespace(framework.KubeClient, ruleNamespace, "monitored"); err != nil { + t.Fatal(err) + } + + var loopError error + err = wait.Poll(time.Second, 5*framework.DefaultTimeout, func() (bool, error) { + var firing bool + firing, loopError = framework.CheckThanosFiringAlert(thanosNamespace, thanosService.Name, testAlert) + return !firing, nil + }) + + if err != nil { + t.Fatalf("waiting for alert %q to stop firing: %v: %v", testAlert, err, loopError) + } +} + func testTRPreserveUserAddedMetadata(t *testing.T) { t.Parallel() @@ -50,7 +131,7 @@ func testTRPreserveUserAddedMetadata(t *testing.T) { name := "test" - thanosRuler := framework.MakeBasicThanosRuler(name, 1) + thanosRuler := framework.MakeBasicThanosRuler(name, 1, "http://test.example.com") thanosRuler, err := framework.CreateThanosRulerAndWaitUntilReady(ns, thanosRuler) if err != nil { t.Fatal(err) diff --git a/test/framework/alertmanager.go b/test/framework/alertmanager.go index 9ca7b1d571..bf47031b62 100644 --- a/test/framework/alertmanager.go +++ b/test/framework/alertmanager.go @@ -339,10 +339,10 @@ func (f *Framework) GetSilences(ns, n string) (models.GettableSilences, error) { return getSilencesResponse, nil } -// WaitForAlertmanagerConfigToContainString retrieves the Alertmanager -// configuration via the Alertmanager's API and checks if it contains the given -// string. -func (f *Framework) WaitForAlertmanagerConfigToContainString(ns, amName, expectedString string) error { +// PollAlertmanagerConfiguration retrieves the Alertmanager configuration via +// the Alertmanager's API and checks that all conditions return without error. +// It will retry every 10 second for 5 minutes before giving up. +func (f *Framework) PollAlertmanagerConfiguration(ns, amName string, conditions ...func(config string) error) error { var pollError error err := wait.Poll(10*time.Second, time.Minute*5, func() (bool, error) { amStatus, err := f.GetAlertmanagerStatus(ns, "alertmanager-"+amName+"-0") @@ -352,9 +352,11 @@ func (f *Framework) WaitForAlertmanagerConfigToContainString(ns, amName, expecte return false, nil } - if !strings.Contains(*amStatus.Config.Original, expectedString) { - pollError = fmt.Errorf("failed to get matching config expected %q but got %q", expectedString, *amStatus.Config.Original) - return false, nil + for _, c := range conditions { + pollError = c(*amStatus.Config.Original) + if pollError != nil { + return false, nil + } } return true, nil @@ -367,6 +369,15 @@ func (f *Framework) WaitForAlertmanagerConfigToContainString(ns, amName, expecte return nil } +func (f *Framework) WaitForAlertmanagerConfigToContainString(ns, amName, expected string) error { + return f.PollAlertmanagerConfiguration(ns, amName, func(config string) error { + if !strings.Contains(config, expected) { + return fmt.Errorf("failed to get matching config expected %q but got %q", expected, config) + } + return nil + }) +} + func (f *Framework) WaitForAlertmanagerConfigToBeReloaded(ns, amName string, previousReloadTimestamp time.Time) error { const configReloadMetricName = "alertmanager_config_last_reload_success_timestamp_seconds" err := wait.Poll(10*time.Second, time.Minute*5, func() (bool, error) { diff --git a/test/framework/namespace.go b/test/framework/namespace.go index 50d5c7e86c..5e0c7806d3 100644 --- a/test/framework/namespace.go +++ b/test/framework/namespace.go @@ -16,12 +16,14 @@ package framework import ( "context" + "encoding/json" "fmt" "testing" "github.com/pkg/errors" "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" "k8s.io/client-go/kubernetes" ) @@ -77,3 +79,35 @@ func AddLabelsToNamespace(kubeClient kubernetes.Interface, name string, addition return nil } + +func RemoveLabelsFromNamespace(kubeClient kubernetes.Interface, name string, labels ...string) error { + ns, err := kubeClient.CoreV1().Namespaces().Get(context.TODO(), name, metav1.GetOptions{}) + if err != nil { + return err + } + + if len(ns.Labels) == 0 { + return nil + } + + type patch struct { + Op string `json:"op"` + Path string `json:"path"` + } + + var patches []patch + for _, l := range labels { + patches = append(patches, patch{Op: "remove", Path: "/metadata/labels/" + l}) + } + b, err := json.Marshal(patches) + if err != nil { + return err + } + + _, err = kubeClient.CoreV1().Namespaces().Patch(context.TODO(), name, types.JSONPatchType, b, metav1.PatchOptions{}) + if err != nil { + return err + } + + return nil +} diff --git a/test/framework/probe.go b/test/framework/probe.go index f13bc3ce27..71a7167d54 100644 --- a/test/framework/probe.go +++ b/test/framework/probe.go @@ -36,7 +36,7 @@ func (f *Framework) MakeBlackBoxExporterService(ns, name string) *v1.Service { Spec: v1.ServiceSpec{ Type: v1.ServiceTypeClusterIP, Selector: map[string]string{ - "app": "blackbox-exporter", + "app.kubernetes.io/name": "blackbox-exporter", }, Ports: []v1.ServicePort{ { @@ -88,13 +88,13 @@ func (f *Framework) createBlackBoxExporterDeploymentAndWaitReady(ns, name string Replicas: &replicas, Selector: &metav1.LabelSelector{ MatchLabels: map[string]string{ - "app": "blackbox-exporter", + "app.kubernetes.io/name": "blackbox-exporter", }, }, Template: v1.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ Labels: map[string]string{ - "app": "blackbox-exporter", + "app.kubernetes.io/name": "blackbox-exporter", }, }, Spec: v1.PodSpec{ diff --git a/test/framework/prometheus.go b/test/framework/prometheus.go index 6ce8290571..dbfa2261f7 100644 --- a/test/framework/prometheus.go +++ b/test/framework/prometheus.go @@ -262,7 +262,7 @@ func (f *Framework) MakeThanosQuerierService(name string) *v1.Service { }, }, Selector: map[string]string{ - "app": "thanos-query", + "app.kubernetes.io/name": "thanos-query", }, }, } @@ -532,7 +532,7 @@ func (f *Framework) CheckPrometheusFiringAlert(ns, svcName, alertName string) (b ns, svcName, "/api/v1/query", - map[string]string{"query": fmt.Sprintf("ALERTS{alertname=\"%v\"}", alertName)}, + map[string]string{"query": fmt.Sprintf(`ALERTS{alertname="%v",alertstate="firing"}`, alertName)}, ) if err != nil { return false, err @@ -547,12 +547,7 @@ func (f *Framework) CheckPrometheusFiringAlert(ns, svcName, alertName string) (b return false, errors.Errorf("expected 1 query result but got %v", len(q.Data.Result)) } - alertstate, ok := q.Data.Result[0].Metric["alertstate"] - if !ok { - return false, errors.Errorf("could not retrieve 'alertstate' label from query result: %v", q.Data.Result[0]) - } - - return alertstate == "firing", nil + return true, nil } // PrintPrometheusLogs prints the logs for each Prometheus replica. @@ -586,8 +581,8 @@ func (f *Framework) WaitForPrometheusFiringAlert(ns, svcName, alertName string) return errors.Errorf( "waiting for alert '%v' to fire: %v: %v", alertName, - err.Error(), - loopError.Error(), + err, + loopError, ) } return nil diff --git a/test/framework/thanosruler.go b/test/framework/thanosruler.go index 2f98bf3fef..4901750d40 100644 --- a/test/framework/thanosruler.go +++ b/test/framework/thanosruler.go @@ -15,11 +15,15 @@ package framework import ( + "bytes" "context" + "encoding/json" "fmt" "time" + v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/apimachinery/pkg/util/wait" "github.com/pkg/errors" @@ -27,14 +31,14 @@ import ( "github.com/prometheus-operator/prometheus-operator/pkg/thanos" ) -func (f *Framework) MakeBasicThanosRuler(name string, replicas int32) *monitoringv1.ThanosRuler { +func (f *Framework) MakeBasicThanosRuler(name string, replicas int32, queryEndpoint string) *monitoringv1.ThanosRuler { return &monitoringv1.ThanosRuler{ ObjectMeta: metav1.ObjectMeta{ Name: name, }, Spec: monitoringv1.ThanosRulerSpec{ Replicas: &replicas, - QueryEndpoints: []string{"test"}, + QueryEndpoints: []string{queryEndpoint}, LogLevel: "debug", }, } @@ -84,6 +88,85 @@ func (f *Framework) WaitForThanosRulerReady(tr *monitoringv1.ThanosRuler, timeou return errors.Wrapf(pollErr, "waiting for ThanosRuler %v/%v: %v", tr.Namespace, tr.Name, err) } +func (f *Framework) MakeThanosRulerService(name, group string, serviceType v1.ServiceType) *v1.Service { + service := &v1.Service{ + ObjectMeta: metav1.ObjectMeta{ + Name: fmt.Sprintf("thanos-ruler-%s", name), + Labels: map[string]string{ + "group": group, + }, + }, + Spec: v1.ServiceSpec{ + Type: serviceType, + Ports: []v1.ServicePort{ + { + Name: "web", + Port: 9090, + TargetPort: intstr.FromString("web"), + }, + }, + Selector: map[string]string{ + "thanos-ruler": name, + }, + }, + } + return service +} + +func (f *Framework) WaitForThanosFiringAlert(ns, svcName, alertName string) error { + var loopError error + + err := wait.Poll(time.Second, 5*f.DefaultTimeout, func() (bool, error) { + var firing bool + firing, loopError = f.CheckThanosFiringAlert(ns, svcName, alertName) + return firing, nil + }) + + if err != nil { + return errors.Errorf( + "waiting for alert '%v' to fire: %v: %v", + alertName, + err, + loopError, + ) + } + return nil +} + +func (f *Framework) CheckThanosFiringAlert(ns, svcName, alertName string) (bool, error) { + response, err := f.ThanosSVCGetRequest( + ns, + svcName, + "/api/v1/alerts", + nil, + ) + if err != nil { + return false, errors.Wrapf(err, "failed to get Thanos service %s/%s", ns, svcName) + } + + apiResponse := ThanosAlertsAPIResponse{} + if err := json.NewDecoder(bytes.NewBuffer(response)).Decode(&apiResponse); err != nil { + return false, errors.Wrap(err, "failed to decode alerts from Thanos ruler API") + } + + for _, alert := range apiResponse.Data.Alerts { + if alert.State != "firing" { + continue + } + if alert.Labels["alertname"] == alertName { + return true, nil + } + } + + return false, fmt.Errorf("failed to find %q alert in the list of %d alerts", alertName, len(apiResponse.Data.Alerts)) +} + +func (f *Framework) ThanosSVCGetRequest(ns, svcName, endpoint string, query map[string]string) ([]byte, error) { + ProxyGet := f.KubeClient.CoreV1().Services(ns).ProxyGet + request := ProxyGet("", svcName, "web", endpoint, query) + return request.DoRaw(context.TODO()) +} + func (f *Framework) DeleteThanosRulerAndWaitUntilGone(ns, name string) error { _, err := f.MonClientV1.ThanosRulers(ns).Get(context.TODO(), name, metav1.GetOptions{}) if err != nil { @@ -109,3 +192,20 @@ func (f *Framework) DeleteThanosRulerAndWaitUntilGone(ns, name string) error { return nil } + +type ThanosAlert struct { + Labels map[string]string `json:"labels"` + Annotations map[string]string `json:"annotations"` + State string `json:"state"` + ActiveAt time.Time `json:"activeAt"` + Value string `json:"value"` +} + +type ThanosAlertsData struct { + Alerts []ThanosAlert `json:"alerts"` +} + +type ThanosAlertsAPIResponse struct { + Status string `json:"status"` + Data *ThanosAlertsData `json:"data"` +} diff --git a/vendor/github.com/go-openapi/errors/.golangci.yml b/vendor/github.com/go-openapi/errors/.golangci.yml index f9381aee54..ee3b326969 100644 --- a/vendor/github.com/go-openapi/errors/.golangci.yml +++ b/vendor/github.com/go-openapi/errors/.golangci.yml @@ -39,3 +39,5 @@ linters: - nestif - godot - errorlint + - paralleltest + - tparallel diff --git a/vendor/github.com/go-openapi/errors/README.md b/vendor/github.com/go-openapi/errors/README.md index 0ce50b23b2..4aac049e60 100644 --- a/vendor/github.com/go-openapi/errors/README.md +++ b/vendor/github.com/go-openapi/errors/README.md @@ -1,7 +1,10 @@ -# OpenAPI errors [![Build Status](https://travis-ci.org/go-openapi/errors.svg?branch=master)](https://travis-ci.org/go-openapi/errors) [![codecov](https://codecov.io/gh/go-openapi/errors/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/errors) [![Slack Status](https://slackin.goswagger.io/badge.svg)](https://slackin.goswagger.io) +# OpenAPI errors +[![Build Status](https://travis-ci.org/go-openapi/errors.svg?branch=master)](https://travis-ci.org/go-openapi/errors) +[![codecov](https://codecov.io/gh/go-openapi/errors/branch/master/graph/badge.svg)](https://codecov.io/gh/go-openapi/errors) +[![Slack Status](https://slackin.goswagger.io/badge.svg)](https://slackin.goswagger.io) [![license](http://img.shields.io/badge/license-Apache%20v2-orange.svg)](https://raw.githubusercontent.com/go-openapi/errors/master/LICENSE) -[![GoDoc](https://godoc.org/github.com/go-openapi/errors?status.svg)](http://godoc.org/github.com/go-openapi/errors) +[![Go Reference](https://pkg.go.dev/badge/github.com/go-openapi/errors.svg)](https://pkg.go.dev/github.com/go-openapi/errors) [![GolangCI](https://golangci.com/badges/github.com/go-openapi/errors.svg)](https://golangci.com) [![Go Report Card](https://goreportcard.com/badge/github.com/go-openapi/errors)](https://goreportcard.com/report/github.com/go-openapi/errors) diff --git a/vendor/github.com/go-openapi/errors/api.go b/vendor/github.com/go-openapi/errors/api.go index 7667cee76c..854d6eec1e 100644 --- a/vendor/github.com/go-openapi/errors/api.go +++ b/vendor/github.com/go-openapi/errors/api.go @@ -44,6 +44,14 @@ func (a *apiError) Code() int32 { return a.code } +// MarshalJSON implements the JSON encoding interface +func (a apiError) MarshalJSON() ([]byte, error) { + return json.Marshal(map[string]interface{}{ + "code": a.code, + "message": a.message, + }) +} + // New creates a new API error with a code and a message func New(code int32, message string, args ...interface{}) Error { if len(args) > 0 { @@ -81,6 +89,15 @@ func (m *MethodNotAllowedError) Code() int32 { return m.code } +// MarshalJSON implements the JSON encoding interface +func (m MethodNotAllowedError) MarshalJSON() ([]byte, error) { + return json.Marshal(map[string]interface{}{ + "code": m.code, + "message": m.message, + "allowed": m.Allowed, + }) +} + func errorAsJSON(err Error) []byte { b, _ := json.Marshal(struct { Code int32 `json:"code"` diff --git a/vendor/github.com/go-openapi/errors/headers.go b/vendor/github.com/go-openapi/errors/headers.go index 0360c094ea..f7b8bf1fc8 100644 --- a/vendor/github.com/go-openapi/errors/headers.go +++ b/vendor/github.com/go-openapi/errors/headers.go @@ -15,6 +15,7 @@ package errors import ( + "encoding/json" "fmt" "net/http" ) @@ -38,6 +39,18 @@ func (e *Validation) Code() int32 { return e.code } +// MarshalJSON implements the JSON encoding interface +func (e Validation) MarshalJSON() ([]byte, error) { + return json.Marshal(map[string]interface{}{ + "code": e.code, + "message": e.message, + "in": e.In, + "name": e.Name, + "value": e.Value, + "values": e.Values, + }) +} + // ValidateName produces an error message name for an aliased property func (e *Validation) ValidateName(name string) *Validation { if e.Name == "" && name != "" { diff --git a/vendor/github.com/go-openapi/errors/middleware.go b/vendor/github.com/go-openapi/errors/middleware.go index 6390d4636a..c26ad484eb 100644 --- a/vendor/github.com/go-openapi/errors/middleware.go +++ b/vendor/github.com/go-openapi/errors/middleware.go @@ -23,9 +23,9 @@ import ( // APIVerificationFailed is an error that contains all the missing info for a mismatched section // between the api registrations and the api spec type APIVerificationFailed struct { - Section string - MissingSpecification []string - MissingRegistration []string + Section string `json:"section,omitempty"` + MissingSpecification []string `json:"missingSpecification,omitempty"` + MissingRegistration []string `json:"missingRegistration,omitempty"` } // diff --git a/vendor/github.com/go-openapi/errors/parsing.go b/vendor/github.com/go-openapi/errors/parsing.go index 0f96ce2094..5096e1ea7b 100644 --- a/vendor/github.com/go-openapi/errors/parsing.go +++ b/vendor/github.com/go-openapi/errors/parsing.go @@ -14,7 +14,10 @@ package errors -import "fmt" +import ( + "encoding/json" + "fmt" +) // ParseError represents a parsing error type ParseError struct { @@ -35,6 +38,22 @@ func (e *ParseError) Code() int32 { return e.code } +// MarshalJSON implements the JSON encoding interface +func (e ParseError) MarshalJSON() ([]byte, error) { + var reason string + if e.Reason != nil { + reason = e.Reason.Error() + } + return json.Marshal(map[string]interface{}{ + "code": e.code, + "message": e.message, + "in": e.In, + "name": e.Name, + "value": e.Value, + "reason": reason, + }) +} + const ( parseErrorTemplContent = `parsing %s %s from %q failed, because %s` parseErrorTemplContentNoIn = `parsing %s from %q failed, because %s` diff --git a/vendor/github.com/go-openapi/errors/schema.go b/vendor/github.com/go-openapi/errors/schema.go index f4a7d4ac23..bf335cb2fb 100644 --- a/vendor/github.com/go-openapi/errors/schema.go +++ b/vendor/github.com/go-openapi/errors/schema.go @@ -15,6 +15,7 @@ package errors import ( + "encoding/json" "fmt" "strings" ) @@ -119,6 +120,15 @@ func (c *CompositeError) Error() string { return c.message } +// MarshalJSON implements the JSON encoding interface +func (c CompositeError) MarshalJSON() ([]byte, error) { + return json.Marshal(map[string]interface{}{ + "code": c.code, + "message": c.message, + "errors": c.Errors, + }) +} + // CompositeValidationError an error to wrap a bunch of other errors func CompositeValidationError(errors ...error) *CompositeError { return &CompositeError{ diff --git a/vendor/github.com/go-openapi/runtime/.golangci.yml b/vendor/github.com/go-openapi/runtime/.golangci.yml new file mode 100644 index 0000000000..71629d4ddd --- /dev/null +++ b/vendor/github.com/go-openapi/runtime/.golangci.yml @@ -0,0 +1,42 @@ +linters-settings: + govet: + check-shadowing: true + golint: + min-confidence: 0 + gocyclo: + min-complexity: 30 + maligned: + suggest-new: true + dupl: + threshold: 100 + goconst: + min-len: 2 + min-occurrences: 4 +linters: + enable-all: true + disable: + - maligned + - lll + - gochecknoglobals + - godox + - gocognit + - whitespace + - wsl + - funlen + - gochecknoglobals + - gochecknoinits + - scopelint + - wrapcheck + - exhaustivestruct + - exhaustive + - nlreturn + - testpackage + - gci + - gofumpt + - goerr113 + - gomnd + - tparallel + - nestif + - godot + - errorlint + - noctx diff --git a/vendor/github.com/go-openapi/runtime/.travis.yml b/vendor/github.com/go-openapi/runtime/.travis.yml index e36276ab3f..78cdc892fa 100644 --- a/vendor/github.com/go-openapi/runtime/.travis.yml +++ b/vendor/github.com/go-openapi/runtime/.travis.yml @@ -1,10 +1,19 @@ after_success: - bash <(curl -s https://codecov.io/bash) go: -- 1.13.x - 1.14.x +- 1.x install: - GO111MODULE=off go get -u gotest.tools/gotestsum +jobs: + include: + # include linting job, but only for latest go version and amd64 arch + - go: 1.x + arch: amd64 + install: + go get github.com/golangci/golangci-lint/cmd/golangci-lint + script: + - golangci-lint run --new-from-rev master language: go notifications: slack: diff --git a/vendor/github.com/go-openapi/runtime/client/opentracing.go b/vendor/github.com/go-openapi/runtime/client/opentracing.go new file mode 100644 index 0000000000..87e0753ac9 --- /dev/null +++ b/vendor/github.com/go-openapi/runtime/client/opentracing.go @@ -0,0 +1,98 @@ +package client + +import ( + "net/http" + "regexp" + "strings" + + "github.com/go-openapi/strfmt" + "github.com/opentracing/opentracing-go" + "github.com/opentracing/opentracing-go/ext" + "github.com/opentracing/opentracing-go/log" + + "github.com/go-openapi/runtime" +) + +type tracingTransport struct { + transport runtime.ClientTransport + host string + opts []opentracing.StartSpanOption +} + +func newOpenTracingTransport(transport runtime.ClientTransport, host string, opts []opentracing.StartSpanOption, +) runtime.ClientTransport { + return &tracingTransport{ + transport: transport, + host: host, + opts: opts, + } +} + +func (t *tracingTransport) Submit(op *runtime.ClientOperation) (interface{}, error) { + authInfo := op.AuthInfo + reader := op.Reader + + var span opentracing.Span + defer func() { + if span != nil { + span.Finish() + } + }() + + op.AuthInfo = runtime.ClientAuthInfoWriterFunc(func(req runtime.ClientRequest, reg strfmt.Registry) error { + span = createClientSpan(op, req.GetHeaderParams(), t.host, t.opts) + return authInfo.AuthenticateRequest(req, reg) + }) + + op.Reader = runtime.ClientResponseReaderFunc(func(response runtime.ClientResponse, consumer runtime.Consumer) (interface{}, error) { + if span != nil { + code := response.Code() + ext.HTTPStatusCode.Set(span, uint16(code)) + if code >= 400 { + ext.Error.Set(span, true) + } + } + return reader.ReadResponse(response, consumer) + }) + + submit, err := t.transport.Submit(op) + if err != nil && span != nil { + ext.Error.Set(span, true) + span.LogFields(log.Error(err)) + } + return submit, err +} + +func createClientSpan(op *runtime.ClientOperation, header http.Header, host string, + opts []opentracing.StartSpanOption) opentracing.Span { + ctx := op.Context + span := opentracing.SpanFromContext(ctx) + + if span != nil { + opts = append(opts, ext.SpanKindRPCClient) + span, _ = opentracing.StartSpanFromContextWithTracer( + ctx, span.Tracer(), toSnakeCase(op.ID), opts...) + + ext.Component.Set(span, "go-openapi") + ext.PeerHostname.Set(span, host) + span.SetTag("http.path", op.PathPattern) + ext.HTTPMethod.Set(span, op.Method) + + _ = span.Tracer().Inject( + span.Context(), + opentracing.HTTPHeaders, + opentracing.HTTPHeadersCarrier(header)) + + return span + } + return nil +} + +var matchFirstCap = regexp.MustCompile("(.)([A-Z][a-z]+)") +var matchAllCap = regexp.MustCompile("([a-z0-9])([A-Z])") + +func toSnakeCase(str string) string { + snake := matchFirstCap.ReplaceAllString(str, "${1}_${2}") + snake = matchAllCap.ReplaceAllString(snake, "${1}_${2}") + return strings.ToLower(snake) +} diff --git a/vendor/github.com/go-openapi/runtime/client/runtime.go b/vendor/github.com/go-openapi/runtime/client/runtime.go index 083d751e3c..f57c4420cf 100644 --- a/vendor/github.com/go-openapi/runtime/client/runtime.go +++ b/vendor/github.com/go-openapi/runtime/client/runtime.go @@ -32,6 +32,7 @@ import ( "time" "github.com/go-openapi/strfmt" + "github.com/opentracing/opentracing-go" "github.com/go-openapi/runtime" "github.com/go-openapi/runtime/logger" @@ -81,7 +82,7 @@ type TLSClientOptions struct { ServerName string // InsecureSkipVerify controls whether the certificate chain and hostname presented - // by the server are validated. If false, any certificate is accepted. + // by the server are validated. If true, any certificate is accepted. InsecureSkipVerify bool // VerifyPeerCertificate, if not nil, is called after normal @@ -292,6 +293,14 @@ func NewWithClient(host, basePath string, schemes []string, client *http.Client) return rt } +// WithOpenTracing adds opentracing support to the provided runtime. +// A new client span is created for each request. +// If the context of the client operation does not contain an active span, no span is created. +// The provided opts are applied to each spans - for example to add global tags. +func (r *Runtime) WithOpenTracing(opts ...opentracing.StartSpanOption) runtime.ClientTransport { + return newOpenTracingTransport(r, r.Host, opts) +} + func (r *Runtime) pickScheme(schemes []string) string { if v := r.selectScheme(r.schemes); v != "" { return v diff --git a/vendor/github.com/go-openapi/runtime/client_request.go b/vendor/github.com/go-openapi/runtime/client_request.go index 6215e0a1c1..3efda34821 100644 --- a/vendor/github.com/go-openapi/runtime/client_request.go +++ b/vendor/github.com/go-openapi/runtime/client_request.go @@ -101,3 +101,53 @@ func (n *namedReadCloser) Read(p []byte) (int, error) { func (n *namedReadCloser) Name() string { return n.name } + +type TestClientRequest struct { + Headers http.Header + Body interface{} +} + +func (t *TestClientRequest) SetHeaderParam(name string, values ...string) error { + if t.Headers == nil { + t.Headers = make(http.Header) + } + t.Headers.Set(name, values[0]) + return nil +} + +func (t *TestClientRequest) SetQueryParam(_ string, _ ...string) error { return nil } + +func (t *TestClientRequest) SetFormParam(_ string, _ ...string) error { return nil } + +func (t *TestClientRequest) SetPathParam(_ string, _ string) error { return nil } + +func (t *TestClientRequest) SetFileParam(_ string, _ ...NamedReadCloser) error { return nil } + +func (t *TestClientRequest) SetBodyParam(body interface{}) error { + t.Body = body + return nil +} + +func (t *TestClientRequest) SetTimeout(time.Duration) error { + return nil +} + +func (t *TestClientRequest) GetQueryParams() url.Values { return nil } + +func (t *TestClientRequest) GetMethod() string { return "" } + +func (t *TestClientRequest) GetPath() string { return "" } + +func (t *TestClientRequest) GetBody() []byte { return nil } + +func (t *TestClientRequest) GetBodyParam() interface{} { + return t.Body +} + +func (t *TestClientRequest) GetFileParam() map[string][]NamedReadCloser { + return nil +} + +func (t *TestClientRequest) GetHeaderParams() http.Header { + return t.Headers +} diff --git a/vendor/github.com/go-openapi/runtime/go.mod b/vendor/github.com/go-openapi/runtime/go.mod index 3effc2817e..6fcf0fe65c 100644 --- a/vendor/github.com/go-openapi/runtime/go.mod +++ b/vendor/github.com/go-openapi/runtime/go.mod @@ -9,6 +9,7 @@ require ( github.com/go-openapi/strfmt v0.19.5 github.com/go-openapi/swag v0.19.9 github.com/go-openapi/validate v0.19.10 + github.com/opentracing/opentracing-go v1.2.0 github.com/stretchr/testify v1.6.1 gopkg.in/yaml.v2 v2.3.0 gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776 // indirect diff --git a/vendor/github.com/go-openapi/runtime/go.sum b/vendor/github.com/go-openapi/runtime/go.sum index 5cadebb499..27801d87ff 100644 --- a/vendor/github.com/go-openapi/runtime/go.sum +++ b/vendor/github.com/go-openapi/runtime/go.sum @@ -168,6 +168,8 @@ github.com/mitchellh/mapstructure v1.3.2/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= +github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-toml v1.4.0/go.mod h1:PN7xzY2wHTK0K9p34ErDQMlFxa51Fk0OUruD3k1mMwo= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= diff --git a/vendor/github.com/go-openapi/runtime/middleware/router.go b/vendor/github.com/go-openapi/runtime/middleware/router.go index 02768bade2..5052031c8d 100644 --- a/vendor/github.com/go-openapi/runtime/middleware/router.go +++ b/vendor/github.com/go-openapi/runtime/middleware/router.go @@ -22,6 +22,7 @@ import ( "strings" "github.com/go-openapi/runtime/security" + "github.com/go-openapi/swag" "github.com/go-openapi/analysis" "github.com/go-openapi/errors" @@ -418,6 +419,15 @@ func (d *defaultRouteBuilder) AddRoute(method, path string, operation *spec.Oper produces := d.analyzer.ProducesFor(operation) parameters := d.analyzer.ParamsFor(method, strings.TrimPrefix(path, bp)) + // add API defaults if not part of the spec + if defConsumes := d.api.DefaultConsumes(); defConsumes != "" && !swag.ContainsStringsCI(consumes, defConsumes) { + consumes = append(consumes, defConsumes) + } + + if defProduces := d.api.DefaultProduces(); defProduces != "" && !swag.ContainsStringsCI(produces, defProduces) { + produces = append(produces, defProduces) + } + record := denco.NewRecord(pathConverter.ReplaceAllString(path, ":$1"), &routeEntry{ BasePath: bp, PathPattern: path, diff --git a/vendor/github.com/prometheus/alertmanager/api/v2/client/alert/alert_client.go b/vendor/github.com/prometheus/alertmanager/api/v2/client/alert/alert_client.go index 7d299c45ba..24cbe8c950 100644 --- a/vendor/github.com/prometheus/alertmanager/api/v2/client/alert/alert_client.go +++ b/vendor/github.com/prometheus/alertmanager/api/v2/client/alert/alert_client.go @@ -23,12 +23,11 @@ import ( "fmt" "github.com/go-openapi/runtime" - - strfmt "github.com/go-openapi/strfmt" + "github.com/go-openapi/strfmt" ) // New creates a new alert API client. -func New(transport runtime.ClientTransport, formats strfmt.Registry) *Client { +func New(transport runtime.ClientTransport, formats strfmt.Registry) ClientService { return &Client{transport: transport, formats: formats} } @@ -40,8 +39,17 @@ type Client struct { formats strfmt.Registry } +// ClientService is the interface for Client methods +type ClientService interface { + GetAlerts(params *GetAlertsParams) (*GetAlertsOK, error) + + PostAlerts(params *PostAlertsParams) (*PostAlertsOK, error) + + SetTransport(transport runtime.ClientTransport) +} + /* -GetAlerts Get a list of alerts + GetAlerts Get a list of alerts */ func (a *Client) GetAlerts(params *GetAlertsParams) (*GetAlertsOK, error) { // TODO: Validate the params before sending @@ -75,7 +83,7 @@ func (a *Client) GetAlerts(params *GetAlertsParams) (*GetAlertsOK, error) { } /* -PostAlerts Create new Alerts + PostAlerts Create new Alerts */ func (a *Client) PostAlerts(params *PostAlertsParams) (*PostAlertsOK, error) { // TODO: Validate the params before sending diff --git a/vendor/github.com/prometheus/alertmanager/api/v2/client/alert/get_alerts_parameters.go b/vendor/github.com/prometheus/alertmanager/api/v2/client/alert/get_alerts_parameters.go index cba0387c85..de05f6889e 100644 --- a/vendor/github.com/prometheus/alertmanager/api/v2/client/alert/get_alerts_parameters.go +++ b/vendor/github.com/prometheus/alertmanager/api/v2/client/alert/get_alerts_parameters.go @@ -27,9 +27,8 @@ import ( "github.com/go-openapi/errors" "github.com/go-openapi/runtime" cr "github.com/go-openapi/runtime/client" + "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - - strfmt "github.com/go-openapi/strfmt" ) // NewGetAlertsParams creates a new GetAlertsParams object diff --git a/vendor/github.com/prometheus/alertmanager/api/v2/client/alert/get_alerts_responses.go b/vendor/github.com/prometheus/alertmanager/api/v2/client/alert/get_alerts_responses.go index 6a302f0278..0fd6e282be 100644 --- a/vendor/github.com/prometheus/alertmanager/api/v2/client/alert/get_alerts_responses.go +++ b/vendor/github.com/prometheus/alertmanager/api/v2/client/alert/get_alerts_responses.go @@ -24,10 +24,9 @@ import ( "io" "github.com/go-openapi/runtime" + "github.com/go-openapi/strfmt" - strfmt "github.com/go-openapi/strfmt" - - models "github.com/prometheus/alertmanager/api/v2/models" + "github.com/prometheus/alertmanager/api/v2/models" ) // GetAlertsReader is a Reader for the GetAlerts structure. diff --git a/vendor/github.com/prometheus/alertmanager/api/v2/client/alert/post_alerts_parameters.go b/vendor/github.com/prometheus/alertmanager/api/v2/client/alert/post_alerts_parameters.go index de1b021a2f..3e5c99805a 100644 --- a/vendor/github.com/prometheus/alertmanager/api/v2/client/alert/post_alerts_parameters.go +++ b/vendor/github.com/prometheus/alertmanager/api/v2/client/alert/post_alerts_parameters.go @@ -27,10 +27,9 @@ import ( "github.com/go-openapi/errors" "github.com/go-openapi/runtime" cr "github.com/go-openapi/runtime/client" + "github.com/go-openapi/strfmt" - strfmt "github.com/go-openapi/strfmt" - - models "github.com/prometheus/alertmanager/api/v2/models" + "github.com/prometheus/alertmanager/api/v2/models" ) // NewPostAlertsParams creates a new PostAlertsParams object diff --git a/vendor/github.com/prometheus/alertmanager/api/v2/client/alert/post_alerts_responses.go b/vendor/github.com/prometheus/alertmanager/api/v2/client/alert/post_alerts_responses.go index ec7307bbd1..693efd5b19 100644 --- a/vendor/github.com/prometheus/alertmanager/api/v2/client/alert/post_alerts_responses.go +++ b/vendor/github.com/prometheus/alertmanager/api/v2/client/alert/post_alerts_responses.go @@ -24,8 +24,7 @@ import ( "io" "github.com/go-openapi/runtime" - - strfmt "github.com/go-openapi/strfmt" + "github.com/go-openapi/strfmt" ) // PostAlertsReader is a Reader for the PostAlerts structure. diff --git a/vendor/github.com/prometheus/alertmanager/api/v2/client/alertgroup/alertgroup_client.go b/vendor/github.com/prometheus/alertmanager/api/v2/client/alertgroup/alertgroup_client.go index 0ec0d1815c..f7c4a1faa7 100644 --- a/vendor/github.com/prometheus/alertmanager/api/v2/client/alertgroup/alertgroup_client.go +++ b/vendor/github.com/prometheus/alertmanager/api/v2/client/alertgroup/alertgroup_client.go @@ -23,12 +23,11 @@ import ( "fmt" "github.com/go-openapi/runtime" - - strfmt "github.com/go-openapi/strfmt" + "github.com/go-openapi/strfmt" ) // New creates a new alertgroup API client. -func New(transport runtime.ClientTransport, formats strfmt.Registry) *Client { +func New(transport runtime.ClientTransport, formats strfmt.Registry) ClientService { return &Client{transport: transport, formats: formats} } @@ -40,8 +39,15 @@ type Client struct { formats strfmt.Registry } +// ClientService is the interface for Client methods +type ClientService interface { + GetAlertGroups(params *GetAlertGroupsParams) (*GetAlertGroupsOK, error) + + SetTransport(transport runtime.ClientTransport) +} + /* -GetAlertGroups Get a list of alert groups + GetAlertGroups Get a list of alert groups */ func (a *Client) GetAlertGroups(params *GetAlertGroupsParams) (*GetAlertGroupsOK, error) { // TODO: Validate the params before sending diff --git a/vendor/github.com/prometheus/alertmanager/api/v2/client/alertgroup/get_alert_groups_parameters.go b/vendor/github.com/prometheus/alertmanager/api/v2/client/alertgroup/get_alert_groups_parameters.go index 2c59f41604..b76d0b1b94 100644 --- a/vendor/github.com/prometheus/alertmanager/api/v2/client/alertgroup/get_alert_groups_parameters.go +++ b/vendor/github.com/prometheus/alertmanager/api/v2/client/alertgroup/get_alert_groups_parameters.go @@ -27,9 +27,8 @@ import ( "github.com/go-openapi/errors" "github.com/go-openapi/runtime" cr "github.com/go-openapi/runtime/client" + "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - - strfmt "github.com/go-openapi/strfmt" ) // NewGetAlertGroupsParams creates a new GetAlertGroupsParams object diff --git a/vendor/github.com/prometheus/alertmanager/api/v2/client/alertgroup/get_alert_groups_responses.go b/vendor/github.com/prometheus/alertmanager/api/v2/client/alertgroup/get_alert_groups_responses.go index 2140edbf9d..6c686ef3ee 100644 --- a/vendor/github.com/prometheus/alertmanager/api/v2/client/alertgroup/get_alert_groups_responses.go +++ b/vendor/github.com/prometheus/alertmanager/api/v2/client/alertgroup/get_alert_groups_responses.go @@ -24,10 +24,9 @@ import ( "io" "github.com/go-openapi/runtime" + "github.com/go-openapi/strfmt" - strfmt "github.com/go-openapi/strfmt" - - models "github.com/prometheus/alertmanager/api/v2/models" + "github.com/prometheus/alertmanager/api/v2/models" ) // GetAlertGroupsReader is a Reader for the GetAlertGroups structure. diff --git a/vendor/github.com/prometheus/alertmanager/api/v2/client/alertmanager_client.go b/vendor/github.com/prometheus/alertmanager/api/v2/client/alertmanager_client.go index d30ab2a86d..23313fdd79 100644 --- a/vendor/github.com/prometheus/alertmanager/api/v2/client/alertmanager_client.go +++ b/vendor/github.com/prometheus/alertmanager/api/v2/client/alertmanager_client.go @@ -22,8 +22,7 @@ package client import ( "github.com/go-openapi/runtime" httptransport "github.com/go-openapi/runtime/client" - - strfmt "github.com/go-openapi/strfmt" + "github.com/go-openapi/strfmt" "github.com/prometheus/alertmanager/api/v2/client/alert" "github.com/prometheus/alertmanager/api/v2/client/alertgroup" @@ -74,17 +73,11 @@ func New(transport runtime.ClientTransport, formats strfmt.Registry) *Alertmanag cli := new(Alertmanager) cli.Transport = transport - cli.Alert = alert.New(transport, formats) - cli.Alertgroup = alertgroup.New(transport, formats) - cli.General = general.New(transport, formats) - cli.Receiver = receiver.New(transport, formats) - cli.Silence = silence.New(transport, formats) - return cli } @@ -129,15 +122,15 @@ func (cfg *TransportConfig) WithSchemes(schemes []string) *TransportConfig { // Alertmanager is a client for alertmanager type Alertmanager struct { - Alert *alert.Client + Alert alert.ClientService - Alertgroup *alertgroup.Client + Alertgroup alertgroup.ClientService - General *general.Client + General general.ClientService - Receiver *receiver.Client + Receiver receiver.ClientService - Silence *silence.Client + Silence silence.ClientService Transport runtime.ClientTransport } @@ -145,15 +138,9 @@ type Alertmanager struct { // SetTransport changes the transport on the client and all its subresources func (c *Alertmanager) SetTransport(transport runtime.ClientTransport) { c.Transport = transport - c.Alert.SetTransport(transport) - c.Alertgroup.SetTransport(transport) - c.General.SetTransport(transport) - c.Receiver.SetTransport(transport) - c.Silence.SetTransport(transport) - } diff --git a/vendor/github.com/prometheus/alertmanager/api/v2/client/general/general_client.go b/vendor/github.com/prometheus/alertmanager/api/v2/client/general/general_client.go index 36808e611c..35304b1790 100644 --- a/vendor/github.com/prometheus/alertmanager/api/v2/client/general/general_client.go +++ b/vendor/github.com/prometheus/alertmanager/api/v2/client/general/general_client.go @@ -23,12 +23,11 @@ import ( "fmt" "github.com/go-openapi/runtime" - - strfmt "github.com/go-openapi/strfmt" + "github.com/go-openapi/strfmt" ) // New creates a new general API client. -func New(transport runtime.ClientTransport, formats strfmt.Registry) *Client { +func New(transport runtime.ClientTransport, formats strfmt.Registry) ClientService { return &Client{transport: transport, formats: formats} } @@ -40,8 +39,15 @@ type Client struct { formats strfmt.Registry } +// ClientService is the interface for Client methods +type ClientService interface { + GetStatus(params *GetStatusParams) (*GetStatusOK, error) + + SetTransport(transport runtime.ClientTransport) +} + /* -GetStatus Get current status of an Alertmanager instance and its cluster + GetStatus Get current status of an Alertmanager instance and its cluster */ func (a *Client) GetStatus(params *GetStatusParams) (*GetStatusOK, error) { // TODO: Validate the params before sending diff --git a/vendor/github.com/prometheus/alertmanager/api/v2/client/general/get_status_parameters.go b/vendor/github.com/prometheus/alertmanager/api/v2/client/general/get_status_parameters.go index f8f3e2b9c3..814e8b31ab 100644 --- a/vendor/github.com/prometheus/alertmanager/api/v2/client/general/get_status_parameters.go +++ b/vendor/github.com/prometheus/alertmanager/api/v2/client/general/get_status_parameters.go @@ -27,8 +27,7 @@ import ( "github.com/go-openapi/errors" "github.com/go-openapi/runtime" cr "github.com/go-openapi/runtime/client" - - strfmt "github.com/go-openapi/strfmt" + "github.com/go-openapi/strfmt" ) // NewGetStatusParams creates a new GetStatusParams object diff --git a/vendor/github.com/prometheus/alertmanager/api/v2/client/general/get_status_responses.go b/vendor/github.com/prometheus/alertmanager/api/v2/client/general/get_status_responses.go index c27be6fec9..d457ccc92b 100644 --- a/vendor/github.com/prometheus/alertmanager/api/v2/client/general/get_status_responses.go +++ b/vendor/github.com/prometheus/alertmanager/api/v2/client/general/get_status_responses.go @@ -24,10 +24,9 @@ import ( "io" "github.com/go-openapi/runtime" + "github.com/go-openapi/strfmt" - strfmt "github.com/go-openapi/strfmt" - - models "github.com/prometheus/alertmanager/api/v2/models" + "github.com/prometheus/alertmanager/api/v2/models" ) // GetStatusReader is a Reader for the GetStatus structure. diff --git a/vendor/github.com/prometheus/alertmanager/api/v2/client/receiver/get_receivers_parameters.go b/vendor/github.com/prometheus/alertmanager/api/v2/client/receiver/get_receivers_parameters.go index 99b478a2f3..090b9e4283 100644 --- a/vendor/github.com/prometheus/alertmanager/api/v2/client/receiver/get_receivers_parameters.go +++ b/vendor/github.com/prometheus/alertmanager/api/v2/client/receiver/get_receivers_parameters.go @@ -27,8 +27,7 @@ import ( "github.com/go-openapi/errors" "github.com/go-openapi/runtime" cr "github.com/go-openapi/runtime/client" - - strfmt "github.com/go-openapi/strfmt" + "github.com/go-openapi/strfmt" ) // NewGetReceiversParams creates a new GetReceiversParams object diff --git a/vendor/github.com/prometheus/alertmanager/api/v2/client/receiver/get_receivers_responses.go b/vendor/github.com/prometheus/alertmanager/api/v2/client/receiver/get_receivers_responses.go index 17aa87132f..3bc473d867 100644 --- a/vendor/github.com/prometheus/alertmanager/api/v2/client/receiver/get_receivers_responses.go +++ b/vendor/github.com/prometheus/alertmanager/api/v2/client/receiver/get_receivers_responses.go @@ -24,10 +24,9 @@ import ( "io" "github.com/go-openapi/runtime" + "github.com/go-openapi/strfmt" - strfmt "github.com/go-openapi/strfmt" - - models "github.com/prometheus/alertmanager/api/v2/models" + "github.com/prometheus/alertmanager/api/v2/models" ) // GetReceiversReader is a Reader for the GetReceivers structure. diff --git a/vendor/github.com/prometheus/alertmanager/api/v2/client/receiver/receiver_client.go b/vendor/github.com/prometheus/alertmanager/api/v2/client/receiver/receiver_client.go index 0a9967e3ab..1cda82018c 100644 --- a/vendor/github.com/prometheus/alertmanager/api/v2/client/receiver/receiver_client.go +++ b/vendor/github.com/prometheus/alertmanager/api/v2/client/receiver/receiver_client.go @@ -23,12 +23,11 @@ import ( "fmt" "github.com/go-openapi/runtime" - - strfmt "github.com/go-openapi/strfmt" + "github.com/go-openapi/strfmt" ) // New creates a new receiver API client. -func New(transport runtime.ClientTransport, formats strfmt.Registry) *Client { +func New(transport runtime.ClientTransport, formats strfmt.Registry) ClientService { return &Client{transport: transport, formats: formats} } @@ -40,8 +39,15 @@ type Client struct { formats strfmt.Registry } +// ClientService is the interface for Client methods +type ClientService interface { + GetReceivers(params *GetReceiversParams) (*GetReceiversOK, error) + + SetTransport(transport runtime.ClientTransport) +} + /* -GetReceivers Get list of all receivers (name of notification integrations) + GetReceivers Get list of all receivers (name of notification integrations) */ func (a *Client) GetReceivers(params *GetReceiversParams) (*GetReceiversOK, error) { // TODO: Validate the params before sending diff --git a/vendor/github.com/prometheus/alertmanager/api/v2/client/silence/delete_silence_parameters.go b/vendor/github.com/prometheus/alertmanager/api/v2/client/silence/delete_silence_parameters.go index 98914082b4..2b4e9b8c83 100644 --- a/vendor/github.com/prometheus/alertmanager/api/v2/client/silence/delete_silence_parameters.go +++ b/vendor/github.com/prometheus/alertmanager/api/v2/client/silence/delete_silence_parameters.go @@ -27,8 +27,7 @@ import ( "github.com/go-openapi/errors" "github.com/go-openapi/runtime" cr "github.com/go-openapi/runtime/client" - - strfmt "github.com/go-openapi/strfmt" + "github.com/go-openapi/strfmt" ) // NewDeleteSilenceParams creates a new DeleteSilenceParams object diff --git a/vendor/github.com/prometheus/alertmanager/api/v2/client/silence/delete_silence_responses.go b/vendor/github.com/prometheus/alertmanager/api/v2/client/silence/delete_silence_responses.go index 53bd3cb6c0..848c53dc03 100644 --- a/vendor/github.com/prometheus/alertmanager/api/v2/client/silence/delete_silence_responses.go +++ b/vendor/github.com/prometheus/alertmanager/api/v2/client/silence/delete_silence_responses.go @@ -24,8 +24,7 @@ import ( "io" "github.com/go-openapi/runtime" - - strfmt "github.com/go-openapi/strfmt" + "github.com/go-openapi/strfmt" ) // DeleteSilenceReader is a Reader for the DeleteSilence structure. diff --git a/vendor/github.com/prometheus/alertmanager/api/v2/client/silence/get_silence_parameters.go b/vendor/github.com/prometheus/alertmanager/api/v2/client/silence/get_silence_parameters.go index f083e45a0d..e8cb7f00e2 100644 --- a/vendor/github.com/prometheus/alertmanager/api/v2/client/silence/get_silence_parameters.go +++ b/vendor/github.com/prometheus/alertmanager/api/v2/client/silence/get_silence_parameters.go @@ -27,8 +27,7 @@ import ( "github.com/go-openapi/errors" "github.com/go-openapi/runtime" cr "github.com/go-openapi/runtime/client" - - strfmt "github.com/go-openapi/strfmt" + "github.com/go-openapi/strfmt" ) // NewGetSilenceParams creates a new GetSilenceParams object diff --git a/vendor/github.com/prometheus/alertmanager/api/v2/client/silence/get_silence_responses.go b/vendor/github.com/prometheus/alertmanager/api/v2/client/silence/get_silence_responses.go index 693e226fd5..7fc3f53da6 100644 --- a/vendor/github.com/prometheus/alertmanager/api/v2/client/silence/get_silence_responses.go +++ b/vendor/github.com/prometheus/alertmanager/api/v2/client/silence/get_silence_responses.go @@ -24,10 +24,9 @@ import ( "io" "github.com/go-openapi/runtime" + "github.com/go-openapi/strfmt" - strfmt "github.com/go-openapi/strfmt" - - models "github.com/prometheus/alertmanager/api/v2/models" + "github.com/prometheus/alertmanager/api/v2/models" ) // GetSilenceReader is a Reader for the GetSilence structure. diff --git a/vendor/github.com/prometheus/alertmanager/api/v2/client/silence/get_silences_parameters.go b/vendor/github.com/prometheus/alertmanager/api/v2/client/silence/get_silences_parameters.go index e4e26771d0..940fd8e9ef 100644 --- a/vendor/github.com/prometheus/alertmanager/api/v2/client/silence/get_silences_parameters.go +++ b/vendor/github.com/prometheus/alertmanager/api/v2/client/silence/get_silences_parameters.go @@ -27,9 +27,8 @@ import ( "github.com/go-openapi/errors" "github.com/go-openapi/runtime" cr "github.com/go-openapi/runtime/client" + "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - - strfmt "github.com/go-openapi/strfmt" ) // NewGetSilencesParams creates a new GetSilencesParams object diff --git a/vendor/github.com/prometheus/alertmanager/api/v2/client/silence/get_silences_responses.go b/vendor/github.com/prometheus/alertmanager/api/v2/client/silence/get_silences_responses.go index 920a6ce937..819a242793 100644 --- a/vendor/github.com/prometheus/alertmanager/api/v2/client/silence/get_silences_responses.go +++ b/vendor/github.com/prometheus/alertmanager/api/v2/client/silence/get_silences_responses.go @@ -24,10 +24,9 @@ import ( "io" "github.com/go-openapi/runtime" + "github.com/go-openapi/strfmt" - strfmt "github.com/go-openapi/strfmt" - - models "github.com/prometheus/alertmanager/api/v2/models" + "github.com/prometheus/alertmanager/api/v2/models" ) // GetSilencesReader is a Reader for the GetSilences structure. diff --git a/vendor/github.com/prometheus/alertmanager/api/v2/client/silence/post_silences_parameters.go b/vendor/github.com/prometheus/alertmanager/api/v2/client/silence/post_silences_parameters.go index de117fd9af..5fadff8e2e 100644 --- a/vendor/github.com/prometheus/alertmanager/api/v2/client/silence/post_silences_parameters.go +++ b/vendor/github.com/prometheus/alertmanager/api/v2/client/silence/post_silences_parameters.go @@ -27,10 +27,9 @@ import ( "github.com/go-openapi/errors" "github.com/go-openapi/runtime" cr "github.com/go-openapi/runtime/client" + "github.com/go-openapi/strfmt" - strfmt "github.com/go-openapi/strfmt" - - models "github.com/prometheus/alertmanager/api/v2/models" + "github.com/prometheus/alertmanager/api/v2/models" ) // NewPostSilencesParams creates a new PostSilencesParams object diff --git a/vendor/github.com/prometheus/alertmanager/api/v2/client/silence/post_silences_responses.go b/vendor/github.com/prometheus/alertmanager/api/v2/client/silence/post_silences_responses.go index 3358f2e705..c71931f73a 100644 --- a/vendor/github.com/prometheus/alertmanager/api/v2/client/silence/post_silences_responses.go +++ b/vendor/github.com/prometheus/alertmanager/api/v2/client/silence/post_silences_responses.go @@ -24,9 +24,8 @@ import ( "io" "github.com/go-openapi/runtime" + "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" - - strfmt "github.com/go-openapi/strfmt" ) // PostSilencesReader is a Reader for the PostSilences structure. diff --git a/vendor/github.com/prometheus/alertmanager/api/v2/client/silence/silence_client.go b/vendor/github.com/prometheus/alertmanager/api/v2/client/silence/silence_client.go index 9d9721c68c..b601f9d8c9 100644 --- a/vendor/github.com/prometheus/alertmanager/api/v2/client/silence/silence_client.go +++ b/vendor/github.com/prometheus/alertmanager/api/v2/client/silence/silence_client.go @@ -23,12 +23,11 @@ import ( "fmt" "github.com/go-openapi/runtime" - - strfmt "github.com/go-openapi/strfmt" + "github.com/go-openapi/strfmt" ) // New creates a new silence API client. -func New(transport runtime.ClientTransport, formats strfmt.Registry) *Client { +func New(transport runtime.ClientTransport, formats strfmt.Registry) ClientService { return &Client{transport: transport, formats: formats} } @@ -40,8 +39,21 @@ type Client struct { formats strfmt.Registry } +// ClientService is the interface for Client methods +type ClientService interface { + DeleteSilence(params *DeleteSilenceParams) (*DeleteSilenceOK, error) + + GetSilence(params *GetSilenceParams) (*GetSilenceOK, error) + + GetSilences(params *GetSilencesParams) (*GetSilencesOK, error) + + PostSilences(params *PostSilencesParams) (*PostSilencesOK, error) + + SetTransport(transport runtime.ClientTransport) +} + /* -DeleteSilence Delete a silence by its ID + DeleteSilence Delete a silence by its ID */ func (a *Client) DeleteSilence(params *DeleteSilenceParams) (*DeleteSilenceOK, error) { // TODO: Validate the params before sending @@ -75,7 +87,7 @@ func (a *Client) DeleteSilence(params *DeleteSilenceParams) (*DeleteSilenceOK, e } /* -GetSilence Get a silence by its ID + GetSilence Get a silence by its ID */ func (a *Client) GetSilence(params *GetSilenceParams) (*GetSilenceOK, error) { // TODO: Validate the params before sending @@ -109,7 +121,7 @@ func (a *Client) GetSilence(params *GetSilenceParams) (*GetSilenceOK, error) { } /* -GetSilences Get a list of silences + GetSilences Get a list of silences */ func (a *Client) GetSilences(params *GetSilencesParams) (*GetSilencesOK, error) { // TODO: Validate the params before sending @@ -143,7 +155,7 @@ func (a *Client) GetSilences(params *GetSilencesParams) (*GetSilencesOK, error) } /* -PostSilences Post a new silence or update an existing one + PostSilences Post a new silence or update an existing one */ func (a *Client) PostSilences(params *PostSilencesParams) (*PostSilencesOK, error) { // TODO: Validate the params before sending diff --git a/vendor/github.com/prometheus/alertmanager/api/v2/models/alert.go b/vendor/github.com/prometheus/alertmanager/api/v2/models/alert.go index 832df76e41..1703075446 100644 --- a/vendor/github.com/prometheus/alertmanager/api/v2/models/alert.go +++ b/vendor/github.com/prometheus/alertmanager/api/v2/models/alert.go @@ -20,14 +20,14 @@ package models // Editing this file might prove futile when you re-run the swagger generate command import ( - strfmt "github.com/go-openapi/strfmt" - "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" "github.com/go-openapi/validate" ) // Alert alert +// // swagger:model alert type Alert struct { diff --git a/vendor/github.com/prometheus/alertmanager/api/v2/models/alert_group.go b/vendor/github.com/prometheus/alertmanager/api/v2/models/alert_group.go index 92a4b91826..3db729359d 100644 --- a/vendor/github.com/prometheus/alertmanager/api/v2/models/alert_group.go +++ b/vendor/github.com/prometheus/alertmanager/api/v2/models/alert_group.go @@ -22,14 +22,14 @@ package models import ( "strconv" - strfmt "github.com/go-openapi/strfmt" - "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" "github.com/go-openapi/validate" ) // AlertGroup alert group +// // swagger:model alertGroup type AlertGroup struct { diff --git a/vendor/github.com/prometheus/alertmanager/api/v2/models/alert_groups.go b/vendor/github.com/prometheus/alertmanager/api/v2/models/alert_groups.go index 9cf8efe659..cb48c08e5f 100644 --- a/vendor/github.com/prometheus/alertmanager/api/v2/models/alert_groups.go +++ b/vendor/github.com/prometheus/alertmanager/api/v2/models/alert_groups.go @@ -22,13 +22,13 @@ package models import ( "strconv" - strfmt "github.com/go-openapi/strfmt" - "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" ) // AlertGroups alert groups +// // swagger:model alertGroups type AlertGroups []*AlertGroup diff --git a/vendor/github.com/prometheus/alertmanager/api/v2/models/alert_status.go b/vendor/github.com/prometheus/alertmanager/api/v2/models/alert_status.go index cadbad364e..9ee99f7851 100644 --- a/vendor/github.com/prometheus/alertmanager/api/v2/models/alert_status.go +++ b/vendor/github.com/prometheus/alertmanager/api/v2/models/alert_status.go @@ -22,14 +22,14 @@ package models import ( "encoding/json" - strfmt "github.com/go-openapi/strfmt" - "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" "github.com/go-openapi/validate" ) // AlertStatus alert status +// // swagger:model alertStatus type AlertStatus struct { @@ -113,7 +113,7 @@ const ( // prop value enum func (m *AlertStatus) validateStateEnum(path, location string, value string) error { - if err := validate.Enum(path, location, value, alertStatusTypeStatePropEnum); err != nil { + if err := validate.EnumCase(path, location, value, alertStatusTypeStatePropEnum, true); err != nil { return err } return nil diff --git a/vendor/github.com/prometheus/alertmanager/api/v2/models/alertmanager_config.go b/vendor/github.com/prometheus/alertmanager/api/v2/models/alertmanager_config.go index a7ef560d02..958114bbf8 100644 --- a/vendor/github.com/prometheus/alertmanager/api/v2/models/alertmanager_config.go +++ b/vendor/github.com/prometheus/alertmanager/api/v2/models/alertmanager_config.go @@ -20,14 +20,14 @@ package models // Editing this file might prove futile when you re-run the swagger generate command import ( - strfmt "github.com/go-openapi/strfmt" - "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" "github.com/go-openapi/validate" ) // AlertmanagerConfig alertmanager config +// // swagger:model alertmanagerConfig type AlertmanagerConfig struct { diff --git a/vendor/github.com/prometheus/alertmanager/api/v2/models/alertmanager_status.go b/vendor/github.com/prometheus/alertmanager/api/v2/models/alertmanager_status.go index 88afa7fe29..483beb23e1 100644 --- a/vendor/github.com/prometheus/alertmanager/api/v2/models/alertmanager_status.go +++ b/vendor/github.com/prometheus/alertmanager/api/v2/models/alertmanager_status.go @@ -20,14 +20,14 @@ package models // Editing this file might prove futile when you re-run the swagger generate command import ( - strfmt "github.com/go-openapi/strfmt" - "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" "github.com/go-openapi/validate" ) // AlertmanagerStatus alertmanager status +// // swagger:model alertmanagerStatus type AlertmanagerStatus struct { diff --git a/vendor/github.com/prometheus/alertmanager/api/v2/models/cluster_status.go b/vendor/github.com/prometheus/alertmanager/api/v2/models/cluster_status.go index 063caac431..a3373a729d 100644 --- a/vendor/github.com/prometheus/alertmanager/api/v2/models/cluster_status.go +++ b/vendor/github.com/prometheus/alertmanager/api/v2/models/cluster_status.go @@ -23,14 +23,14 @@ import ( "encoding/json" "strconv" - strfmt "github.com/go-openapi/strfmt" - "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" "github.com/go-openapi/validate" ) // ClusterStatus cluster status +// // swagger:model clusterStatus type ClusterStatus struct { @@ -115,7 +115,7 @@ const ( // prop value enum func (m *ClusterStatus) validateStatusEnum(path, location string, value string) error { - if err := validate.Enum(path, location, value, clusterStatusTypeStatusPropEnum); err != nil { + if err := validate.EnumCase(path, location, value, clusterStatusTypeStatusPropEnum, true); err != nil { return err } return nil diff --git a/vendor/github.com/prometheus/alertmanager/api/v2/models/gettable_alert.go b/vendor/github.com/prometheus/alertmanager/api/v2/models/gettable_alert.go index c0c983486f..2f74818c27 100644 --- a/vendor/github.com/prometheus/alertmanager/api/v2/models/gettable_alert.go +++ b/vendor/github.com/prometheus/alertmanager/api/v2/models/gettable_alert.go @@ -22,14 +22,14 @@ package models import ( "strconv" - strfmt "github.com/go-openapi/strfmt" - "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" "github.com/go-openapi/validate" ) // GettableAlert gettable alert +// // swagger:model gettableAlert type GettableAlert struct { @@ -158,7 +158,6 @@ func (m GettableAlert) MarshalJSON() ([]byte, error) { return nil, err } _parts = append(_parts, aO1) - return swag.ConcatJSON(_parts...), nil } diff --git a/vendor/github.com/prometheus/alertmanager/api/v2/models/gettable_alerts.go b/vendor/github.com/prometheus/alertmanager/api/v2/models/gettable_alerts.go index fe7f1defdf..f5a5c04215 100644 --- a/vendor/github.com/prometheus/alertmanager/api/v2/models/gettable_alerts.go +++ b/vendor/github.com/prometheus/alertmanager/api/v2/models/gettable_alerts.go @@ -22,13 +22,13 @@ package models import ( "strconv" - strfmt "github.com/go-openapi/strfmt" - "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" ) // GettableAlerts gettable alerts +// // swagger:model gettableAlerts type GettableAlerts []*GettableAlert diff --git a/vendor/github.com/prometheus/alertmanager/api/v2/models/gettable_silence.go b/vendor/github.com/prometheus/alertmanager/api/v2/models/gettable_silence.go index e2cad93190..8fb7a5129c 100644 --- a/vendor/github.com/prometheus/alertmanager/api/v2/models/gettable_silence.go +++ b/vendor/github.com/prometheus/alertmanager/api/v2/models/gettable_silence.go @@ -20,14 +20,14 @@ package models // Editing this file might prove futile when you re-run the swagger generate command import ( - strfmt "github.com/go-openapi/strfmt" - "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" "github.com/go-openapi/validate" ) // GettableSilence gettable silence +// // swagger:model gettableSilence type GettableSilence struct { @@ -106,7 +106,6 @@ func (m GettableSilence) MarshalJSON() ([]byte, error) { return nil, err } _parts = append(_parts, aO1) - return swag.ConcatJSON(_parts...), nil } diff --git a/vendor/github.com/prometheus/alertmanager/api/v2/models/gettable_silences.go b/vendor/github.com/prometheus/alertmanager/api/v2/models/gettable_silences.go index 8f1604e3ff..32d109ef7e 100644 --- a/vendor/github.com/prometheus/alertmanager/api/v2/models/gettable_silences.go +++ b/vendor/github.com/prometheus/alertmanager/api/v2/models/gettable_silences.go @@ -22,13 +22,13 @@ package models import ( "strconv" - strfmt "github.com/go-openapi/strfmt" - "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" ) // GettableSilences gettable silences +// // swagger:model gettableSilences type GettableSilences []*GettableSilence diff --git a/vendor/github.com/prometheus/alertmanager/api/v2/models/label_set.go b/vendor/github.com/prometheus/alertmanager/api/v2/models/label_set.go index 0d1d35389d..d7d2985238 100644 --- a/vendor/github.com/prometheus/alertmanager/api/v2/models/label_set.go +++ b/vendor/github.com/prometheus/alertmanager/api/v2/models/label_set.go @@ -20,10 +20,11 @@ package models // Editing this file might prove futile when you re-run the swagger generate command import ( - strfmt "github.com/go-openapi/strfmt" + "github.com/go-openapi/strfmt" ) // LabelSet label set +// // swagger:model labelSet type LabelSet map[string]string diff --git a/vendor/github.com/prometheus/alertmanager/api/v2/models/matcher.go b/vendor/github.com/prometheus/alertmanager/api/v2/models/matcher.go index eae3605a7e..f2e2d6de8c 100644 --- a/vendor/github.com/prometheus/alertmanager/api/v2/models/matcher.go +++ b/vendor/github.com/prometheus/alertmanager/api/v2/models/matcher.go @@ -20,17 +20,20 @@ package models // Editing this file might prove futile when you re-run the swagger generate command import ( - strfmt "github.com/go-openapi/strfmt" - "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" "github.com/go-openapi/validate" ) // Matcher matcher +// // swagger:model matcher type Matcher struct { + // is equal + IsEqual *bool `json:"isEqual,omitempty"` + // is regex // Required: true IsRegex *bool `json:"isRegex"` diff --git a/vendor/github.com/prometheus/alertmanager/api/v2/models/matchers.go b/vendor/github.com/prometheus/alertmanager/api/v2/models/matchers.go index bd28548978..3fb73c4342 100644 --- a/vendor/github.com/prometheus/alertmanager/api/v2/models/matchers.go +++ b/vendor/github.com/prometheus/alertmanager/api/v2/models/matchers.go @@ -22,14 +22,14 @@ package models import ( "strconv" - strfmt "github.com/go-openapi/strfmt" - "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" "github.com/go-openapi/validate" ) // Matchers matchers +// // swagger:model matchers type Matchers []*Matcher diff --git a/vendor/github.com/prometheus/alertmanager/api/v2/models/peer_status.go b/vendor/github.com/prometheus/alertmanager/api/v2/models/peer_status.go index 29e10ece6f..204c3d7857 100644 --- a/vendor/github.com/prometheus/alertmanager/api/v2/models/peer_status.go +++ b/vendor/github.com/prometheus/alertmanager/api/v2/models/peer_status.go @@ -20,14 +20,14 @@ package models // Editing this file might prove futile when you re-run the swagger generate command import ( - strfmt "github.com/go-openapi/strfmt" - "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" "github.com/go-openapi/validate" ) // PeerStatus peer status +// // swagger:model peerStatus type PeerStatus struct { diff --git a/vendor/github.com/prometheus/alertmanager/api/v2/models/postable_alert.go b/vendor/github.com/prometheus/alertmanager/api/v2/models/postable_alert.go index afa91ca965..88c06e8352 100644 --- a/vendor/github.com/prometheus/alertmanager/api/v2/models/postable_alert.go +++ b/vendor/github.com/prometheus/alertmanager/api/v2/models/postable_alert.go @@ -20,14 +20,14 @@ package models // Editing this file might prove futile when you re-run the swagger generate command import ( - strfmt "github.com/go-openapi/strfmt" - "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" "github.com/go-openapi/validate" ) // PostableAlert postable alert +// // swagger:model postableAlert type PostableAlert struct { @@ -104,7 +104,6 @@ func (m PostableAlert) MarshalJSON() ([]byte, error) { return nil, err } _parts = append(_parts, aO1) - return swag.ConcatJSON(_parts...), nil } diff --git a/vendor/github.com/prometheus/alertmanager/api/v2/models/postable_alerts.go b/vendor/github.com/prometheus/alertmanager/api/v2/models/postable_alerts.go index 7097adcaf1..9a13563682 100644 --- a/vendor/github.com/prometheus/alertmanager/api/v2/models/postable_alerts.go +++ b/vendor/github.com/prometheus/alertmanager/api/v2/models/postable_alerts.go @@ -22,13 +22,13 @@ package models import ( "strconv" - strfmt "github.com/go-openapi/strfmt" - "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" ) // PostableAlerts postable alerts +// // swagger:model postableAlerts type PostableAlerts []*PostableAlert diff --git a/vendor/github.com/prometheus/alertmanager/api/v2/models/postable_silence.go b/vendor/github.com/prometheus/alertmanager/api/v2/models/postable_silence.go index 45efa4ff7d..c77a9534a8 100644 --- a/vendor/github.com/prometheus/alertmanager/api/v2/models/postable_silence.go +++ b/vendor/github.com/prometheus/alertmanager/api/v2/models/postable_silence.go @@ -20,13 +20,13 @@ package models // Editing this file might prove futile when you re-run the swagger generate command import ( - strfmt "github.com/go-openapi/strfmt" - "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" ) // PostableSilence postable silence +// // swagger:model postableSilence type PostableSilence struct { @@ -79,7 +79,6 @@ func (m PostableSilence) MarshalJSON() ([]byte, error) { return nil, err } _parts = append(_parts, aO1) - return swag.ConcatJSON(_parts...), nil } diff --git a/vendor/github.com/prometheus/alertmanager/api/v2/models/receiver.go b/vendor/github.com/prometheus/alertmanager/api/v2/models/receiver.go index 3686e6d199..9f85db60a1 100644 --- a/vendor/github.com/prometheus/alertmanager/api/v2/models/receiver.go +++ b/vendor/github.com/prometheus/alertmanager/api/v2/models/receiver.go @@ -20,14 +20,14 @@ package models // Editing this file might prove futile when you re-run the swagger generate command import ( - strfmt "github.com/go-openapi/strfmt" - "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" "github.com/go-openapi/validate" ) // Receiver receiver +// // swagger:model receiver type Receiver struct { diff --git a/vendor/github.com/prometheus/alertmanager/api/v2/models/silence.go b/vendor/github.com/prometheus/alertmanager/api/v2/models/silence.go index 0a842a301b..27fb9f3d15 100644 --- a/vendor/github.com/prometheus/alertmanager/api/v2/models/silence.go +++ b/vendor/github.com/prometheus/alertmanager/api/v2/models/silence.go @@ -20,14 +20,14 @@ package models // Editing this file might prove futile when you re-run the swagger generate command import ( - strfmt "github.com/go-openapi/strfmt" - "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" "github.com/go-openapi/validate" ) // Silence silence +// // swagger:model silence type Silence struct { diff --git a/vendor/github.com/prometheus/alertmanager/api/v2/models/silence_status.go b/vendor/github.com/prometheus/alertmanager/api/v2/models/silence_status.go index 669269e189..0c63df8533 100644 --- a/vendor/github.com/prometheus/alertmanager/api/v2/models/silence_status.go +++ b/vendor/github.com/prometheus/alertmanager/api/v2/models/silence_status.go @@ -22,14 +22,14 @@ package models import ( "encoding/json" - strfmt "github.com/go-openapi/strfmt" - "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" "github.com/go-openapi/validate" ) // SilenceStatus silence status +// // swagger:model silenceStatus type SilenceStatus struct { @@ -79,7 +79,7 @@ const ( // prop value enum func (m *SilenceStatus) validateStateEnum(path, location string, value string) error { - if err := validate.Enum(path, location, value, silenceStatusTypeStatePropEnum); err != nil { + if err := validate.EnumCase(path, location, value, silenceStatusTypeStatePropEnum, true); err != nil { return err } return nil diff --git a/vendor/github.com/prometheus/alertmanager/api/v2/models/version_info.go b/vendor/github.com/prometheus/alertmanager/api/v2/models/version_info.go index 232d805d28..f7124eca8e 100644 --- a/vendor/github.com/prometheus/alertmanager/api/v2/models/version_info.go +++ b/vendor/github.com/prometheus/alertmanager/api/v2/models/version_info.go @@ -20,14 +20,14 @@ package models // Editing this file might prove futile when you re-run the swagger generate command import ( - strfmt "github.com/go-openapi/strfmt" - "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" "github.com/go-openapi/swag" "github.com/go-openapi/validate" ) // VersionInfo version info +// // swagger:model versionInfo type VersionInfo struct { diff --git a/vendor/github.com/prometheus/alertmanager/config/config.go b/vendor/github.com/prometheus/alertmanager/config/config.go index 056311c783..e911e1b63c 100644 --- a/vendor/github.com/prometheus/alertmanager/config/config.go +++ b/vendor/github.com/prometheus/alertmanager/config/config.go @@ -21,6 +21,7 @@ import ( "net/url" "path/filepath" "regexp" + "sort" "strings" "time" @@ -28,6 +29,9 @@ import ( commoncfg "github.com/prometheus/common/config" "github.com/prometheus/common/model" "gopkg.in/yaml.v2" + + "github.com/prometheus/alertmanager/pkg/labels" + "github.com/prometheus/alertmanager/timeinterval" ) const secretToken = "" @@ -214,15 +218,59 @@ func resolveFilepaths(baseDir string, cfg *Config) { for i, tf := range cfg.Templates { cfg.Templates[i] = join(tf) } + + cfg.Global.HTTPConfig.SetDirectory(baseDir) + for _, receiver := range cfg.Receivers { + for _, cfg := range receiver.OpsGenieConfigs { + cfg.HTTPConfig.SetDirectory(baseDir) + } + for _, cfg := range receiver.PagerdutyConfigs { + cfg.HTTPConfig.SetDirectory(baseDir) + } + for _, cfg := range receiver.PushoverConfigs { + cfg.HTTPConfig.SetDirectory(baseDir) + } + for _, cfg := range receiver.SlackConfigs { + cfg.HTTPConfig.SetDirectory(baseDir) + } + for _, cfg := range receiver.VictorOpsConfigs { + cfg.HTTPConfig.SetDirectory(baseDir) + } + for _, cfg := range receiver.WebhookConfigs { + cfg.HTTPConfig.SetDirectory(baseDir) + } + for _, cfg := range receiver.WechatConfigs { + cfg.HTTPConfig.SetDirectory(baseDir) + } + } +} + +// MuteTimeInterval represents a named set of time intervals for which a route should be muted. +type MuteTimeInterval struct { + Name string `yaml:"name"` + TimeIntervals []timeinterval.TimeInterval `yaml:"time_intervals"` +} + +// UnmarshalYAML implements the yaml.Unmarshaler interface for MuteTimeInterval. +func (mt *MuteTimeInterval) UnmarshalYAML(unmarshal func(interface{}) error) error { + type plain MuteTimeInterval + if err := unmarshal((*plain)(mt)); err != nil { + return err + } + if mt.Name == "" { + return fmt.Errorf("missing name in mute time interval") + } + return nil } // Config is the top-level configuration for Alertmanager's config files. type Config struct { - Global *GlobalConfig `yaml:"global,omitempty" json:"global,omitempty"` - Route *Route `yaml:"route,omitempty" json:"route,omitempty"` - InhibitRules []*InhibitRule `yaml:"inhibit_rules,omitempty" json:"inhibit_rules,omitempty"` - Receivers []*Receiver `yaml:"receivers,omitempty" json:"receivers,omitempty"` - Templates []string `yaml:"templates" json:"templates"` + Global *GlobalConfig `yaml:"global,omitempty" json:"global,omitempty"` + Route *Route `yaml:"route,omitempty" json:"route,omitempty"` + InhibitRules []*InhibitRule `yaml:"inhibit_rules,omitempty" json:"inhibit_rules,omitempty"` + Receivers []*Receiver `yaml:"receivers,omitempty" json:"receivers,omitempty"` + Templates []string `yaml:"templates" json:"templates"` + MuteTimeIntervals []MuteTimeInterval `yaml:"mute_time_intervals,omitempty" json:"mute_time_intervals,omitempty"` // original is the input from which the config was parsed. original string @@ -253,6 +301,10 @@ func (c *Config) UnmarshalYAML(unmarshal func(interface{}) error) error { *c.Global = DefaultGlobalConfig() } + if c.Global.SlackAPIURL != nil && len(c.Global.SlackAPIURLFile) > 0 { + return fmt.Errorf("at most one of slack_api_url & slack_api_url_file must be configured") + } + names := map[string]struct{}{} for _, rcv := range c.Receivers { @@ -301,11 +353,12 @@ func (c *Config) UnmarshalYAML(unmarshal func(interface{}) error) error { if sc.HTTPConfig == nil { sc.HTTPConfig = c.Global.HTTPConfig } - if sc.APIURL == nil { - if c.Global.SlackAPIURL == nil { - return fmt.Errorf("no global Slack API URL set") + if sc.APIURL == nil && len(sc.APIURLFile) == 0 { + if c.Global.SlackAPIURL == nil && len(c.Global.SlackAPIURLFile) == 0 { + return fmt.Errorf("no global Slack API URL set either inline or in a file") } sc.APIURL = c.Global.SlackAPIURL + sc.APIURLFile = c.Global.SlackAPIURLFile } } for _, poc := range rcv.PushoverConfigs { @@ -408,9 +461,23 @@ func (c *Config) UnmarshalYAML(unmarshal func(interface{}) error) error { if len(c.Route.Match) > 0 || len(c.Route.MatchRE) > 0 { return fmt.Errorf("root route must not have any matchers") } + if len(c.Route.MuteTimeIntervals) > 0 { + return fmt.Errorf("root route must not have any mute time intervals") + } // Validate that all receivers used in the routing tree are defined. - return checkReceiver(c.Route, names) + if err := checkReceiver(c.Route, names); err != nil { + return err + } + + tiNames := make(map[string]struct{}) + for _, mt := range c.MuteTimeIntervals { + if _, ok := tiNames[mt.Name]; ok { + return fmt.Errorf("mute time interval %q is not unique", mt.Name) + } + tiNames[mt.Name] = struct{}{} + } + return checkTimeInterval(c.Route, tiNames) } // checkReceiver returns an error if a node in the routing tree @@ -430,11 +497,29 @@ func checkReceiver(r *Route, receivers map[string]struct{}) error { return nil } +func checkTimeInterval(r *Route, timeIntervals map[string]struct{}) error { + for _, sr := range r.Routes { + if err := checkTimeInterval(sr, timeIntervals); err != nil { + return err + } + } + if len(r.MuteTimeIntervals) == 0 { + return nil + } + for _, mt := range r.MuteTimeIntervals { + if _, ok := timeIntervals[mt]; !ok { + return fmt.Errorf("undefined time interval %q used in route", mt) + } + } + return nil +} + // DefaultGlobalConfig returns GlobalConfig with default values. func DefaultGlobalConfig() GlobalConfig { + var defaultHTTPConfig = commoncfg.DefaultHTTPClientConfig return GlobalConfig{ ResolveTimeout: model.Duration(5 * time.Minute), - HTTPConfig: &commoncfg.HTTPClientConfig{}, + HTTPConfig: &defaultHTTPConfig, SMTPHello: "localhost", SMTPRequireTLS: true, @@ -552,6 +637,7 @@ type GlobalConfig struct { SMTPAuthIdentity string `yaml:"smtp_auth_identity,omitempty" json:"smtp_auth_identity,omitempty"` SMTPRequireTLS bool `yaml:"smtp_require_tls" json:"smtp_require_tls,omitempty"` SlackAPIURL *SecretURL `yaml:"slack_api_url,omitempty" json:"slack_api_url,omitempty"` + SlackAPIURLFile string `yaml:"slack_api_url_file,omitempty" json:"slack_api_url_file,omitempty"` PagerdutyURL *URL `yaml:"pagerduty_url,omitempty" json:"pagerduty_url,omitempty"` OpsGenieAPIURL *URL `yaml:"opsgenie_api_url,omitempty" json:"opsgenie_api_url,omitempty"` OpsGenieAPIKey Secret `yaml:"opsgenie_api_key,omitempty" json:"opsgenie_api_key,omitempty"` @@ -576,11 +662,14 @@ type Route struct { GroupByStr []string `yaml:"group_by,omitempty" json:"group_by,omitempty"` GroupBy []model.LabelName `yaml:"-" json:"-"` GroupByAll bool `yaml:"-" json:"-"` - - Match map[string]string `yaml:"match,omitempty" json:"match,omitempty"` - MatchRE MatchRegexps `yaml:"match_re,omitempty" json:"match_re,omitempty"` - Continue bool `yaml:"continue" json:"continue,omitempty"` - Routes []*Route `yaml:"routes,omitempty" json:"routes,omitempty"` + // Deprecated. Remove before v1.0 release. + Match map[string]string `yaml:"match,omitempty" json:"match,omitempty"` + // Deprecated. Remove before v1.0 release. + MatchRE MatchRegexps `yaml:"match_re,omitempty" json:"match_re,omitempty"` + Matchers Matchers `yaml:"matchers,omitempty" json:"matchers,omitempty"` + MuteTimeIntervals []string `yaml:"mute_time_intervals,omitempty" json:"mute_time_intervals,omitempty"` + Continue bool `yaml:"continue" json:"continue,omitempty"` + Routes []*Route `yaml:"routes,omitempty" json:"routes,omitempty"` GroupWait *model.Duration `yaml:"group_wait,omitempty" json:"group_wait,omitempty"` GroupInterval *model.Duration `yaml:"group_interval,omitempty" json:"group_interval,omitempty"` @@ -640,17 +729,21 @@ func (r *Route) UnmarshalYAML(unmarshal func(interface{}) error) error { // Both alerts have to have a set of labels being equal. type InhibitRule struct { // SourceMatch defines a set of labels that have to equal the given - // value for source alerts. + // value for source alerts. Deprecated. Remove before v1.0 release. SourceMatch map[string]string `yaml:"source_match,omitempty" json:"source_match,omitempty"` // SourceMatchRE defines pairs like SourceMatch but does regular expression - // matching. + // matching. Deprecated. Remove before v1.0 release. SourceMatchRE MatchRegexps `yaml:"source_match_re,omitempty" json:"source_match_re,omitempty"` + // SourceMatchers defines a set of label matchers that have to be fulfilled for source alerts. + SourceMatchers Matchers `yaml:"source_matchers,omitempty" json:"source_matchers,omitempty"` // TargetMatch defines a set of labels that have to equal the given - // value for target alerts. + // value for target alerts. Deprecated. Remove before v1.0 release. TargetMatch map[string]string `yaml:"target_match,omitempty" json:"target_match,omitempty"` // TargetMatchRE defines pairs like TargetMatch but does regular expression - // matching. + // matching. Deprecated. Remove before v1.0 release. TargetMatchRE MatchRegexps `yaml:"target_match_re,omitempty" json:"target_match_re,omitempty"` + // TargetMatchers defines a set of label matchers that have to be fulfilled for target alerts. + TargetMatchers Matchers `yaml:"target_matchers,omitempty" json:"target_matchers,omitempty"` // A set of labels that must be equal between the source and target alert // for them to be a match. Equal model.LabelNames `yaml:"equal,omitempty" json:"equal,omitempty"` @@ -754,7 +847,7 @@ func (re Regexp) MarshalYAML() (interface{}, error) { return nil, nil } -// UnmarshalJSON implements the json.Marshaler interface for Regexp +// UnmarshalJSON implements the json.Unmarshaler interface for Regexp func (re *Regexp) UnmarshalJSON(data []byte) error { var s string if err := json.Unmarshal(data, &s); err != nil { @@ -776,3 +869,62 @@ func (re Regexp) MarshalJSON() ([]byte, error) { } return nil, nil } + +// Matchers is label.Matchers with an added UnmarshalYAML method to implement the yaml.Unmarshaler interface +// and MarshalYAML to implement the yaml.Marshaler interface. +type Matchers labels.Matchers + +// UnmarshalYAML implements the yaml.Unmarshaler interface for Matchers. +func (m *Matchers) UnmarshalYAML(unmarshal func(interface{}) error) error { + var lines []string + if err := unmarshal(&lines); err != nil { + return err + } + for _, line := range lines { + pm, err := labels.ParseMatchers(line) + if err != nil { + return err + } + *m = append(*m, pm...) + } + sort.Sort(labels.Matchers(*m)) + return nil +} + +// MarshalYAML implements the yaml.Marshaler interface for Matchers. +func (m Matchers) MarshalYAML() (interface{}, error) { + result := make([]string, len(m)) + for i, matcher := range m { + result[i] = matcher.String() + } + return result, nil +} + +// UnmarshalJSON implements the json.Unmarshaler interface for Matchers. +func (m *Matchers) UnmarshalJSON(data []byte) error { + var lines []string + if err := json.Unmarshal(data, &lines); err != nil { + return err + } + for _, line := range lines { + pm, err := labels.ParseMatchers(line) + if err != nil { + return err + } + *m = append(*m, pm...) + } + sort.Sort(labels.Matchers(*m)) + return nil +} + +// MarshalJSON implements the json.Marshaler interface for Matchers. +func (m Matchers) MarshalJSON() ([]byte, error) { + if len(m) == 0 { + return nil, nil + } + result := make([]string, len(m)) + for i, matcher := range m { + result[i] = matcher.String() + } + return json.Marshal(result) +} diff --git a/vendor/github.com/prometheus/alertmanager/config/notifiers.go b/vendor/github.com/prometheus/alertmanager/config/notifiers.go index 3817143432..5db3d66ff6 100644 --- a/vendor/github.com/prometheus/alertmanager/config/notifiers.go +++ b/vendor/github.com/prometheus/alertmanager/config/notifiers.go @@ -328,7 +328,8 @@ type SlackConfig struct { HTTPConfig *commoncfg.HTTPClientConfig `yaml:"http_config,omitempty" json:"http_config,omitempty"` - APIURL *SecretURL `yaml:"api_url,omitempty" json:"api_url,omitempty"` + APIURL *SecretURL `yaml:"api_url,omitempty" json:"api_url,omitempty"` + APIURLFile string `yaml:"api_url_file,omitempty" json:"api_url_file,omitempty"` // Slack channel override, (like #other-channel or @username). Channel string `yaml:"channel,omitempty" json:"channel,omitempty"` @@ -357,7 +358,15 @@ type SlackConfig struct { func (c *SlackConfig) UnmarshalYAML(unmarshal func(interface{}) error) error { *c = DefaultSlackConfig type plain SlackConfig - return unmarshal((*plain)(c)) + if err := unmarshal((*plain)(c)); err != nil { + return err + } + + if c.APIURL != nil && len(c.APIURLFile) > 0 { + return fmt.Errorf("at most one of api_url & api_url_file must be configured") + } + + return nil } // WebhookConfig configures notifications via a generic webhook. @@ -490,7 +499,8 @@ type VictorOpsConfig struct { HTTPConfig *commoncfg.HTTPClientConfig `yaml:"http_config,omitempty" json:"http_config,omitempty"` - APIKey Secret `yaml:"api_key" json:"api_key"` + APIKey Secret `yaml:"api_key,omitempty" json:"api_key,omitempty"` + APIKeyFile Secret `yaml:"api_key_file,omitempty" json:"api_key_file,omitempty"` APIURL *URL `yaml:"api_url" json:"api_url"` RoutingKey string `yaml:"routing_key" json:"routing_key"` MessageType string `yaml:"message_type" json:"message_type"` diff --git a/vendor/github.com/prometheus/alertmanager/pkg/labels/matcher.go b/vendor/github.com/prometheus/alertmanager/pkg/labels/matcher.go index 7fa5d947e7..308ed9d472 100644 --- a/vendor/github.com/prometheus/alertmanager/pkg/labels/matcher.go +++ b/vendor/github.com/prometheus/alertmanager/pkg/labels/matcher.go @@ -14,8 +14,13 @@ package labels import ( + "bytes" + "encoding/json" "fmt" "regexp" + "strings" + + "github.com/prometheus/common/model" ) // MatchType is an enum for label matching types. @@ -69,7 +74,7 @@ func NewMatcher(t MatchType, n, v string) (*Matcher, error) { } func (m *Matcher) String() string { - return fmt.Sprintf("%s%s%q", m.Name, m.Type, m.Value) + return fmt.Sprintf(`%s%s"%s"`, m.Name, m.Type, openMetricsEscape(m.Value)) } // Matches returns whether the matcher matches the given string value. @@ -86,3 +91,108 @@ func (m *Matcher) Matches(s string) bool { } panic("labels.Matcher.Matches: invalid match type") } + +type apiV1Matcher struct { + Name string `json:"name"` + Value string `json:"value"` + IsRegex bool `json:"isRegex"` + IsEqual bool `json:"isEqual"` +} + +// MarshalJSON retains backwards compatibility with types.Matcher for the v1 API. +func (m Matcher) MarshalJSON() ([]byte, error) { + return json.Marshal(apiV1Matcher{ + Name: m.Name, + Value: m.Value, + IsRegex: m.Type == MatchRegexp || m.Type == MatchNotRegexp, + IsEqual: m.Type == MatchRegexp || m.Type == MatchEqual, + }) +} + +func (m *Matcher) UnmarshalJSON(data []byte) error { + var v1m apiV1Matcher + if err := json.Unmarshal(data, &v1m); err != nil { + return err + } + + var t MatchType + switch { + case v1m.IsEqual && !v1m.IsRegex: + t = MatchEqual + case !v1m.IsEqual && !v1m.IsRegex: + t = MatchNotEqual + case v1m.IsEqual && v1m.IsRegex: + t = MatchRegexp + case !v1m.IsEqual && v1m.IsRegex: + t = MatchNotRegexp + } + + matcher, err := NewMatcher(t, v1m.Name, v1m.Value) + if err != nil { + return err + } + *m = *matcher + return nil +} + +// openMetricsEscape is similar to the usual string escaping, but more +// restricted. It merely replaces a new-line character with '\n', a double-quote +// character with '\"', and a backslash with '\\', which is the escaping used by +// OpenMetrics. +func openMetricsEscape(s string) string { + r := strings.NewReplacer( + `\`, `\\`, + "\n", `\n`, + `"`, `\"`, + ) + return r.Replace(s) +} + +// Matchers is a slice of Matchers that is sortable, implements Stringer, and +// provides a Matches method to match a LabelSet against all Matchers in the +// slice. Note that some users of Matchers might require it to be sorted. +type Matchers []*Matcher + +func (ms Matchers) Len() int { return len(ms) } +func (ms Matchers) Swap(i, j int) { ms[i], ms[j] = ms[j], ms[i] } + +func (ms Matchers) Less(i, j int) bool { + if ms[i].Name > ms[j].Name { + return false + } + if ms[i].Name < ms[j].Name { + return true + } + if ms[i].Value > ms[j].Value { + return false + } + if ms[i].Value < ms[j].Value { + return true + } + return ms[i].Type < ms[j].Type +} + +// Matches checks whether all matchers are fulfilled against the given label set. +func (ms Matchers) Matches(lset model.LabelSet) bool { + for _, m := range ms { + if !m.Matches(string(lset[model.LabelName(m.Name)])) { + return false + } + } + return true +} + +func (ms Matchers) String() string { + var buf bytes.Buffer + + buf.WriteByte('{') + for i, m := range ms { + if i > 0 { + buf.WriteByte(',') + } + buf.WriteString(m.String()) + } + buf.WriteByte('}') + + return buf.String() +} diff --git a/vendor/github.com/prometheus/alertmanager/pkg/labels/parse.go b/vendor/github.com/prometheus/alertmanager/pkg/labels/parse.go index 7f664ecad0..907056febe 100644 --- a/vendor/github.com/prometheus/alertmanager/pkg/labels/parse.go +++ b/vendor/github.com/prometheus/alertmanager/pkg/labels/parse.go @@ -16,12 +16,17 @@ package labels import ( "regexp" "strings" + "unicode/utf8" "github.com/pkg/errors" ) var ( - re = regexp.MustCompile(`(?:\s?)(\w+)(=|=~|!=|!~)(?:\"([^"=~!]+)\"|([^"=~!]+)|\"\")`) + re = regexp.MustCompile( + // '=~' has to come before '=' because otherwise only the '=' + // will be consumed, and the '~' will be part of the 3rd token. + `^\s*([a-zA-Z_:][a-zA-Z0-9_:]*)\s*(=~|=|!=|!~)\s*((?s).*?)\s*$`, + ) typeMap = map[string]MatchType{ "=": MatchEqual, "!=": MatchNotEqual, @@ -30,27 +35,59 @@ var ( } ) +// ParseMatchers parses a comma-separated list of Matchers. A leading '{' and/or +// a trailing '}' is optional and will be trimmed before further +// parsing. Individual Matchers are separated by commas outside of quoted parts +// of the input string. Those commas may be surrounded by whitespace. Parts of the +// string inside unescaped double quotes ('"…"') are considered quoted (and +// commas don't act as separators there). If double quotes are escaped with a +// single backslash ('\"'), they are ignored for the purpose of identifying +// quoted parts of the input string. If the input string, after trimming the +// optional trailing '}', ends with a comma, followed by optional whitespace, +// this comma and whitespace will be trimmed. +// +// Examples for valid input strings: +// {foo = "bar", dings != "bums", } +// foo=bar,dings!=bums +// foo=bar, dings!=bums +// {quote="She said: \"Hi, ladies! That's gender-neutral…\""} +// statuscode=~"5.." +// +// See ParseMatcher for details on how an individual Matcher is parsed. func ParseMatchers(s string) ([]*Matcher, error) { matchers := []*Matcher{} s = strings.TrimPrefix(s, "{") s = strings.TrimSuffix(s, "}") - var insideQuotes bool - var token string - var tokens []string + var ( + insideQuotes bool + escaped bool + token strings.Builder + tokens []string + ) for _, r := range s { - if !insideQuotes && r == ',' { - tokens = append(tokens, token) - token = "" - continue - } - token += string(r) - if r == '"' { - insideQuotes = !insideQuotes + switch r { + case ',': + if !insideQuotes { + tokens = append(tokens, token.String()) + token.Reset() + continue + } + case '"': + if !escaped { + insideQuotes = !insideQuotes + } else { + escaped = false + } + case '\\': + escaped = !escaped + default: + escaped = false } + token.WriteRune(r) } - if token != "" { - tokens = append(tokens, token) + if s := strings.TrimSpace(token.String()); s != "" { + tokens = append(tokens, s) } for _, token := range tokens { m, err := ParseMatcher(token) @@ -63,32 +100,72 @@ func ParseMatchers(s string) ([]*Matcher, error) { return matchers, nil } +// ParseMatcher parses a matcher with a syntax inspired by PromQL and +// OpenMetrics. This syntax is convenient to describe filters and selectors in +// UIs and config files. To support the interactive nature of the use cases, the +// parser is in various aspects fairly tolerant. +// +// The syntax of a matcher consists of three tokens: (1) A valid Prometheus +// label name. (2) One of '=', '!=', '=~', or '!~', with the same meaning as +// known from PromQL selectors. (3) A UTF-8 string, which may be enclosed in +// double quotes. Before or after each token, there may be any amount of +// whitespace, which will be discarded. The 3rd token may be the empty +// string. Within the 3rd token, OpenMetrics escaping rules apply: '\"' for a +// double-quote, '\n' for a line feed, '\\' for a literal backslash. Unescaped +// '"' must not occur inside the 3rd token (only as the 1st or last +// character). However, literal line feed characters are tolerated, as are +// single '\' characters not followed by '\', 'n', or '"'. They act as a literal +// backslash in that case. func ParseMatcher(s string) (*Matcher, error) { - var ( - name, value string - matchType MatchType - ) - ms := re.FindStringSubmatch(s) - if len(ms) < 4 { + if len(ms) == 0 { return nil, errors.Errorf("bad matcher format: %s", s) } - name = ms[1] - if name == "" { - return nil, errors.New("failed to parse label name") - } + var ( + rawValue = strings.TrimPrefix(ms[3], "\"") + value strings.Builder + escaped bool + ) - matchType, found := typeMap[ms[2]] - if !found { - return nil, errors.New("failed to find match operator") + if !utf8.ValidString(rawValue) { + return nil, errors.Errorf("matcher value not valid UTF-8: %s", rawValue) } - if ms[3] != "" { - value = ms[3] - } else { - value = ms[4] + // Unescape the rawValue: + for i, r := range rawValue { + if escaped { + escaped = false + switch r { + case 'n': + value.WriteByte('\n') + case '"', '\\': + value.WriteRune(r) + default: + // This was a spurious escape, so treat the '\' as literal. + value.WriteByte('\\') + value.WriteRune(r) + } + continue + } + switch r { + case '\\': + if i < len(rawValue)-1 { + escaped = true + continue + } + // '\' encountered as last byte. Treat it as literal. + value.WriteByte('\\') + case '"': + if i < len(rawValue)-1 { // Otherwise this is a trailing quote. + return nil, errors.Errorf( + "matcher value contains unescaped double quote: %s", rawValue, + ) + } + default: + value.WriteRune(r) + } } - return NewMatcher(matchType, name, value) + return NewMatcher(typeMap[ms[2]], ms[1], value.String()) } diff --git a/vendor/github.com/prometheus/alertmanager/timeinterval/timeinterval.go b/vendor/github.com/prometheus/alertmanager/timeinterval/timeinterval.go new file mode 100644 index 0000000000..24c4a4ea03 --- /dev/null +++ b/vendor/github.com/prometheus/alertmanager/timeinterval/timeinterval.go @@ -0,0 +1,542 @@ +// Copyright 2020 Prometheus Team +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package timeinterval + +import ( + "encoding/json" + "errors" + "fmt" + "regexp" + "strconv" + "strings" + "time" + + "gopkg.in/yaml.v2" +) + +// TimeInterval describes intervals of time. ContainsTime will tell you if a golang time is contained +// within the interval. +type TimeInterval struct { + Times []TimeRange `yaml:"times,omitempty" json:"times,omitempty"` + Weekdays []WeekdayRange `yaml:"weekdays,flow,omitempty" json:"weekdays,omitempty"` + DaysOfMonth []DayOfMonthRange `yaml:"days_of_month,flow,omitempty" json:"days_of_month,omitempty"` + Months []MonthRange `yaml:"months,flow,omitempty" json:"months,omitempty"` + Years []YearRange `yaml:"years,flow,omitempty" json:"years,omitempty"` +} + +// TimeRange represents a range of minutes within a 1440 minute day, exclusive of the End minute. A day consists of 1440 minutes. +// For example, 4:00PM to End of the day would Begin at 1020 and End at 1440. +type TimeRange struct { + StartMinute int + EndMinute int +} + +// InclusiveRange is used to hold the Beginning and End values of many time interval components. +type InclusiveRange struct { + Begin int + End int +} + +// A WeekdayRange is an inclusive range between [0, 6] where 0 = Sunday. +type WeekdayRange struct { + InclusiveRange +} + +// A DayOfMonthRange is an inclusive range that may have negative Beginning/End values that represent distance from the End of the month Beginning at -1. +type DayOfMonthRange struct { + InclusiveRange +} + +// A MonthRange is an inclusive range between [1, 12] where 1 = January. +type MonthRange struct { + InclusiveRange +} + +// A YearRange is a positive inclusive range. +type YearRange struct { + InclusiveRange +} + +type yamlTimeRange struct { + StartTime string `yaml:"start_time" json:"start_time"` + EndTime string `yaml:"end_time" json:"end_time"` +} + +// A range with a Beginning and End that can be represented as strings. +type stringableRange interface { + setBegin(int) + setEnd(int) + // Try to map a member of the range into an integer. + memberFromString(string) (int, error) +} + +func (ir *InclusiveRange) setBegin(n int) { + ir.Begin = n +} + +func (ir *InclusiveRange) setEnd(n int) { + ir.End = n +} + +func (ir *InclusiveRange) memberFromString(in string) (out int, err error) { + out, err = strconv.Atoi(in) + if err != nil { + return -1, err + } + return out, nil +} + +func (r *WeekdayRange) memberFromString(in string) (out int, err error) { + out, ok := daysOfWeek[in] + if !ok { + return -1, fmt.Errorf("%s is not a valid weekday", in) + } + return out, nil +} + +func (r *MonthRange) memberFromString(in string) (out int, err error) { + out, ok := months[in] + if !ok { + out, err = strconv.Atoi(in) + if err != nil { + return -1, fmt.Errorf("%s is not a valid month", in) + } + } + return out, nil +} + +var daysOfWeek = map[string]int{ + "sunday": 0, + "monday": 1, + "tuesday": 2, + "wednesday": 3, + "thursday": 4, + "friday": 5, + "saturday": 6, +} +var daysOfWeekInv = map[int]string{ + 0: "sunday", + 1: "monday", + 2: "tuesday", + 3: "wednesday", + 4: "thursday", + 5: "friday", + 6: "saturday", +} + +var months = map[string]int{ + "january": 1, + "february": 2, + "march": 3, + "april": 4, + "may": 5, + "june": 6, + "july": 7, + "august": 8, + "september": 9, + "october": 10, + "november": 11, + "december": 12, +} + +var monthsInv = map[int]string{ + 1: "january", + 2: "february", + 3: "march", + 4: "april", + 5: "may", + 6: "june", + 7: "july", + 8: "august", + 9: "september", + 10: "october", + 11: "november", + 12: "december", +} + +// UnmarshalYAML implements the Unmarshaller interface for WeekdayRange. +func (r *WeekdayRange) UnmarshalYAML(unmarshal func(interface{}) error) error { + var str string + if err := unmarshal(&str); err != nil { + return err + } + if err := stringableRangeFromString(str, r); err != nil { + return err + } + if r.Begin > r.End { + return errors.New("start day cannot be before end day") + } + if r.Begin < 0 || r.Begin > 6 { + return fmt.Errorf("%s is not a valid day of the week: out of range", str) + } + if r.End < 0 || r.End > 6 { + return fmt.Errorf("%s is not a valid day of the week: out of range", str) + } + return nil +} + +// UnmarshalJSON implements the json.Unmarshaler interface for WeekdayRange. +// It delegates to the YAML unmarshaller as it can parse JSON and has validation logic. +func (r *WeekdayRange) UnmarshalJSON(in []byte) error { + return yaml.Unmarshal(in, r) +} + +// UnmarshalYAML implements the Unmarshaller interface for DayOfMonthRange. +func (r *DayOfMonthRange) UnmarshalYAML(unmarshal func(interface{}) error) error { + var str string + if err := unmarshal(&str); err != nil { + return err + } + if err := stringableRangeFromString(str, r); err != nil { + return err + } + // Check beginning <= end accounting for negatives day of month indices as well. + // Months != 31 days can't be addressed here and are clamped, but at least we can catch blatant errors. + if r.Begin == 0 || r.Begin < -31 || r.Begin > 31 { + return fmt.Errorf("%d is not a valid day of the month: out of range", r.Begin) + } + if r.End == 0 || r.End < -31 || r.End > 31 { + return fmt.Errorf("%d is not a valid day of the month: out of range", r.End) + } + // Restricting here prevents errors where begin > end in longer months but not shorter months. + if r.Begin < 0 && r.End > 0 { + return fmt.Errorf("end day must be negative if start day is negative") + } + // Check begin <= end. We can't know this for sure when using negative indices + // but we can prevent cases where its always invalid (using 28 day minimum length). + checkBegin := r.Begin + checkEnd := r.End + if r.Begin < 0 { + checkBegin = 28 + r.Begin + } + if r.End < 0 { + checkEnd = 28 + r.End + } + if checkBegin > checkEnd { + return fmt.Errorf("end day %d is always before start day %d", r.End, r.Begin) + } + return nil +} + +// UnmarshalJSON implements the json.Unmarshaler interface for DayOfMonthRange. +// It delegates to the YAML unmarshaller as it can parse JSON and has validation logic. +func (r *DayOfMonthRange) UnmarshalJSON(in []byte) error { + return yaml.Unmarshal(in, r) +} + +// UnmarshalYAML implements the Unmarshaller interface for MonthRange. +func (r *MonthRange) UnmarshalYAML(unmarshal func(interface{}) error) error { + var str string + if err := unmarshal(&str); err != nil { + return err + } + if err := stringableRangeFromString(str, r); err != nil { + return err + } + if r.Begin > r.End { + begin := monthsInv[r.Begin] + end := monthsInv[r.End] + return fmt.Errorf("end month %s is before start month %s", end, begin) + } + return nil +} + +// UnmarshalJSON implements the json.Unmarshaler interface for MonthRange. +// It delegates to the YAML unmarshaller as it can parse JSON and has validation logic. +func (r *MonthRange) UnmarshalJSON(in []byte) error { + return yaml.Unmarshal(in, r) +} + +// UnmarshalYAML implements the Unmarshaller interface for YearRange. +func (r *YearRange) UnmarshalYAML(unmarshal func(interface{}) error) error { + var str string + if err := unmarshal(&str); err != nil { + return err + } + if err := stringableRangeFromString(str, r); err != nil { + return err + } + if r.Begin > r.End { + return fmt.Errorf("end year %d is before start year %d", r.End, r.Begin) + } + return nil +} + +// UnmarshalJSON implements the json.Unmarshaler interface for YearRange. +// It delegates to the YAML unmarshaller as it can parse JSON and has validation logic. +func (r *YearRange) UnmarshalJSON(in []byte) error { + return yaml.Unmarshal(in, r) +} + +// UnmarshalYAML implements the Unmarshaller interface for TimeRanges. +func (tr *TimeRange) UnmarshalYAML(unmarshal func(interface{}) error) error { + var y yamlTimeRange + if err := unmarshal(&y); err != nil { + return err + } + if y.EndTime == "" || y.StartTime == "" { + return errors.New("both start and end times must be provided") + } + start, err := parseTime(y.StartTime) + if err != nil { + return err + } + end, err := parseTime(y.EndTime) + if err != nil { + return err + } + if start >= end { + return errors.New("start time cannot be equal or greater than end time") + } + tr.StartMinute, tr.EndMinute = start, end + return nil +} + +// UnmarshalJSON implements the json.Unmarshaler interface for Timerange. +// It delegates to the YAML unmarshaller as it can parse JSON and has validation logic. +func (tr *TimeRange) UnmarshalJSON(in []byte) error { + return yaml.Unmarshal(in, tr) +} + +// MarshalYAML implements the yaml.Marshaler interface for WeekdayRange. +func (r WeekdayRange) MarshalYAML() (interface{}, error) { + bytes, err := r.MarshalText() + return string(bytes), err +} + +// MarshalText implements the econding.TextMarshaler interface for WeekdayRange. +// It converts the range into a colon-seperated string, or a single weekday if possible. +// e.g. "monday:friday" or "saturday". +func (r WeekdayRange) MarshalText() ([]byte, error) { + beginStr, ok := daysOfWeekInv[r.Begin] + if !ok { + return nil, fmt.Errorf("unable to convert %d into weekday string", r.Begin) + } + if r.Begin == r.End { + return []byte(beginStr), nil + } + endStr, ok := daysOfWeekInv[r.End] + if !ok { + return nil, fmt.Errorf("unable to convert %d into weekday string", r.End) + } + rangeStr := fmt.Sprintf("%s:%s", beginStr, endStr) + return []byte(rangeStr), nil +} + +// MarshalYAML implements the yaml.Marshaler interface for TimeRange. +func (tr TimeRange) MarshalYAML() (out interface{}, err error) { + startHr := tr.StartMinute / 60 + endHr := tr.EndMinute / 60 + startMin := tr.StartMinute % 60 + endMin := tr.EndMinute % 60 + + startStr := fmt.Sprintf("%02d:%02d", startHr, startMin) + endStr := fmt.Sprintf("%02d:%02d", endHr, endMin) + + yTr := yamlTimeRange{startStr, endStr} + return interface{}(yTr), err +} + +// MarshalJSON implements the json.Marshaler interface for TimeRange. +func (tr TimeRange) MarshalJSON() (out []byte, err error) { + startHr := tr.StartMinute / 60 + endHr := tr.EndMinute / 60 + startMin := tr.StartMinute % 60 + endMin := tr.EndMinute % 60 + + startStr := fmt.Sprintf("%02d:%02d", startHr, startMin) + endStr := fmt.Sprintf("%02d:%02d", endHr, endMin) + + yTr := yamlTimeRange{startStr, endStr} + return json.Marshal(yTr) +} + +// MarshalText implements the encoding.TextMarshaler interface for InclusiveRange. +// It converts the struct into a colon-separated string, or a single element if +// appropriate. e.g. "monday:friday" or "monday" +func (ir InclusiveRange) MarshalText() ([]byte, error) { + if ir.Begin == ir.End { + return []byte(strconv.Itoa(ir.Begin)), nil + } + out := fmt.Sprintf("%d:%d", ir.Begin, ir.End) + return []byte(out), nil +} + +//MarshalYAML implements the yaml.Marshaler interface for InclusiveRange. +func (ir InclusiveRange) MarshalYAML() (interface{}, error) { + bytes, err := ir.MarshalText() + return string(bytes), err +} + +// TimeLayout specifies the layout to be used in time.Parse() calls for time intervals. +const TimeLayout = "15:04" + +var validTime string = "^((([01][0-9])|(2[0-3])):[0-5][0-9])$|(^24:00$)" +var validTimeRE *regexp.Regexp = regexp.MustCompile(validTime) + +// Given a time, determines the number of days in the month that time occurs in. +func daysInMonth(t time.Time) int { + monthStart := time.Date(t.Year(), t.Month(), 1, 0, 0, 0, 0, t.Location()) + monthEnd := monthStart.AddDate(0, 1, 0) + diff := monthEnd.Sub(monthStart) + return int(diff.Hours() / 24) +} + +func clamp(n, min, max int) int { + if n <= min { + return min + } + if n >= max { + return max + } + return n +} + +// ContainsTime returns true if the TimeInterval contains the given time, otherwise returns false. +func (tp TimeInterval) ContainsTime(t time.Time) bool { + if tp.Times != nil { + in := false + for _, validMinutes := range tp.Times { + if (t.Hour()*60+t.Minute()) >= validMinutes.StartMinute && (t.Hour()*60+t.Minute()) < validMinutes.EndMinute { + in = true + break + } + } + if !in { + return false + } + } + if tp.DaysOfMonth != nil { + in := false + for _, validDates := range tp.DaysOfMonth { + var begin, end int + daysInMonth := daysInMonth(t) + if validDates.Begin < 0 { + begin = daysInMonth + validDates.Begin + 1 + } else { + begin = validDates.Begin + } + if validDates.End < 0 { + end = daysInMonth + validDates.End + 1 + } else { + end = validDates.End + } + // Skip clamping if the beginning date is after the end of the month. + if begin > daysInMonth { + continue + } + // Clamp to the boundaries of the month to prevent crossing into other months. + begin = clamp(begin, -1*daysInMonth, daysInMonth) + end = clamp(end, -1*daysInMonth, daysInMonth) + if t.Day() >= begin && t.Day() <= end { + in = true + break + } + } + if !in { + return false + } + } + if tp.Months != nil { + in := false + for _, validMonths := range tp.Months { + if t.Month() >= time.Month(validMonths.Begin) && t.Month() <= time.Month(validMonths.End) { + in = true + break + } + } + if !in { + return false + } + } + if tp.Weekdays != nil { + in := false + for _, validDays := range tp.Weekdays { + if t.Weekday() >= time.Weekday(validDays.Begin) && t.Weekday() <= time.Weekday(validDays.End) { + in = true + break + } + } + if !in { + return false + } + } + if tp.Years != nil { + in := false + for _, validYears := range tp.Years { + if t.Year() >= validYears.Begin && t.Year() <= validYears.End { + in = true + break + } + } + if !in { + return false + } + } + return true +} + +// Converts a string of the form "HH:MM" into the number of minutes elapsed in the day. +func parseTime(in string) (mins int, err error) { + if !validTimeRE.MatchString(in) { + return 0, fmt.Errorf("couldn't parse timestamp %s, invalid format", in) + } + timestampComponents := strings.Split(in, ":") + if len(timestampComponents) != 2 { + return 0, fmt.Errorf("invalid timestamp format: %s", in) + } + timeStampHours, err := strconv.Atoi(timestampComponents[0]) + if err != nil { + return 0, err + } + timeStampMinutes, err := strconv.Atoi(timestampComponents[1]) + if err != nil { + return 0, err + } + if timeStampHours < 0 || timeStampHours > 24 || timeStampMinutes < 0 || timeStampMinutes > 60 { + return 0, fmt.Errorf("timestamp %s out of range", in) + } + // Timestamps are stored as minutes elapsed in the day, so multiply hours by 60. + mins = timeStampHours*60 + timeStampMinutes + return mins, nil +} + +// Converts a range that can be represented as strings (e.g. monday:wednesday) into an equivalent integer-represented range. +func stringableRangeFromString(in string, r stringableRange) (err error) { + in = strings.ToLower(in) + if strings.ContainsRune(in, ':') { + components := strings.Split(in, ":") + if len(components) != 2 { + return fmt.Errorf("couldn't parse range %s, invalid format", in) + } + start, err := r.memberFromString(components[0]) + if err != nil { + return err + } + End, err := r.memberFromString(components[1]) + if err != nil { + return err + } + r.setBegin(start) + r.setEnd(End) + return nil + } + val, err := r.memberFromString(in) + if err != nil { + return err + } + r.setBegin(val) + r.setEnd(val) + return nil +} diff --git a/vendor/github.com/prometheus/common/config/http_config.go b/vendor/github.com/prometheus/common/config/http_config.go index 07de306b54..b3726da921 100644 --- a/vendor/github.com/prometheus/common/config/http_config.go +++ b/vendor/github.com/prometheus/common/config/http_config.go @@ -17,11 +17,13 @@ package config import ( "bytes" + "context" "crypto/sha256" "crypto/tls" "crypto/x509" "fmt" "io/ioutil" + "net" "net/http" "net/url" "strings" @@ -38,6 +40,12 @@ var DefaultHTTPClientConfig = HTTPClientConfig{ FollowRedirects: true, } +// defaultHTTPClientOptions holds the default HTTP client options. +var defaultHTTPClientOptions = httpClientOptions{ + keepAlivesEnabled: true, + http2Enabled: true, +} + type closeIdler interface { CloseIdleConnections() } @@ -194,15 +202,50 @@ func (a *BasicAuth) UnmarshalYAML(unmarshal func(interface{}) error) error { return unmarshal((*plain)(a)) } +// DialContextFunc defines the signature of the DialContext() function implemented +// by net.Dialer. +type DialContextFunc func(context.Context, string, string) (net.Conn, error) + +type httpClientOptions struct { + dialContextFunc DialContextFunc + keepAlivesEnabled bool + http2Enabled bool +} + +// HTTPClientOption defines an option that can be applied to the HTTP client. +type HTTPClientOption func(options *httpClientOptions) + +// WithDialContextFunc allows you to override func gets used for the actual dialing. The default is `net.Dialer.DialContext`. +func WithDialContextFunc(fn DialContextFunc) HTTPClientOption { + return func(opts *httpClientOptions) { + opts.dialContextFunc = fn + } +} + +// WithKeepAlivesDisabled allows to disable HTTP keepalive. +func WithKeepAlivesDisabled() HTTPClientOption { + return func(opts *httpClientOptions) { + opts.keepAlivesEnabled = false + } +} + +// WithHTTP2Disabled allows to disable HTTP2. +func WithHTTP2Disabled() HTTPClientOption { + return func(opts *httpClientOptions) { + opts.http2Enabled = false + } +} + // NewClient returns a http.Client using the specified http.RoundTripper. func newClient(rt http.RoundTripper) *http.Client { return &http.Client{Transport: rt} } // NewClientFromConfig returns a new HTTP client configured for the -// given config.HTTPClientConfig. The name is used as go-conntrack metric label. -func NewClientFromConfig(cfg HTTPClientConfig, name string, disableKeepAlives, enableHTTP2 bool) (*http.Client, error) { - rt, err := NewRoundTripperFromConfig(cfg, name, disableKeepAlives, enableHTTP2) +// given config.HTTPClientConfig and config.HTTPClientOption. +// The name is used as go-conntrack metric label. +func NewClientFromConfig(cfg HTTPClientConfig, name string, optFuncs ...HTTPClientOption) (*http.Client, error) { + rt, err := NewRoundTripperFromConfig(cfg, name, optFuncs...) if err != nil { return nil, err } @@ -216,8 +259,27 @@ func NewClientFromConfig(cfg HTTPClientConfig, name string, disableKeepAlives, e } // NewRoundTripperFromConfig returns a new HTTP RoundTripper configured for the -// given config.HTTPClientConfig. The name is used as go-conntrack metric label. -func NewRoundTripperFromConfig(cfg HTTPClientConfig, name string, disableKeepAlives, enableHTTP2 bool) (http.RoundTripper, error) { +// given config.HTTPClientConfig and config.HTTPClientOption. +// The name is used as go-conntrack metric label. +func NewRoundTripperFromConfig(cfg HTTPClientConfig, name string, optFuncs ...HTTPClientOption) (http.RoundTripper, error) { + opts := defaultHTTPClientOptions + for _, f := range optFuncs { + f(&opts) + } + + var dialContext func(ctx context.Context, network, addr string) (net.Conn, error) + + if opts.dialContextFunc != nil { + dialContext = conntrack.NewDialContextFunc( + conntrack.DialWithDialContextFunc((func(context.Context, string, string) (net.Conn, error))(opts.dialContextFunc)), + conntrack.DialWithTracing(), + conntrack.DialWithName(name)) + } else { + dialContext = conntrack.NewDialContextFunc( + conntrack.DialWithTracing(), + conntrack.DialWithName(name)) + } + newRT := func(tlsConfig *tls.Config) (http.RoundTripper, error) { // The only timeout we care about is the configured scrape timeout. // It is applied on request. So we leave out any timings here. @@ -225,7 +287,7 @@ func NewRoundTripperFromConfig(cfg HTTPClientConfig, name string, disableKeepAli Proxy: http.ProxyURL(cfg.ProxyURL.URL), MaxIdleConns: 20000, MaxIdleConnsPerHost: 1000, // see https://github.com/golang/go/issues/13801 - DisableKeepAlives: disableKeepAlives, + DisableKeepAlives: !opts.keepAlivesEnabled, TLSClientConfig: tlsConfig, DisableCompression: true, // 5 minutes is typically above the maximum sane scrape interval. So we can @@ -233,12 +295,9 @@ func NewRoundTripperFromConfig(cfg HTTPClientConfig, name string, disableKeepAli IdleConnTimeout: 5 * time.Minute, TLSHandshakeTimeout: 10 * time.Second, ExpectContinueTimeout: 1 * time.Second, - DialContext: conntrack.NewDialContextFunc( - conntrack.DialWithTracing(), - conntrack.DialWithName(name), - ), + DialContext: dialContext, } - if enableHTTP2 { + if opts.http2Enabled { // HTTP/2 support is golang has many problematic cornercases where // dead connections would be kept and used in connection pools. // https://github.com/golang/go/issues/32388 diff --git a/vendor/github.com/prometheus/prometheus/NOTICE b/vendor/github.com/prometheus/prometheus/NOTICE index 5e4f509896..33f226d9f8 100644 --- a/vendor/github.com/prometheus/prometheus/NOTICE +++ b/vendor/github.com/prometheus/prometheus/NOTICE @@ -91,8 +91,13 @@ https://github.com/dgryski/go-tsz Copyright (c) 2015,2016 Damian Gryski See https://github.com/dgryski/go-tsz/blob/master/LICENSE for license details. +The Codicon icon font from Microsoft +https://github.com/microsoft/vscode-codicons +Copyright (c) Microsoft Corporation and other contributors +See https://github.com/microsoft/vscode-codicons/blob/main/LICENSE for license details. + We also use code from a large number of npm packages. For details, see: -- https://github.com/prometheus/prometheus/blob/master/web/ui/react-app/package.json -- https://github.com/prometheus/prometheus/blob/master/web/ui/react-app/package-lock.json +- https://github.com/prometheus/prometheus/blob/main/web/ui/react-app/package.json +- https://github.com/prometheus/prometheus/blob/main/web/ui/react-app/package-lock.json - The individual package licenses as copied from the node_modules directory can be found in the npm_licenses.tar.bz2 archive in release tarballs and Docker images. diff --git a/vendor/github.com/prometheus/prometheus/pkg/exemplar/exemplar.go b/vendor/github.com/prometheus/prometheus/pkg/exemplar/exemplar.go index c6ea0db94d..8e3e01b5c9 100644 --- a/vendor/github.com/prometheus/prometheus/pkg/exemplar/exemplar.go +++ b/vendor/github.com/prometheus/prometheus/pkg/exemplar/exemplar.go @@ -22,3 +22,25 @@ type Exemplar struct { HasTs bool Ts int64 } + +type QueryResult struct { + SeriesLabels labels.Labels `json:"seriesLabels"` + Exemplars []Exemplar `json:"exemplars"` +} + +// Equals compares if the exemplar e is the same as e2. Note that if HasTs is false for +// both exemplars then the timestamps will be ignored for the comparison. This can come up +// when an exemplar is exported without it's own timestamp, in which case the scrape timestamp +// is assigned to the Ts field. However we still want to treat the same exemplar, scraped without +// an exported timestamp, as a duplicate of itself for each subsequent scrape. +func (e Exemplar) Equals(e2 Exemplar) bool { + if !labels.Equal(e.Labels, e2.Labels) { + return false + } + + if (e.HasTs || e2.HasTs) && e.Ts != e2.Ts { + return false + } + + return e.Value == e2.Value +} diff --git a/vendor/github.com/prometheus/prometheus/promql/engine.go b/vendor/github.com/prometheus/prometheus/promql/engine.go index 2ed1014419..5c9caebada 100644 --- a/vendor/github.com/prometheus/prometheus/promql/engine.go +++ b/vendor/github.com/prometheus/prometheus/promql/engine.go @@ -19,6 +19,7 @@ import ( "context" "fmt" "math" + "reflect" "regexp" "runtime" "sort" @@ -211,6 +212,9 @@ type EngineOpts struct { // EnableAtModifier if true enables @ modifier. Disabled otherwise. EnableAtModifier bool + + // EnableNegativeOffset if true enables negative (-) offset values. Disabled otherwise. + EnableNegativeOffset bool } // Engine handles the lifetime of queries from beginning to end. @@ -226,6 +230,7 @@ type Engine struct { lookbackDelta time.Duration noStepSubqueryIntervalFn func(rangeMillis int64) int64 enableAtModifier bool + enableNegativeOffset bool } // NewEngine returns a new engine. @@ -307,6 +312,7 @@ func NewEngine(opts EngineOpts) *Engine { lookbackDelta: opts.LookbackDelta, noStepSubqueryIntervalFn: opts.NoStepSubqueryIntervalFn, enableAtModifier: opts.EnableAtModifier, + enableNegativeOffset: opts.EnableNegativeOffset, } } @@ -388,34 +394,53 @@ func (ng *Engine) newQuery(q storage.Queryable, expr parser.Expr, start, end tim } var ErrValidationAtModifierDisabled = errors.New("@ modifier is disabled") +var ErrValidationNegativeOffsetDisabled = errors.New("negative offset is disabled") func (ng *Engine) validateOpts(expr parser.Expr) error { - if ng.enableAtModifier { + if ng.enableAtModifier && ng.enableNegativeOffset { return nil } + var atModifierUsed, negativeOffsetUsed bool + var validationErr error parser.Inspect(expr, func(node parser.Node, path []parser.Node) error { switch n := node.(type) { case *parser.VectorSelector: if n.Timestamp != nil || n.StartOrEnd == parser.START || n.StartOrEnd == parser.END { - validationErr = ErrValidationAtModifierDisabled - return validationErr + atModifierUsed = true + } + if n.OriginalOffset < 0 { + negativeOffsetUsed = true } case *parser.MatrixSelector: vs := n.VectorSelector.(*parser.VectorSelector) if vs.Timestamp != nil || vs.StartOrEnd == parser.START || vs.StartOrEnd == parser.END { - validationErr = ErrValidationAtModifierDisabled - return validationErr + atModifierUsed = true + } + if vs.OriginalOffset < 0 { + negativeOffsetUsed = true } case *parser.SubqueryExpr: if n.Timestamp != nil || n.StartOrEnd == parser.START || n.StartOrEnd == parser.END { - validationErr = ErrValidationAtModifierDisabled - return validationErr + atModifierUsed = true + } + if n.OriginalOffset < 0 { + negativeOffsetUsed = true } } + + if atModifierUsed && !ng.enableAtModifier { + validationErr = ErrValidationAtModifierDisabled + return validationErr + } + if negativeOffsetUsed && !ng.enableNegativeOffset { + validationErr = ErrValidationNegativeOffsetDisabled + return validationErr + } + return nil }) @@ -877,6 +902,12 @@ func (ev *evaluator) Eval(expr parser.Expr) (v parser.Value, ws storage.Warnings return v, ws, nil } +// EvalSeriesHelper stores extra information about a series. +type EvalSeriesHelper struct { + // The grouping key used by aggregation. + groupingKey uint64 +} + // EvalNodeHelper stores extra information and caches for evaluating a single node across steps. type EvalNodeHelper struct { // Evaluation timestamp. @@ -937,10 +968,12 @@ func (enh *EvalNodeHelper) signatureFunc(on bool, names ...string) func(labels.L } // rangeEval evaluates the given expressions, and then for each step calls -// the given function with the values computed for each expression at that -// step. The return value is the combination into time series of all the +// the given funcCall with the values computed for each expression at that +// step. The return value is the combination into time series of all the // function call results. -func (ev *evaluator) rangeEval(funcCall func([]parser.Value, *EvalNodeHelper) (Vector, storage.Warnings), exprs ...parser.Expr) (Matrix, storage.Warnings) { +// The prepSeries function (if provided) can be used to prepare the helper +// for each series, then passed to each call funcCall. +func (ev *evaluator) rangeEval(prepSeries func(labels.Labels, *EvalSeriesHelper), funcCall func([]parser.Value, [][]EvalSeriesHelper, *EvalNodeHelper) (Vector, storage.Warnings), exprs ...parser.Expr) (Matrix, storage.Warnings) { numSteps := int((ev.endTimestamp-ev.startTimestamp)/ev.interval) + 1 matrixes := make([]Matrix, len(exprs)) origMatrixes := make([]Matrix, len(exprs)) @@ -976,6 +1009,30 @@ func (ev *evaluator) rangeEval(funcCall func([]parser.Value, *EvalNodeHelper) (V enh := &EvalNodeHelper{Out: make(Vector, 0, biggestLen)} seriess := make(map[uint64]Series, biggestLen) // Output series by series hash. tempNumSamples := ev.currentSamples + + var ( + seriesHelpers [][]EvalSeriesHelper + bufHelpers [][]EvalSeriesHelper // Buffer updated on each step + ) + + // If the series preparation function is provided, we should run it for + // every single series in the matrix. + if prepSeries != nil { + seriesHelpers = make([][]EvalSeriesHelper, len(exprs)) + bufHelpers = make([][]EvalSeriesHelper, len(exprs)) + + for i := range exprs { + seriesHelpers[i] = make([]EvalSeriesHelper, len(matrixes[i])) + bufHelpers[i] = make([]EvalSeriesHelper, len(matrixes[i])) + + for si, series := range matrixes[i] { + h := seriesHelpers[i][si] + prepSeries(series.Metric, &h) + seriesHelpers[i][si] = h + } + } + } + for ts := ev.startTimestamp; ts <= ev.endTimestamp; ts += ev.interval { if err := contextDone(ev.ctx, "expression evaluation"); err != nil { ev.error(err) @@ -985,11 +1042,20 @@ func (ev *evaluator) rangeEval(funcCall func([]parser.Value, *EvalNodeHelper) (V // Gather input vectors for this timestamp. for i := range exprs { vectors[i] = vectors[i][:0] + + if prepSeries != nil { + bufHelpers[i] = bufHelpers[i][:0] + } + for si, series := range matrixes[i] { for _, point := range series.Points { if point.T == ts { if ev.currentSamples < ev.maxSamples { vectors[i] = append(vectors[i], Sample{Metric: series.Metric, Point: point}) + if prepSeries != nil { + bufHelpers[i] = append(bufHelpers[i], seriesHelpers[i][si]) + } + // Move input vectors forward so we don't have to re-scan the same // past points at the next step. matrixes[i][si].Points = series.Points[1:] @@ -1003,9 +1069,10 @@ func (ev *evaluator) rangeEval(funcCall func([]parser.Value, *EvalNodeHelper) (V } args[i] = vectors[i] } + // Make the function call. enh.Ts = ts - result, ws := funcCall(args, enh) + result, ws := funcCall(args, bufHelpers, enh) if result.ContainsSameLabelset() { ev.errorf("vector cannot contain metrics with the same labelset") } @@ -1101,20 +1168,35 @@ func (ev *evaluator) eval(expr parser.Expr) (parser.Value, storage.Warnings) { } numSteps := int((ev.endTimestamp-ev.startTimestamp)/ev.interval) + 1 + // Create a new span to help investigate inner evaluation performances. + span, _ := opentracing.StartSpanFromContext(ev.ctx, stats.InnerEvalTime.SpanOperation()+" eval "+reflect.TypeOf(expr).String()) + defer span.Finish() + switch e := expr.(type) { case *parser.AggregateExpr: + // Grouping labels must be sorted (expected both by generateGroupingKey() and aggregation()). + sortedGrouping := e.Grouping + sort.Strings(sortedGrouping) + + // Prepare a function to initialise series helpers with the grouping key. + buf := make([]byte, 0, 1024) + initSeries := func(series labels.Labels, h *EvalSeriesHelper) { + h.groupingKey, buf = generateGroupingKey(series, sortedGrouping, e.Without, buf) + } + unwrapParenExpr(&e.Param) if s, ok := unwrapStepInvariantExpr(e.Param).(*parser.StringLiteral); ok { - return ev.rangeEval(func(v []parser.Value, enh *EvalNodeHelper) (Vector, storage.Warnings) { - return ev.aggregation(e.Op, e.Grouping, e.Without, s.Val, v[0].(Vector), enh), nil + return ev.rangeEval(initSeries, func(v []parser.Value, sh [][]EvalSeriesHelper, enh *EvalNodeHelper) (Vector, storage.Warnings) { + return ev.aggregation(e.Op, sortedGrouping, e.Without, s.Val, v[0].(Vector), sh[0], enh), nil }, e.Expr) } - return ev.rangeEval(func(v []parser.Value, enh *EvalNodeHelper) (Vector, storage.Warnings) { + + return ev.rangeEval(initSeries, func(v []parser.Value, sh [][]EvalSeriesHelper, enh *EvalNodeHelper) (Vector, storage.Warnings) { var param float64 if e.Param != nil { param = v[0].(Vector)[0].V } - return ev.aggregation(e.Op, e.Grouping, e.Without, param, v[1].(Vector), enh), nil + return ev.aggregation(e.Op, sortedGrouping, e.Without, param, v[1].(Vector), sh[1], enh), nil }, e.Param, e.Expr) case *parser.Call: @@ -1127,7 +1209,7 @@ func (ev *evaluator) eval(expr parser.Expr) (parser.Value, storage.Warnings) { arg := unwrapStepInvariantExpr(e.Args[0]) vs, ok := arg.(*parser.VectorSelector) if ok { - return ev.rangeEval(func(v []parser.Value, enh *EvalNodeHelper) (Vector, storage.Warnings) { + return ev.rangeEval(nil, func(v []parser.Value, _ [][]EvalSeriesHelper, enh *EvalNodeHelper) (Vector, storage.Warnings) { if vs.Timestamp != nil { // This is a special case only for "timestamp" since the offset // needs to be adjusted for every point. @@ -1171,7 +1253,7 @@ func (ev *evaluator) eval(expr parser.Expr) (parser.Value, storage.Warnings) { } if !matrixArg { // Does not have a matrix argument. - return ev.rangeEval(func(v []parser.Value, enh *EvalNodeHelper) (Vector, storage.Warnings) { + return ev.rangeEval(nil, func(v []parser.Value, _ [][]EvalSeriesHelper, enh *EvalNodeHelper) (Vector, storage.Warnings) { return call(v, e.Args, enh), warnings }, e.Args...) } @@ -1216,11 +1298,16 @@ func (ev *evaluator) eval(expr parser.Expr) (parser.Value, storage.Warnings) { ev.currentSamples -= len(points) points = points[:0] it.Reset(s.Iterator()) + metric := selVS.Series[i].Labels() + // The last_over_time function acts like offset; thus, it + // should keep the metric name. For all the other range + // vector functions, the only change needed is to drop the + // metric name in the output. + if e.Func.Name != "last_over_time" { + metric = dropMetricName(metric) + } ss := Series{ - // For all range vector functions, the only change to the - // output labels is dropping the metric name so just do - // it once here. - Metric: dropMetricName(selVS.Series[i].Labels()), + Metric: metric, Points: getPointSlice(numSteps), } inMatrix[0].Metric = selVS.Series[i].Labels() @@ -1333,43 +1420,43 @@ func (ev *evaluator) eval(expr parser.Expr) (parser.Value, storage.Warnings) { case *parser.BinaryExpr: switch lt, rt := e.LHS.Type(), e.RHS.Type(); { case lt == parser.ValueTypeScalar && rt == parser.ValueTypeScalar: - return ev.rangeEval(func(v []parser.Value, enh *EvalNodeHelper) (Vector, storage.Warnings) { + return ev.rangeEval(nil, func(v []parser.Value, _ [][]EvalSeriesHelper, enh *EvalNodeHelper) (Vector, storage.Warnings) { val := scalarBinop(e.Op, v[0].(Vector)[0].Point.V, v[1].(Vector)[0].Point.V) return append(enh.Out, Sample{Point: Point{V: val}}), nil }, e.LHS, e.RHS) case lt == parser.ValueTypeVector && rt == parser.ValueTypeVector: switch e.Op { case parser.LAND: - return ev.rangeEval(func(v []parser.Value, enh *EvalNodeHelper) (Vector, storage.Warnings) { + return ev.rangeEval(nil, func(v []parser.Value, _ [][]EvalSeriesHelper, enh *EvalNodeHelper) (Vector, storage.Warnings) { return ev.VectorAnd(v[0].(Vector), v[1].(Vector), e.VectorMatching, enh), nil }, e.LHS, e.RHS) case parser.LOR: - return ev.rangeEval(func(v []parser.Value, enh *EvalNodeHelper) (Vector, storage.Warnings) { + return ev.rangeEval(nil, func(v []parser.Value, _ [][]EvalSeriesHelper, enh *EvalNodeHelper) (Vector, storage.Warnings) { return ev.VectorOr(v[0].(Vector), v[1].(Vector), e.VectorMatching, enh), nil }, e.LHS, e.RHS) case parser.LUNLESS: - return ev.rangeEval(func(v []parser.Value, enh *EvalNodeHelper) (Vector, storage.Warnings) { + return ev.rangeEval(nil, func(v []parser.Value, _ [][]EvalSeriesHelper, enh *EvalNodeHelper) (Vector, storage.Warnings) { return ev.VectorUnless(v[0].(Vector), v[1].(Vector), e.VectorMatching, enh), nil }, e.LHS, e.RHS) default: - return ev.rangeEval(func(v []parser.Value, enh *EvalNodeHelper) (Vector, storage.Warnings) { + return ev.rangeEval(nil, func(v []parser.Value, _ [][]EvalSeriesHelper, enh *EvalNodeHelper) (Vector, storage.Warnings) { return ev.VectorBinop(e.Op, v[0].(Vector), v[1].(Vector), e.VectorMatching, e.ReturnBool, enh), nil }, e.LHS, e.RHS) } case lt == parser.ValueTypeVector && rt == parser.ValueTypeScalar: - return ev.rangeEval(func(v []parser.Value, enh *EvalNodeHelper) (Vector, storage.Warnings) { + return ev.rangeEval(nil, func(v []parser.Value, _ [][]EvalSeriesHelper, enh *EvalNodeHelper) (Vector, storage.Warnings) { return ev.VectorscalarBinop(e.Op, v[0].(Vector), Scalar{V: v[1].(Vector)[0].Point.V}, false, e.ReturnBool, enh), nil }, e.LHS, e.RHS) case lt == parser.ValueTypeScalar && rt == parser.ValueTypeVector: - return ev.rangeEval(func(v []parser.Value, enh *EvalNodeHelper) (Vector, storage.Warnings) { + return ev.rangeEval(nil, func(v []parser.Value, _ [][]EvalSeriesHelper, enh *EvalNodeHelper) (Vector, storage.Warnings) { return ev.VectorscalarBinop(e.Op, v[1].(Vector), Scalar{V: v[0].(Vector)[0].Point.V}, true, e.ReturnBool, enh), nil }, e.LHS, e.RHS) } case *parser.NumberLiteral: - return ev.rangeEval(func(v []parser.Value, enh *EvalNodeHelper) (Vector, storage.Warnings) { + return ev.rangeEval(nil, func(v []parser.Value, _ [][]EvalSeriesHelper, enh *EvalNodeHelper) (Vector, storage.Warnings) { return append(enh.Out, Sample{Point: Point{V: e.Val}}), nil }) @@ -1382,7 +1469,7 @@ func (ev *evaluator) eval(expr parser.Expr) (parser.Value, storage.Warnings) { ev.error(errWithWarnings{errors.Wrap(err, "expanding series"), ws}) } mat := make(Matrix, 0, len(e.Series)) - it := storage.NewBuffer(durationMilliseconds(ev.lookbackDelta)) + it := storage.NewMemoizedEmptyIterator(durationMilliseconds(ev.lookbackDelta)) for i, s := range e.Series { it.Reset(s.Iterator()) ss := Series{ @@ -1513,7 +1600,7 @@ func (ev *evaluator) vectorSelector(node *parser.VectorSelector, ts int64) (Vect ev.error(errWithWarnings{errors.Wrap(err, "expanding series"), ws}) } vec := make(Vector, 0, len(node.Series)) - it := storage.NewBuffer(durationMilliseconds(ev.lookbackDelta)) + it := storage.NewMemoizedEmptyIterator(durationMilliseconds(ev.lookbackDelta)) for i, s := range node.Series { it.Reset(s.Iterator()) @@ -1535,7 +1622,7 @@ func (ev *evaluator) vectorSelector(node *parser.VectorSelector, ts int64) (Vect } // vectorSelectorSingle evaluates a instant vector for the iterator of one time series. -func (ev *evaluator) vectorSelectorSingle(it *storage.BufferedSeriesIterator, node *parser.VectorSelector, ts int64) (int64, float64, bool) { +func (ev *evaluator) vectorSelectorSingle(it *storage.MemoizedSeriesIterator, node *parser.VectorSelector, ts int64) (int64, float64, bool) { refTime := ts - durationMilliseconds(node.Offset) var t int64 var v float64 @@ -1552,7 +1639,7 @@ func (ev *evaluator) vectorSelectorSingle(it *storage.BufferedSeriesIterator, no } if !ok || t > refTime { - t, v, ok = it.PeekBack(1) + t, v, ok = it.PeekPrev() if !ok || t < refTime-durationMilliseconds(ev.lookbackDelta) { return 0, 0, false } @@ -2033,8 +2120,9 @@ type groupedAggregation struct { reverseHeap vectorByReverseValueHeap } -// aggregation evaluates an aggregation operation on a Vector. -func (ev *evaluator) aggregation(op parser.ItemType, grouping []string, without bool, param interface{}, vec Vector, enh *EvalNodeHelper) Vector { +// aggregation evaluates an aggregation operation on a Vector. The provided grouping labels +// must be sorted. +func (ev *evaluator) aggregation(op parser.ItemType, grouping []string, without bool, param interface{}, vec Vector, seriesHelper []EvalSeriesHelper, enh *EvalNodeHelper) Vector { result := map[uint64]*groupedAggregation{} var k int64 @@ -2053,35 +2141,43 @@ func (ev *evaluator) aggregation(op parser.ItemType, grouping []string, without q = param.(float64) } var valueLabel string + var recomputeGroupingKey bool if op == parser.COUNT_VALUES { valueLabel = param.(string) if !model.LabelName(valueLabel).IsValid() { ev.errorf("invalid label name %q", valueLabel) } if !without { + // We're changing the grouping labels so we have to ensure they're still sorted + // and we have to flag to recompute the grouping key. Considering the count_values() + // operator is less frequently used than other aggregations, we're fine having to + // re-compute the grouping key on each step for this case. grouping = append(grouping, valueLabel) + sort.Strings(grouping) + recomputeGroupingKey = true } } - sort.Strings(grouping) lb := labels.NewBuilder(nil) - buf := make([]byte, 0, 1024) - for _, s := range vec { + var buf []byte + for si, s := range vec { metric := s.Metric if op == parser.COUNT_VALUES { lb.Reset(metric) lb.Set(valueLabel, strconv.FormatFloat(s.V, 'f', -1, 64)) metric = lb.Labels() + + // We've changed the metric so we have to recompute the grouping key. + recomputeGroupingKey = true } - var ( - groupingKey uint64 - ) - if without { - groupingKey, buf = metric.HashWithoutLabels(buf, grouping...) + // We can use the pre-computed grouping key unless grouping labels have changed. + var groupingKey uint64 + if !recomputeGroupingKey { + groupingKey = seriesHelper[si].groupingKey } else { - groupingKey, buf = metric.HashForLabels(buf, grouping...) + groupingKey, buf = generateGroupingKey(metric, grouping, without, buf) } group, ok := result[groupingKey] @@ -2268,6 +2364,21 @@ func (ev *evaluator) aggregation(op parser.ItemType, grouping []string, without return enh.Out } +// groupingKey builds and returns the grouping key for the given metric and +// grouping labels. +func generateGroupingKey(metric labels.Labels, grouping []string, without bool, buf []byte) (uint64, []byte) { + if without { + return metric.HashWithoutLabels(buf, grouping...) + } + + if len(grouping) == 0 { + // No need to generate any hash if there are no grouping labels. + return 0, buf + } + + return metric.HashForLabels(buf, grouping...) +} + // btos returns 1 if b is true, 0 otherwise. func btos(b bool) float64 { if b { diff --git a/vendor/github.com/prometheus/prometheus/promql/functions.go b/vendor/github.com/prometheus/prometheus/promql/functions.go index 3a96a9ecec..e497be364b 100644 --- a/vendor/github.com/prometheus/prometheus/promql/functions.go +++ b/vendor/github.com/prometheus/prometheus/promql/functions.go @@ -70,17 +70,17 @@ func extrapolatedRate(vals []parser.Value, args parser.Expressions, enh *EvalNod if len(samples.Points) < 2 { return enh.Out } - var ( - counterCorrection float64 - lastValue float64 - ) - for _, sample := range samples.Points { - if isCounter && sample.V < lastValue { - counterCorrection += lastValue + + resultValue := samples.Points[len(samples.Points)-1].V - samples.Points[0].V + if isCounter { + var lastValue float64 + for _, sample := range samples.Points { + if sample.V < lastValue { + resultValue += lastValue + } + lastValue = sample.V } - lastValue = sample.V } - resultValue := lastValue - samples.Points[0].V + counterCorrection // Duration between first/last samples and boundary of range. durationToStart := float64(samples.Points[0].T-rangeStart) / 1000 @@ -278,6 +278,23 @@ func funcSortDesc(vals []parser.Value, args parser.Expressions, enh *EvalNodeHel return Vector(byValueSorter) } +// === clamp(Vector parser.ValueTypeVector, min, max Scalar) Vector === +func funcClamp(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) Vector { + vec := vals[0].(Vector) + min := vals[1].(Vector)[0].Point.V + max := vals[2].(Vector)[0].Point.V + if max < min { + return enh.Out + } + for _, el := range vec { + enh.Out = append(enh.Out, Sample{ + Metric: enh.DropMetricName(el.Metric), + Point: Point{V: math.Max(min, math.Min(max, el.V))}, + }) + } + return enh.Out +} + // === clamp_max(Vector parser.ValueTypeVector, max Scalar) Vector === func funcClampMax(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) Vector { vec := vals[0].(Vector) @@ -383,7 +400,16 @@ func funcCountOverTime(vals []parser.Value, args parser.Expressions, enh *EvalNo }) } -// === floor(Vector parser.ValueTypeVector) Vector === +// === last_over_time(Matrix parser.ValueTypeMatrix) Vector === +func funcLastOverTime(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) Vector { + el := vals[0].(Matrix)[0] + + return append(enh.Out, Sample{ + Metric: el.Metric, + Point: Point{V: el.Points[len(el.Points)-1].V}, + }) +} + // === max_over_time(Matrix parser.ValueTypeMatrix) Vector === func funcMaxOverTime(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) Vector { return aggrOverTime(vals, enh, func(values []Point) float64 { @@ -537,6 +563,18 @@ func funcLog10(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper return simpleFunc(vals, enh, math.Log10) } +// === sgn(Vector parser.ValueTypeVector) Vector === +func funcSgn(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) Vector { + return simpleFunc(vals, enh, func(v float64) float64 { + if v < 0 { + return -1 + } else if v > 0 { + return 1 + } + return v + }) +} + // === timestamp(Vector parser.ValueTypeVector) Vector === func funcTimestamp(vals []parser.Value, args parser.Expressions, enh *EvalNodeHelper) Vector { vec := vals[0].(Vector) @@ -893,6 +931,7 @@ var FunctionCalls = map[string]FunctionCall{ "avg_over_time": funcAvgOverTime, "ceil": funcCeil, "changes": funcChanges, + "clamp": funcClamp, "clamp_max": funcClampMax, "clamp_min": funcClampMin, "count_over_time": funcCountOverTime, @@ -914,6 +953,7 @@ var FunctionCalls = map[string]FunctionCall{ "ln": funcLn, "log10": funcLog10, "log2": funcLog2, + "last_over_time": funcLastOverTime, "max_over_time": funcMaxOverTime, "min_over_time": funcMinOverTime, "minute": funcMinute, @@ -924,6 +964,7 @@ var FunctionCalls = map[string]FunctionCall{ "resets": funcResets, "round": funcRound, "scalar": funcScalar, + "sgn": funcSgn, "sort": funcSort, "sort_desc": funcSortDesc, "sqrt": funcSqrt, diff --git a/vendor/github.com/prometheus/prometheus/promql/parser/ast.go b/vendor/github.com/prometheus/prometheus/promql/parser/ast.go index a8754f2405..7762425640 100644 --- a/vendor/github.com/prometheus/prometheus/promql/parser/ast.go +++ b/vendor/github.com/prometheus/prometheus/promql/parser/ast.go @@ -316,6 +316,18 @@ func Walk(v Visitor, node Node, path []Node) error { return err } +func ExtractSelectors(expr Expr) [][]*labels.Matcher { + var selectors [][]*labels.Matcher + Inspect(expr, func(node Node, _ []Node) error { + vs, ok := node.(*VectorSelector) + if ok { + selectors = append(selectors, vs.LabelMatchers) + } + return nil + }) + return selectors +} + type inspector func(Node, []Node) error func (f inspector) Visit(node Node, path []Node) (Visitor, error) { diff --git a/vendor/github.com/prometheus/prometheus/promql/parser/functions.go b/vendor/github.com/prometheus/prometheus/promql/parser/functions.go index 4516829e55..a127cd28a4 100644 --- a/vendor/github.com/prometheus/prometheus/promql/parser/functions.go +++ b/vendor/github.com/prometheus/prometheus/promql/parser/functions.go @@ -54,6 +54,11 @@ var Functions = map[string]*Function{ ArgTypes: []ValueType{ValueTypeMatrix}, ReturnType: ValueTypeVector, }, + "clamp": { + Name: "clamp", + ArgTypes: []ValueType{ValueTypeVector, ValueTypeScalar, ValueTypeScalar}, + ReturnType: ValueTypeVector, + }, "clamp_max": { Name: "clamp_max", ArgTypes: []ValueType{ValueTypeVector, ValueTypeScalar}, @@ -149,6 +154,11 @@ var Functions = map[string]*Function{ Variadic: -1, ReturnType: ValueTypeVector, }, + "last_over_time": { + Name: "last_over_time", + ArgTypes: []ValueType{ValueTypeMatrix}, + ReturnType: ValueTypeVector, + }, "ln": { Name: "ln", ArgTypes: []ValueType{ValueTypeVector}, @@ -217,6 +227,11 @@ var Functions = map[string]*Function{ ArgTypes: []ValueType{ValueTypeVector}, ReturnType: ValueTypeScalar, }, + "sgn": { + Name: "sgn", + ArgTypes: []ValueType{ValueTypeVector}, + ReturnType: ValueTypeVector, + }, "sort": { Name: "sort", ArgTypes: []ValueType{ValueTypeVector}, diff --git a/vendor/github.com/prometheus/prometheus/promql/parser/generated_parser.y b/vendor/github.com/prometheus/prometheus/promql/parser/generated_parser.y index 6f398addfd..3f914e4ac3 100644 --- a/vendor/github.com/prometheus/prometheus/promql/parser/generated_parser.y +++ b/vendor/github.com/prometheus/prometheus/promql/parser/generated_parser.y @@ -386,6 +386,11 @@ offset_expr: expr OFFSET duration yylex.(*parser).addOffset($1, $3) $$ = $1 } + | expr OFFSET SUB duration + { + yylex.(*parser).addOffset($1, -$4) + $$ = $1 + } | expr OFFSET error { yylex.(*parser).unexpected("offset", "duration"); $$ = $1 } ; diff --git a/vendor/github.com/prometheus/prometheus/promql/parser/generated_parser.y.go b/vendor/github.com/prometheus/prometheus/promql/parser/generated_parser.y.go index 26005236bb..e0c5ceac57 100644 --- a/vendor/github.com/prometheus/prometheus/promql/parser/generated_parser.y.go +++ b/vendor/github.com/prometheus/prometheus/promql/parser/generated_parser.y.go @@ -189,13 +189,14 @@ var yyToknames = [...]string{ "START_METRIC_SELECTOR", "startSymbolsEnd", } + var yyStatenames = [...]string{} const yyEofCode = 1 const yyErrCode = 2 const yyInitialStackSize = 16 -//line generated_parser.y:742 +//line generated_parser.y:747 //line yacctab:1 var yyExca = [...]int{ @@ -203,301 +204,300 @@ var yyExca = [...]int{ 1, -1, -2, 0, -1, 33, - 1, 127, - 10, 127, - 22, 127, + 1, 128, + 10, 128, + 22, 128, -2, 0, -1, 56, - 2, 139, - 15, 139, - 61, 139, - 67, 139, - -2, 95, - -1, 57, 2, 140, 15, 140, 61, 140, 67, 140, -2, 96, - -1, 58, + -1, 57, 2, 141, 15, 141, 61, 141, 67, 141, - -2, 98, - -1, 59, + -2, 97, + -1, 58, 2, 142, 15, 142, 61, 142, 67, 142, -2, 99, - -1, 60, + -1, 59, 2, 143, 15, 143, 61, 143, 67, 143, -2, 100, - -1, 61, + -1, 60, 2, 144, 15, 144, 61, 144, 67, 144, - -2, 105, - -1, 62, + -2, 101, + -1, 61, 2, 145, 15, 145, 61, 145, 67, 145, - -2, 107, - -1, 63, + -2, 106, + -1, 62, 2, 146, 15, 146, 61, 146, 67, 146, - -2, 109, - -1, 64, + -2, 108, + -1, 63, 2, 147, 15, 147, 61, 147, 67, 147, -2, 110, - -1, 65, + -1, 64, 2, 148, 15, 148, 61, 148, 67, 148, -2, 111, - -1, 66, + -1, 65, 2, 149, 15, 149, 61, 149, 67, 149, -2, 112, - -1, 67, + -1, 66, 2, 150, 15, 150, 61, 150, 67, 150, -2, 113, - -1, 185, - 12, 192, - 13, 192, - 16, 192, - 17, 192, - 23, 192, - 26, 192, - 32, 192, - 33, 192, - 36, 192, - 42, 192, - 46, 192, - 47, 192, - 48, 192, - 49, 192, - 50, 192, - 51, 192, - 52, 192, - 53, 192, - 54, 192, - 55, 192, - 56, 192, - 57, 192, - 61, 192, - 65, 192, - 67, 192, - -2, 0, + -1, 67, + 2, 151, + 15, 151, + 61, 151, + 67, 151, + -2, 114, -1, 186, - 12, 192, - 13, 192, - 16, 192, - 17, 192, - 23, 192, - 26, 192, - 32, 192, - 33, 192, - 36, 192, - 42, 192, - 46, 192, - 47, 192, - 48, 192, - 49, 192, - 50, 192, - 51, 192, - 52, 192, - 53, 192, - 54, 192, - 55, 192, - 56, 192, - 57, 192, - 61, 192, - 65, 192, - 67, 192, + 12, 193, + 13, 193, + 16, 193, + 17, 193, + 23, 193, + 26, 193, + 32, 193, + 33, 193, + 36, 193, + 42, 193, + 46, 193, + 47, 193, + 48, 193, + 49, 193, + 50, 193, + 51, 193, + 52, 193, + 53, 193, + 54, 193, + 55, 193, + 56, 193, + 57, 193, + 61, 193, + 65, 193, + 67, 193, -2, 0, - -1, 205, - 19, 190, + -1, 187, + 12, 193, + 13, 193, + 16, 193, + 17, 193, + 23, 193, + 26, 193, + 32, 193, + 33, 193, + 36, 193, + 42, 193, + 46, 193, + 47, 193, + 48, 193, + 49, 193, + 50, 193, + 51, 193, + 52, 193, + 53, 193, + 54, 193, + 55, 193, + 56, 193, + 57, 193, + 61, 193, + 65, 193, + 67, 193, -2, 0, - -1, 252, + -1, 207, 19, 191, -2, 0, + -1, 254, + 19, 192, + -2, 0, } const yyPrivate = 57344 -const yyLast = 640 +const yyLast = 638 var yyAct = [...]int{ - - 258, 35, 209, 138, 248, 247, 145, 110, 75, 99, - 98, 143, 6, 101, 183, 123, 184, 100, 261, 102, - 185, 186, 243, 144, 149, 242, 148, 97, 49, 70, - 103, 51, 22, 50, 55, 149, 160, 237, 250, 52, - 150, 118, 68, 206, 262, 259, 148, 205, 18, 19, - 236, 150, 20, 105, 93, 106, 96, 201, 69, 104, - 204, 119, 56, 57, 58, 59, 60, 61, 62, 63, - 64, 65, 66, 67, 241, 175, 101, 13, 95, 146, - 147, 24, 102, 30, 2, 3, 4, 5, 70, 107, - 97, 157, 103, 256, 31, 240, 174, 7, 255, 112, - 263, 151, 80, 81, 156, 161, 155, 158, 153, 111, - 154, 254, 10, 90, 91, 238, 8, 93, 94, 96, - 33, 182, 72, 173, 79, 181, 187, 188, 189, 190, - 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, - 32, 95, 180, 124, 125, 126, 127, 128, 129, 130, - 131, 132, 133, 134, 135, 136, 137, 97, 117, 77, - 116, 165, 115, 167, 253, 168, 164, 114, 1, 76, - 81, 140, 239, 202, 203, 172, 152, 163, 113, 251, - 90, 91, 45, 140, 93, 244, 96, 44, 245, 246, - 170, 34, 249, 49, 70, 112, 51, 22, 50, 139, - 169, 171, 77, 177, 52, 111, 140, 68, 95, 252, - 179, 109, 76, 18, 19, 148, 46, 20, 74, 43, - 42, 122, 71, 69, 149, 41, 40, 56, 57, 58, - 59, 60, 61, 62, 63, 64, 65, 66, 67, 257, - 150, 39, 13, 120, 260, 159, 24, 38, 30, 49, - 70, 121, 51, 22, 50, 37, 36, 47, 265, 141, - 52, 54, 266, 68, 9, 9, 178, 78, 176, 18, - 19, 207, 73, 20, 142, 53, 210, 166, 48, 69, - 108, 0, 0, 56, 57, 58, 59, 60, 61, 62, - 63, 64, 65, 66, 67, 211, 0, 0, 13, 0, - 0, 0, 24, 0, 30, 221, 0, 0, 0, 227, - 0, 0, 0, 264, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 223, 224, 0, 0, 225, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 212, - 214, 216, 217, 218, 226, 228, 231, 232, 233, 234, - 235, 211, 0, 213, 215, 219, 220, 222, 229, 230, - 0, 221, 0, 0, 0, 227, 0, 0, 0, 208, + 260, 35, 211, 138, 250, 249, 146, 110, 75, 99, + 98, 101, 144, 184, 6, 185, 123, 102, 140, 100, + 186, 187, 55, 145, 245, 141, 150, 149, 263, 244, + 49, 70, 103, 51, 22, 50, 150, 118, 161, 252, + 243, 52, 151, 239, 68, 264, 261, 112, 149, 203, + 18, 19, 151, 105, 20, 106, 238, 111, 139, 104, + 69, 242, 119, 240, 56, 57, 58, 59, 60, 61, + 62, 63, 64, 65, 66, 67, 176, 107, 101, 13, + 147, 148, 158, 24, 102, 30, 2, 3, 4, 5, + 97, 258, 103, 7, 208, 157, 257, 175, 207, 166, + 70, 152, 80, 81, 165, 162, 156, 159, 154, 256, + 155, 206, 31, 90, 91, 164, 141, 93, 94, 96, + 117, 183, 116, 174, 265, 182, 188, 189, 190, 191, + 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, + 79, 95, 181, 202, 124, 125, 126, 127, 128, 129, + 130, 131, 132, 133, 134, 135, 136, 137, 255, 10, + 168, 77, 169, 153, 54, 141, 112, 9, 9, 72, + 141, 76, 32, 241, 204, 205, 111, 173, 34, 97, + 49, 70, 109, 51, 22, 50, 246, 171, 1, 247, + 248, 52, 81, 251, 68, 8, 253, 170, 172, 33, + 18, 19, 90, 91, 20, 97, 93, 46, 96, 45, + 69, 254, 44, 71, 56, 57, 58, 59, 60, 61, + 62, 63, 64, 65, 66, 67, 43, 77, 42, 13, + 95, 122, 93, 24, 96, 30, 41, 76, 40, 39, + 120, 259, 178, 74, 160, 38, 262, 49, 70, 180, + 51, 22, 50, 121, 149, 37, 95, 115, 52, 36, + 267, 68, 114, 150, 268, 47, 142, 18, 19, 179, + 78, 20, 177, 113, 209, 73, 143, 69, 53, 151, + 212, 56, 57, 58, 59, 60, 61, 62, 63, 64, + 65, 66, 67, 213, 167, 48, 13, 108, 0, 0, + 24, 0, 30, 223, 0, 0, 0, 229, 0, 0, + 0, 266, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 225, 226, 0, 0, 227, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 214, 216, 218, + 219, 220, 228, 230, 233, 234, 235, 236, 237, 213, + 0, 215, 217, 221, 222, 224, 231, 232, 0, 223, + 0, 0, 0, 229, 0, 0, 0, 210, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 225, + 226, 0, 0, 227, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 214, 216, 218, 219, 220, 228, 230, + 233, 234, 235, 236, 237, 0, 0, 215, 217, 221, + 222, 224, 231, 232, 17, 70, 0, 0, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 223, 224, 0, 0, 225, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 212, 214, 216, 217, 218, - 226, 228, 231, 232, 233, 234, 235, 0, 0, 213, - 215, 219, 220, 222, 229, 230, 17, 70, 0, 0, - 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 18, 19, 0, 0, - 20, 0, 17, 31, 0, 0, 22, 0, 0, 0, - 11, 12, 14, 15, 16, 21, 23, 25, 26, 27, - 28, 29, 18, 19, 0, 13, 20, 0, 0, 24, - 0, 30, 0, 0, 0, 0, 11, 12, 14, 15, - 16, 21, 23, 25, 26, 27, 28, 29, 97, 0, - 0, 13, 0, 0, 162, 24, 0, 30, 0, 0, - 80, 81, 82, 0, 83, 84, 85, 86, 87, 88, - 89, 90, 91, 92, 0, 93, 94, 96, 0, 0, - 0, 0, 0, 0, 97, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 80, 81, 82, 95, - 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, + 0, 0, 0, 0, 18, 19, 0, 0, 20, 0, + 17, 31, 0, 0, 22, 0, 0, 0, 11, 12, + 14, 15, 16, 21, 23, 25, 26, 27, 28, 29, + 18, 19, 0, 13, 20, 0, 0, 24, 0, 30, + 0, 0, 0, 0, 11, 12, 14, 15, 16, 21, + 23, 25, 26, 27, 28, 29, 97, 0, 0, 13, + 0, 0, 163, 24, 0, 30, 0, 0, 80, 81, + 82, 0, 83, 84, 85, 86, 87, 88, 89, 90, + 91, 92, 0, 93, 94, 96, 0, 0, 0, 0, + 0, 0, 97, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 80, 81, 82, 95, 83, 84, + 85, 86, 87, 88, 89, 90, 91, 92, 0, 93, + 94, 96, 0, 0, 97, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 80, 81, 82, 0, + 83, 84, 85, 95, 87, 88, 89, 90, 91, 92, 0, 93, 94, 96, 0, 0, 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 80, 81, - 82, 0, 83, 84, 85, 95, 87, 88, 89, 90, - 91, 92, 0, 93, 94, 96, 0, 0, 97, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 80, 81, 82, 0, 83, 84, 0, 95, 87, 88, - 0, 90, 91, 92, 0, 93, 94, 96, 0, 0, + 82, 0, 83, 84, 0, 95, 87, 88, 0, 90, + 91, 92, 0, 93, 94, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 95, + 0, 0, 0, 0, 0, 0, 0, 95, } -var yyPact = [...]int{ - 10, 87, 430, 430, 181, 404, -1000, -1000, -1000, 81, +var yyPact = [...]int{ + 12, 83, 428, 428, 168, 402, -1000, -1000, -1000, 99, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, 200, -1000, 122, -1000, 510, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 15, 77, - -1000, 237, -1000, 237, 75, -1000, -1000, -1000, -1000, -1000, + -1000, 225, -1000, 138, -1000, 508, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 17, 77, + -1000, 235, -1000, 235, 87, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - 193, -1000, -1000, 160, -1000, -1000, 156, -1000, 19, -1000, - -45, -45, -45, -45, -45, -45, -45, -45, -45, -45, - -45, -45, -45, -45, -45, 197, 9, 174, 77, -48, - -1000, 89, 89, 16, -1000, 474, 13, -1000, 159, -1000, - -1000, 161, -1000, -1000, 157, -1000, 73, -1000, 198, 237, - -1000, -50, -42, -1000, 237, 237, 237, 237, 237, 237, - 237, 237, 237, 237, 237, 237, 237, 237, -1000, -1000, - -1000, -1000, 42, -1000, -1000, -1000, -1000, -1000, -1000, 29, - 29, 41, -1000, -1000, -1000, -1000, 349, -1000, -1000, 30, - -1000, 510, -1000, -1000, 97, -1000, 72, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, 1, -2, -1000, - -1000, -1000, 143, 89, 89, 89, 89, 13, 76, 76, - 76, 574, 542, 76, 76, 574, 13, 13, 76, 13, - 143, 18, -1000, -1000, -1000, 162, -1000, 91, -1000, -1000, + 164, -1000, -1000, 255, -1000, -1000, 118, -1000, 15, -1000, + -44, -44, -44, -44, -44, -44, -44, -44, -44, -44, + -44, -44, -44, -44, -44, 16, 10, 161, 77, -50, + -1000, 80, 80, 18, -1000, 472, 191, -1000, 97, -1000, + -1000, 158, -1000, -1000, 159, -1000, 74, -1000, 237, 235, + -1000, -51, -42, -1000, 235, 235, 235, 235, 235, 235, + 235, 235, 235, 235, 235, 235, 235, 235, -1000, 107, + -1000, -1000, -1000, 34, -1000, -1000, -1000, -1000, -1000, -1000, + 31, 31, 92, -1000, -1000, -1000, -1000, 347, -1000, -1000, + 36, -1000, 508, -1000, -1000, 45, -1000, 38, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 5, 0, + -1000, -1000, -1000, 165, 80, 80, 80, 80, 191, 76, + 76, 76, 572, 540, 76, 76, 572, 191, 191, 76, + 191, 165, -1000, 19, -1000, -1000, -1000, 156, -1000, 89, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, - -1000, -1000, -1000, -1000, -1000, -1000, -1000, 237, -1000, -1000, - -1000, -1000, 28, 28, -6, -1000, -1000, -1000, -1000, -1000, - -1000, 25, 98, -1000, -1000, 293, -1000, 510, -1000, -1000, - -1000, 28, -1000, -1000, -1000, -1000, -1000, + -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, -1000, 235, + -1000, -1000, -1000, -1000, 29, 29, 4, -1000, -1000, -1000, + -1000, -1000, -1000, 26, 122, -1000, -1000, 291, -1000, 508, + -1000, -1000, -1000, 29, -1000, -1000, -1000, -1000, -1000, } -var yyPgo = [...]int{ - 0, 280, 7, 278, 2, 277, 276, 261, 275, 274, - 112, 272, 116, 8, 271, 4, 5, 268, 267, 0, - 23, 266, 6, 259, 257, 256, 10, 61, 255, 251, - 1, 247, 245, 9, 243, 34, 241, 226, 225, 221, - 220, 219, 187, 182, 216, 3, 179, 168, 140, +var yyPgo = [...]int{ + 0, 297, 7, 295, 2, 294, 280, 164, 278, 276, + 159, 275, 195, 8, 274, 4, 5, 272, 270, 0, + 23, 269, 6, 266, 265, 259, 10, 62, 255, 253, + 1, 245, 244, 9, 240, 22, 239, 238, 236, 231, + 228, 226, 212, 209, 207, 3, 196, 188, 172, } -var yyR1 = [...]int{ +var yyR1 = [...]int{ 0, 47, 47, 47, 47, 47, 47, 47, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 25, 25, 25, 25, 26, 26, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 27, 29, 29, 39, 39, 34, 34, 34, 34, 15, 15, 15, 15, 14, 14, 14, 4, 4, 31, - 33, 33, 32, 32, 32, 40, 38, 38, 24, 24, - 24, 9, 9, 36, 42, 42, 42, 42, 42, 43, - 44, 44, 44, 35, 35, 35, 1, 1, 1, 2, - 2, 2, 2, 12, 12, 7, 7, 7, 7, 7, + 33, 33, 32, 32, 32, 40, 38, 38, 38, 24, + 24, 24, 9, 9, 36, 42, 42, 42, 42, 42, + 43, 44, 44, 44, 35, 35, 35, 1, 1, 1, + 2, 2, 2, 2, 12, 12, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, - 7, 7, 7, 7, 7, 10, 10, 10, 10, 11, - 11, 11, 13, 13, 13, 13, 48, 18, 18, 18, - 18, 17, 17, 17, 17, 17, 21, 21, 21, 3, + 7, 7, 7, 7, 7, 7, 10, 10, 10, 10, + 11, 11, 11, 13, 13, 13, 13, 48, 18, 18, + 18, 18, 17, 17, 17, 17, 17, 21, 21, 21, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 3, 3, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 6, 6, 6, 6, 6, 8, 8, 5, 5, 5, - 5, 37, 20, 22, 22, 23, 23, 19, 45, 41, - 46, 46, 16, 16, + 6, 6, 6, 6, 6, 6, 8, 8, 5, 5, + 5, 5, 37, 20, 22, 22, 23, 23, 19, 45, + 41, 46, 46, 16, 16, } -var yyR2 = [...]int{ +var yyR2 = [...]int{ 0, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 2, 2, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 0, 1, 3, 3, 1, 1, 3, 3, 3, 4, 2, 1, 3, 1, 2, 1, 1, 2, - 3, 2, 3, 1, 2, 3, 3, 3, 3, 5, - 3, 1, 1, 4, 6, 6, 5, 4, 3, 2, - 2, 1, 1, 3, 4, 2, 3, 1, 2, 3, - 3, 2, 1, 2, 1, 1, 1, 1, 1, 1, + 3, 2, 3, 1, 2, 3, 3, 4, 3, 3, + 5, 3, 1, 1, 4, 6, 6, 5, 4, 3, + 2, 2, 1, 1, 3, 4, 2, 3, 1, 2, + 3, 3, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 3, 4, 2, 0, 3, - 1, 2, 3, 3, 2, 1, 2, 0, 3, 2, - 1, 1, 3, 1, 3, 4, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 3, 4, 2, 0, + 3, 1, 2, 3, 3, 2, 1, 2, 0, 3, + 2, 1, 1, 3, 1, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, - 0, 1, 0, 1, + 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, + 1, 0, 1, 0, 1, } -var yyChk = [...]int{ +var yyChk = [...]int{ -1000, -47, 74, 75, 76, 77, 2, 10, -12, -7, -10, 46, 47, 61, 48, 49, 50, 12, 32, 33, 36, 51, 16, 52, 65, 53, 54, 55, 56, 57, @@ -511,57 +511,57 @@ var yyChk = [...]int{ 2, 61, 67, 15, -33, -30, -30, -35, -1, 18, -2, 12, 2, 18, 7, 2, 4, 2, 22, -27, -34, -29, -39, 60, -27, -27, -27, -27, -27, -27, - -27, -27, -27, -27, -27, -27, -27, -27, -45, 2, - 9, -23, -9, 2, -20, -22, 70, 71, 17, 26, - 42, -45, 2, -33, -26, -15, 15, 2, -15, -32, - 20, -30, 20, 18, 7, 2, -5, 2, 4, 39, - 29, 40, 18, -13, 23, 2, -17, 5, -21, 12, - -20, -22, -30, 64, 66, 62, 63, -30, -30, -30, + -27, -27, -27, -27, -27, -27, -27, -27, -45, 42, + 2, 9, -23, -9, 2, -20, -22, 70, 71, 17, + 26, 42, -45, 2, -33, -26, -15, 15, 2, -15, + -32, 20, -30, 20, 18, 7, 2, -5, 2, 4, + 39, 29, 40, 18, -13, 23, 2, -17, 5, -21, + 12, -20, -22, -30, 64, 66, 62, 63, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, - -30, 15, -20, -20, 19, 6, 2, -14, 20, -4, - -6, 2, 46, 60, 47, 61, 48, 49, 50, 62, - 63, 12, 64, 32, 33, 36, 51, 16, 52, 65, - 66, 53, 54, 55, 56, 57, 20, 7, 18, -2, - 23, 2, 24, 24, -22, -15, -15, -16, -15, -16, - 20, -46, -45, 2, 20, 7, 2, -30, -19, 17, - -19, 24, 19, 2, 20, -4, -19, + -30, -30, -45, 15, -20, -20, 19, 6, 2, -14, + 20, -4, -6, 2, 46, 60, 47, 61, 48, 49, + 50, 62, 63, 12, 64, 32, 33, 36, 51, 16, + 52, 65, 66, 53, 54, 55, 56, 57, 20, 7, + 18, -2, 23, 2, 24, 24, -22, -15, -15, -16, + -15, -16, 20, -46, -45, 2, 20, 7, 2, -30, + -19, 17, -19, 24, 19, 2, 20, -4, -19, } -var yyDef = [...]int{ - 0, -2, 118, 118, 0, 0, 7, 6, 1, 118, - 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, - 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, - 114, 0, 2, -2, 3, 4, 8, 9, 10, 11, - 12, 13, 14, 15, 16, 17, 18, 19, 0, 101, - 181, 0, 189, 0, 81, 82, -2, -2, -2, -2, - -2, -2, -2, -2, -2, -2, -2, -2, 175, 176, - 0, 5, 93, 0, 117, 120, 0, 125, 126, 130, +var yyDef = [...]int{ + 0, -2, 119, 119, 0, 0, 7, 6, 1, 119, + 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 0, 2, -2, 3, 4, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 19, 0, 102, + 182, 0, 190, 0, 82, 83, -2, -2, -2, -2, + -2, -2, -2, -2, -2, -2, -2, -2, 176, 177, + 0, 5, 94, 0, 118, 121, 0, 126, 127, 131, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 0, 0, 0, 0, 22, - 23, 0, 0, 0, 59, 0, 79, 80, 0, 85, - 87, 0, 92, 115, 0, 121, 0, 124, 129, 0, + 23, 0, 0, 0, 59, 0, 80, 81, 0, 86, + 88, 0, 93, 116, 0, 122, 0, 125, 130, 0, 41, 46, 47, 43, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 66, 67, - 188, 68, 0, 70, 185, 186, 71, 72, 182, 0, - 0, 0, 78, 20, 21, 24, 0, 53, 25, 0, - 61, 63, 65, 83, 0, 88, 0, 91, 177, 178, - 179, 180, 116, 119, 122, 123, 128, 131, 133, 136, - 137, 138, 26, 0, 0, -2, -2, 27, 28, 29, - 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, - 40, 0, 183, 184, 73, -2, 77, 0, 52, 55, - 57, 58, 151, 152, 153, 154, 155, 156, 157, 158, - 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, - 169, 170, 171, 172, 173, 174, 60, 64, 84, 86, - 89, 90, 0, 0, 0, 44, 45, 48, 193, 49, - 69, 0, -2, 76, 50, 0, 56, 62, 132, 187, - 134, 0, 74, 75, 51, 54, 135, + 0, 0, 0, 0, 0, 0, 0, 0, 66, 0, + 68, 189, 69, 0, 71, 186, 187, 72, 73, 183, + 0, 0, 0, 79, 20, 21, 24, 0, 53, 25, + 0, 61, 63, 65, 84, 0, 89, 0, 92, 178, + 179, 180, 181, 117, 120, 123, 124, 129, 132, 134, + 137, 138, 139, 26, 0, 0, -2, -2, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 67, 0, 184, 185, 74, -2, 78, 0, + 52, 55, 57, 58, 152, 153, 154, 155, 156, 157, + 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, + 168, 169, 170, 171, 172, 173, 174, 175, 60, 64, + 85, 87, 90, 91, 0, 0, 0, 44, 45, 48, + 194, 49, 70, 0, -2, 77, 50, 0, 56, 62, + 133, 188, 135, 0, 75, 76, 51, 54, 136, } -var yyTok1 = [...]int{ +var yyTok1 = [...]int{ 1, } -var yyTok2 = [...]int{ +var yyTok2 = [...]int{ 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, @@ -571,6 +571,7 @@ var yyTok2 = [...]int{ 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, } + var yyTok3 = [...]int{ 0, } @@ -1244,36 +1245,43 @@ yydefault: yyVAL.node = yyDollar[1].node } case 67: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-4 : yypt+1] //line generated_parser.y:390 { - yylex.(*parser).unexpected("offset", "duration") + yylex.(*parser).addOffset(yyDollar[1].node, -yyDollar[4].duration) yyVAL.node = yyDollar[1].node } case 68: yyDollar = yyS[yypt-3 : yypt+1] -//line generated_parser.y:397 +//line generated_parser.y:395 { - yylex.(*parser).setTimestamp(yyDollar[1].node, yyDollar[3].float) + yylex.(*parser).unexpected("offset", "duration") yyVAL.node = yyDollar[1].node } case 69: - yyDollar = yyS[yypt-5 : yypt+1] + yyDollar = yyS[yypt-3 : yypt+1] //line generated_parser.y:402 { - yylex.(*parser).setAtModifierPreprocessor(yyDollar[1].node, yyDollar[3].item) + yylex.(*parser).setTimestamp(yyDollar[1].node, yyDollar[3].float) yyVAL.node = yyDollar[1].node } case 70: - yyDollar = yyS[yypt-3 : yypt+1] + yyDollar = yyS[yypt-5 : yypt+1] //line generated_parser.y:407 + { + yylex.(*parser).setAtModifierPreprocessor(yyDollar[1].node, yyDollar[3].item) + yyVAL.node = yyDollar[1].node + } + case 71: + yyDollar = yyS[yypt-3 : yypt+1] +//line generated_parser.y:412 { yylex.(*parser).unexpected("@", "timestamp") yyVAL.node = yyDollar[1].node } - case 73: + case 74: yyDollar = yyS[yypt-4 : yypt+1] -//line generated_parser.y:417 +//line generated_parser.y:422 { var errMsg string vs, ok := yyDollar[1].node.(*VectorSelector) @@ -1296,9 +1304,9 @@ yydefault: EndPos: yylex.(*parser).lastClosing, } } - case 74: + case 75: yyDollar = yyS[yypt-6 : yypt+1] -//line generated_parser.y:442 +//line generated_parser.y:447 { yyVAL.node = &SubqueryExpr{ Expr: yyDollar[1].node.(Expr), @@ -1308,37 +1316,37 @@ yydefault: EndPos: yyDollar[6].item.Pos + 1, } } - case 75: + case 76: yyDollar = yyS[yypt-6 : yypt+1] -//line generated_parser.y:452 +//line generated_parser.y:457 { yylex.(*parser).unexpected("subquery selector", "\"]\"") yyVAL.node = yyDollar[1].node } - case 76: + case 77: yyDollar = yyS[yypt-5 : yypt+1] -//line generated_parser.y:454 +//line generated_parser.y:459 { yylex.(*parser).unexpected("subquery selector", "duration or \"]\"") yyVAL.node = yyDollar[1].node } - case 77: + case 78: yyDollar = yyS[yypt-4 : yypt+1] -//line generated_parser.y:456 +//line generated_parser.y:461 { yylex.(*parser).unexpected("subquery or range", "\":\" or \"]\"") yyVAL.node = yyDollar[1].node } - case 78: + case 79: yyDollar = yyS[yypt-3 : yypt+1] -//line generated_parser.y:458 +//line generated_parser.y:463 { yylex.(*parser).unexpected("subquery selector", "duration") yyVAL.node = yyDollar[1].node } - case 79: + case 80: yyDollar = yyS[yypt-2 : yypt+1] -//line generated_parser.y:468 +//line generated_parser.y:473 { if nl, ok := yyDollar[2].node.(*NumberLiteral); ok { if yyDollar[1].item.Typ == SUB { @@ -1350,9 +1358,9 @@ yydefault: yyVAL.node = &UnaryExpr{Op: yyDollar[1].item.Typ, Expr: yyDollar[2].node.(Expr), StartPos: yyDollar[1].item.Pos} } } - case 80: + case 81: yyDollar = yyS[yypt-2 : yypt+1] -//line generated_parser.y:486 +//line generated_parser.y:491 { vs := yyDollar[2].node.(*VectorSelector) vs.PosRange = mergeRanges(&yyDollar[1].item, vs) @@ -1360,9 +1368,9 @@ yydefault: yylex.(*parser).assembleVectorSelector(vs) yyVAL.node = vs } - case 81: + case 82: yyDollar = yyS[yypt-1 : yypt+1] -//line generated_parser.y:494 +//line generated_parser.y:499 { vs := &VectorSelector{ Name: yyDollar[1].item.Val, @@ -1372,44 +1380,44 @@ yydefault: yylex.(*parser).assembleVectorSelector(vs) yyVAL.node = vs } - case 82: + case 83: yyDollar = yyS[yypt-1 : yypt+1] -//line generated_parser.y:504 +//line generated_parser.y:509 { vs := yyDollar[1].node.(*VectorSelector) yylex.(*parser).assembleVectorSelector(vs) yyVAL.node = vs } - case 83: + case 84: yyDollar = yyS[yypt-3 : yypt+1] -//line generated_parser.y:512 +//line generated_parser.y:517 { yyVAL.node = &VectorSelector{ LabelMatchers: yyDollar[2].matchers, PosRange: mergeRanges(&yyDollar[1].item, &yyDollar[3].item), } } - case 84: + case 85: yyDollar = yyS[yypt-4 : yypt+1] -//line generated_parser.y:519 +//line generated_parser.y:524 { yyVAL.node = &VectorSelector{ LabelMatchers: yyDollar[2].matchers, PosRange: mergeRanges(&yyDollar[1].item, &yyDollar[4].item), } } - case 85: + case 86: yyDollar = yyS[yypt-2 : yypt+1] -//line generated_parser.y:526 +//line generated_parser.y:531 { yyVAL.node = &VectorSelector{ LabelMatchers: []*labels.Matcher{}, PosRange: mergeRanges(&yyDollar[1].item, &yyDollar[2].item), } } - case 86: + case 87: yyDollar = yyS[yypt-3 : yypt+1] -//line generated_parser.y:535 +//line generated_parser.y:540 { if yyDollar[1].matchers != nil { yyVAL.matchers = append(yyDollar[1].matchers, yyDollar[3].matcher) @@ -1417,196 +1425,196 @@ yydefault: yyVAL.matchers = yyDollar[1].matchers } } - case 87: + case 88: yyDollar = yyS[yypt-1 : yypt+1] -//line generated_parser.y:543 +//line generated_parser.y:548 { yyVAL.matchers = []*labels.Matcher{yyDollar[1].matcher} } - case 88: + case 89: yyDollar = yyS[yypt-2 : yypt+1] -//line generated_parser.y:545 +//line generated_parser.y:550 { yylex.(*parser).unexpected("label matching", "\",\" or \"}\"") yyVAL.matchers = yyDollar[1].matchers } - case 89: + case 90: yyDollar = yyS[yypt-3 : yypt+1] -//line generated_parser.y:549 +//line generated_parser.y:554 { yyVAL.matcher = yylex.(*parser).newLabelMatcher(yyDollar[1].item, yyDollar[2].item, yyDollar[3].item) } - case 90: + case 91: yyDollar = yyS[yypt-3 : yypt+1] -//line generated_parser.y:551 +//line generated_parser.y:556 { yylex.(*parser).unexpected("label matching", "string") yyVAL.matcher = nil } - case 91: + case 92: yyDollar = yyS[yypt-2 : yypt+1] -//line generated_parser.y:553 +//line generated_parser.y:558 { yylex.(*parser).unexpected("label matching", "label matching operator") yyVAL.matcher = nil } - case 92: + case 93: yyDollar = yyS[yypt-1 : yypt+1] -//line generated_parser.y:555 +//line generated_parser.y:560 { yylex.(*parser).unexpected("label matching", "identifier or \"}\"") yyVAL.matcher = nil } - case 93: + case 94: yyDollar = yyS[yypt-2 : yypt+1] -//line generated_parser.y:563 +//line generated_parser.y:568 { yyVAL.labels = append(yyDollar[2].labels, labels.Label{Name: labels.MetricName, Value: yyDollar[1].item.Val}) sort.Sort(yyVAL.labels) } - case 94: + case 95: yyDollar = yyS[yypt-1 : yypt+1] -//line generated_parser.y:565 +//line generated_parser.y:570 { yyVAL.labels = yyDollar[1].labels } - case 115: + case 116: yyDollar = yyS[yypt-3 : yypt+1] -//line generated_parser.y:572 +//line generated_parser.y:577 { yyVAL.labels = labels.New(yyDollar[2].labels...) } - case 116: + case 117: yyDollar = yyS[yypt-4 : yypt+1] -//line generated_parser.y:574 +//line generated_parser.y:579 { yyVAL.labels = labels.New(yyDollar[2].labels...) } - case 117: + case 118: yyDollar = yyS[yypt-2 : yypt+1] -//line generated_parser.y:576 +//line generated_parser.y:581 { yyVAL.labels = labels.New() } - case 118: + case 119: yyDollar = yyS[yypt-0 : yypt+1] -//line generated_parser.y:578 +//line generated_parser.y:583 { yyVAL.labels = labels.New() } - case 119: + case 120: yyDollar = yyS[yypt-3 : yypt+1] -//line generated_parser.y:582 +//line generated_parser.y:587 { yyVAL.labels = append(yyDollar[1].labels, yyDollar[3].label) } - case 120: + case 121: yyDollar = yyS[yypt-1 : yypt+1] -//line generated_parser.y:584 +//line generated_parser.y:589 { yyVAL.labels = []labels.Label{yyDollar[1].label} } - case 121: + case 122: yyDollar = yyS[yypt-2 : yypt+1] -//line generated_parser.y:586 +//line generated_parser.y:591 { yylex.(*parser).unexpected("label set", "\",\" or \"}\"") yyVAL.labels = yyDollar[1].labels } - case 122: + case 123: yyDollar = yyS[yypt-3 : yypt+1] -//line generated_parser.y:591 +//line generated_parser.y:596 { yyVAL.label = labels.Label{Name: yyDollar[1].item.Val, Value: yylex.(*parser).unquoteString(yyDollar[3].item.Val)} } - case 123: + case 124: yyDollar = yyS[yypt-3 : yypt+1] -//line generated_parser.y:593 +//line generated_parser.y:598 { yylex.(*parser).unexpected("label set", "string") yyVAL.label = labels.Label{} } - case 124: + case 125: yyDollar = yyS[yypt-2 : yypt+1] -//line generated_parser.y:595 +//line generated_parser.y:600 { yylex.(*parser).unexpected("label set", "\"=\"") yyVAL.label = labels.Label{} } - case 125: + case 126: yyDollar = yyS[yypt-1 : yypt+1] -//line generated_parser.y:597 +//line generated_parser.y:602 { yylex.(*parser).unexpected("label set", "identifier or \"}\"") yyVAL.label = labels.Label{} } - case 126: + case 127: yyDollar = yyS[yypt-2 : yypt+1] -//line generated_parser.y:605 +//line generated_parser.y:610 { yylex.(*parser).generatedParserResult = &seriesDescription{ labels: yyDollar[1].labels, values: yyDollar[2].series, } } - case 127: + case 128: yyDollar = yyS[yypt-0 : yypt+1] -//line generated_parser.y:614 +//line generated_parser.y:619 { yyVAL.series = []SequenceValue{} } - case 128: + case 129: yyDollar = yyS[yypt-3 : yypt+1] -//line generated_parser.y:616 +//line generated_parser.y:621 { yyVAL.series = append(yyDollar[1].series, yyDollar[3].series...) } - case 129: + case 130: yyDollar = yyS[yypt-2 : yypt+1] -//line generated_parser.y:618 +//line generated_parser.y:623 { yyVAL.series = yyDollar[1].series } - case 130: + case 131: yyDollar = yyS[yypt-1 : yypt+1] -//line generated_parser.y:620 +//line generated_parser.y:625 { yylex.(*parser).unexpected("series values", "") yyVAL.series = nil } - case 131: + case 132: yyDollar = yyS[yypt-1 : yypt+1] -//line generated_parser.y:624 +//line generated_parser.y:629 { yyVAL.series = []SequenceValue{{Omitted: true}} } - case 132: + case 133: yyDollar = yyS[yypt-3 : yypt+1] -//line generated_parser.y:626 +//line generated_parser.y:631 { yyVAL.series = []SequenceValue{} for i := uint64(0); i < yyDollar[3].uint; i++ { yyVAL.series = append(yyVAL.series, SequenceValue{Omitted: true}) } } - case 133: + case 134: yyDollar = yyS[yypt-1 : yypt+1] -//line generated_parser.y:633 +//line generated_parser.y:638 { yyVAL.series = []SequenceValue{{Value: yyDollar[1].float}} } - case 134: + case 135: yyDollar = yyS[yypt-3 : yypt+1] -//line generated_parser.y:635 +//line generated_parser.y:640 { yyVAL.series = []SequenceValue{} for i := uint64(0); i <= yyDollar[3].uint; i++ { yyVAL.series = append(yyVAL.series, SequenceValue{Value: yyDollar[1].float}) } } - case 135: + case 136: yyDollar = yyS[yypt-4 : yypt+1] -//line generated_parser.y:642 +//line generated_parser.y:647 { yyVAL.series = []SequenceValue{} for i := uint64(0); i <= yyDollar[4].uint; i++ { @@ -1614,45 +1622,45 @@ yydefault: yyDollar[1].float += yyDollar[2].float } } - case 136: + case 137: yyDollar = yyS[yypt-1 : yypt+1] -//line generated_parser.y:652 +//line generated_parser.y:657 { if yyDollar[1].item.Val != "stale" { yylex.(*parser).unexpected("series values", "number or \"stale\"") } yyVAL.float = math.Float64frombits(value.StaleNaN) } - case 181: + case 182: yyDollar = yyS[yypt-1 : yypt+1] -//line generated_parser.y:683 +//line generated_parser.y:688 { yyVAL.node = &NumberLiteral{ Val: yylex.(*parser).number(yyDollar[1].item.Val), PosRange: yyDollar[1].item.PositionRange(), } } - case 182: + case 183: yyDollar = yyS[yypt-1 : yypt+1] -//line generated_parser.y:691 +//line generated_parser.y:696 { yyVAL.float = yylex.(*parser).number(yyDollar[1].item.Val) } - case 183: + case 184: yyDollar = yyS[yypt-2 : yypt+1] -//line generated_parser.y:693 +//line generated_parser.y:698 { yyVAL.float = yyDollar[2].float } - case 184: + case 185: yyDollar = yyS[yypt-2 : yypt+1] -//line generated_parser.y:694 +//line generated_parser.y:699 { yyVAL.float = -yyDollar[2].float } - case 187: + case 188: yyDollar = yyS[yypt-1 : yypt+1] -//line generated_parser.y:700 +//line generated_parser.y:705 { var err error yyVAL.uint, err = strconv.ParseUint(yyDollar[1].item.Val, 10, 64) @@ -1660,9 +1668,9 @@ yydefault: yylex.(*parser).addParseErrf(yyDollar[1].item.PositionRange(), "invalid repetition in series values: %s", err) } } - case 188: + case 189: yyDollar = yyS[yypt-1 : yypt+1] -//line generated_parser.y:710 +//line generated_parser.y:715 { var err error yyVAL.duration, err = parseDuration(yyDollar[1].item.Val) @@ -1670,24 +1678,24 @@ yydefault: yylex.(*parser).addParseErr(yyDollar[1].item.PositionRange(), err) } } - case 189: + case 190: yyDollar = yyS[yypt-1 : yypt+1] -//line generated_parser.y:721 +//line generated_parser.y:726 { yyVAL.node = &StringLiteral{ Val: yylex.(*parser).unquoteString(yyDollar[1].item.Val), PosRange: yyDollar[1].item.PositionRange(), } } - case 190: + case 191: yyDollar = yyS[yypt-0 : yypt+1] -//line generated_parser.y:734 +//line generated_parser.y:739 { yyVAL.duration = 0 } - case 192: + case 193: yyDollar = yyS[yypt-0 : yypt+1] -//line generated_parser.y:738 +//line generated_parser.y:743 { yyVAL.strings = nil } diff --git a/vendor/github.com/prometheus/prometheus/promql/parser/lex.go b/vendor/github.com/prometheus/prometheus/promql/parser/lex.go index ece762dc4d..313bd8f88b 100644 --- a/vendor/github.com/prometheus/prometheus/promql/parser/lex.go +++ b/vendor/github.com/prometheus/prometheus/promql/parser/lex.go @@ -583,8 +583,12 @@ func lexEscape(l *Lexer) stateFn { return lexString } x = x*base + d - ch = l.next() n-- + + // Don't seek after last rune. + if n > 0 { + ch = l.next() + } } if x > max || 0xD800 <= x && x < 0xE000 { diff --git a/vendor/github.com/prometheus/prometheus/promql/parser/printer.go b/vendor/github.com/prometheus/prometheus/promql/parser/printer.go index 0b6368ed24..c5f80eb0b6 100644 --- a/vendor/github.com/prometheus/prometheus/promql/parser/printer.go +++ b/vendor/github.com/prometheus/prometheus/promql/parser/printer.go @@ -116,8 +116,10 @@ func (node *MatrixSelector) String() string { // Copy the Vector selector before changing the offset vecSelector := *node.VectorSelector.(*VectorSelector) offset := "" - if vecSelector.OriginalOffset != time.Duration(0) { + if vecSelector.OriginalOffset > time.Duration(0) { offset = fmt.Sprintf(" offset %s", model.Duration(vecSelector.OriginalOffset)) + } else if vecSelector.OriginalOffset < time.Duration(0) { + offset = fmt.Sprintf(" offset -%s", model.Duration(-vecSelector.OriginalOffset)) } at := "" if vecSelector.Timestamp != nil { @@ -147,8 +149,10 @@ func (node *SubqueryExpr) String() string { step = model.Duration(node.Step).String() } offset := "" - if node.OriginalOffset != time.Duration(0) { + if node.OriginalOffset > time.Duration(0) { offset = fmt.Sprintf(" offset %s", model.Duration(node.OriginalOffset)) + } else if node.OriginalOffset < time.Duration(0) { + offset = fmt.Sprintf(" offset -%s", model.Duration(-node.OriginalOffset)) } at := "" if node.Timestamp != nil { @@ -187,8 +191,10 @@ func (node *VectorSelector) String() string { labelStrings = append(labelStrings, matcher.String()) } offset := "" - if node.OriginalOffset != time.Duration(0) { + if node.OriginalOffset > time.Duration(0) { offset = fmt.Sprintf(" offset %s", model.Duration(node.OriginalOffset)) + } else if node.OriginalOffset < time.Duration(0) { + offset = fmt.Sprintf(" offset -%s", model.Duration(-node.OriginalOffset)) } at := "" if node.Timestamp != nil { diff --git a/vendor/github.com/prometheus/prometheus/promql/test.go b/vendor/github.com/prometheus/prometheus/promql/test.go index 77e133eed4..a60b408907 100644 --- a/vendor/github.com/prometheus/prometheus/promql/test.go +++ b/vendor/github.com/prometheus/prometheus/promql/test.go @@ -108,6 +108,15 @@ func (t *Test) TSDB() *tsdb.DB { return t.storage.DB } +// ExemplarStorage returns the test's exemplar storage. +func (t *Test) ExemplarStorage() storage.ExemplarStorage { + return t.storage +} + +func (t *Test) ExemplarQueryable() storage.ExemplarQueryable { + return t.storage.ExemplarQueryable() +} + func raise(line int, format string, v ...interface{}) error { return &parser.ParseErr{ LineOffset: line, @@ -307,7 +316,7 @@ func (cmd *loadCmd) append(a storage.Appender) error { m := cmd.metrics[h] for _, s := range smpls { - if _, err := a.Add(m, s.T, s.V); err != nil { + if _, err := a.Append(0, m, s.T, s.V); err != nil { return err } } @@ -657,7 +666,8 @@ type LazyLoader struct { loadCmd *loadCmd - storage storage.Storage + storage storage.Storage + SubqueryInterval time.Duration queryEngine *Engine context context.Context @@ -710,11 +720,12 @@ func (ll *LazyLoader) clear() { ll.storage = teststorage.New(ll) opts := EngineOpts{ - Logger: nil, - Reg: nil, - MaxSamples: 10000, - Timeout: 100 * time.Second, - EnableAtModifier: true, + Logger: nil, + Reg: nil, + MaxSamples: 10000, + Timeout: 100 * time.Second, + NoStepSubqueryIntervalFn: func(int64) int64 { return durationMilliseconds(ll.SubqueryInterval) }, + EnableAtModifier: true, } ll.queryEngine = NewEngine(opts) @@ -732,7 +743,7 @@ func (ll *LazyLoader) appendTill(ts int64) error { ll.loadCmd.defs[h] = smpls[i:] break } - if _, err := app.Add(m, s.T, s.V); err != nil { + if _, err := app.Append(0, m, s.T, s.V); err != nil { return err } if i == len(smpls)-1 { diff --git a/vendor/github.com/prometheus/prometheus/storage/fanout.go b/vendor/github.com/prometheus/prometheus/storage/fanout.go index 4bc3db12d9..b737d63008 100644 --- a/vendor/github.com/prometheus/prometheus/storage/fanout.go +++ b/vendor/github.com/prometheus/prometheus/storage/fanout.go @@ -20,6 +20,7 @@ import ( "github.com/go-kit/kit/log/level" "github.com/prometheus/common/model" + "github.com/prometheus/prometheus/pkg/exemplar" "github.com/prometheus/prometheus/pkg/labels" tsdb_errors "github.com/prometheus/prometheus/tsdb/errors" ) @@ -143,31 +144,32 @@ type fanoutAppender struct { secondaries []Appender } -func (f *fanoutAppender) Add(l labels.Labels, t int64, v float64) (uint64, error) { - ref, err := f.primary.Add(l, t, v) +func (f *fanoutAppender) Append(ref uint64, l labels.Labels, t int64, v float64) (uint64, error) { + ref, err := f.primary.Append(ref, l, t, v) if err != nil { return ref, err } for _, appender := range f.secondaries { - if _, err := appender.Add(l, t, v); err != nil { + if _, err := appender.Append(ref, l, t, v); err != nil { return 0, err } } return ref, nil } -func (f *fanoutAppender) AddFast(ref uint64, t int64, v float64) error { - if err := f.primary.AddFast(ref, t, v); err != nil { - return err +func (f *fanoutAppender) AppendExemplar(ref uint64, l labels.Labels, e exemplar.Exemplar) (uint64, error) { + ref, err := f.primary.AppendExemplar(ref, l, e) + if err != nil { + return ref, err } for _, appender := range f.secondaries { - if err := appender.AddFast(ref, t, v); err != nil { - return err + if _, err := appender.AppendExemplar(ref, l, e); err != nil { + return 0, err } } - return nil + return ref, nil } func (f *fanoutAppender) Commit() (err error) { diff --git a/vendor/github.com/prometheus/prometheus/storage/interface.go b/vendor/github.com/prometheus/prometheus/storage/interface.go index 711c253a76..5ddc300b34 100644 --- a/vendor/github.com/prometheus/prometheus/storage/interface.go +++ b/vendor/github.com/prometheus/prometheus/storage/interface.go @@ -17,6 +17,7 @@ import ( "context" "errors" + "github.com/prometheus/prometheus/pkg/exemplar" "github.com/prometheus/prometheus/pkg/labels" "github.com/prometheus/prometheus/tsdb/chunkenc" "github.com/prometheus/prometheus/tsdb/chunks" @@ -28,6 +29,7 @@ var ( ErrOutOfOrderSample = errors.New("out of order sample") ErrDuplicateSampleForTimestamp = errors.New("duplicate sample for timestamp") ErrOutOfBounds = errors.New("out of bounds") + ErrOutOfOrderExemplar = errors.New("out of order exemplar") ) // Appendable allows creating appenders. @@ -45,7 +47,7 @@ type SampleAndChunkQueryable interface { } // Storage ingests and manages samples, along with various indexes. All methods -// are goroutine-safe. Storage implements storage.SampleAppender. +// are goroutine-safe. Storage implements storage.Appender. type Storage interface { SampleAndChunkQueryable Appendable @@ -57,6 +59,13 @@ type Storage interface { Close() error } +// ExemplarStorage ingests and manages exemplars, along with various indexes. All methods are +// goroutine-safe. ExemplarStorage implements storage.ExemplarAppender and storage.ExemplarQuerier. +type ExemplarStorage interface { + ExemplarQueryable + ExemplarAppender +} + // A Queryable handles queries against a storage. // Use it when you need to have access to all samples without chunk encoding abstraction e.g promQL. type Queryable interface { @@ -107,6 +116,18 @@ type LabelQuerier interface { Close() error } +type ExemplarQueryable interface { + // ExemplarQuerier returns a new ExemplarQuerier on the storage. + ExemplarQuerier(ctx context.Context) (ExemplarQuerier, error) +} + +// Querier provides reading access to time series data. +type ExemplarQuerier interface { + // Select all the exemplars that match the matchers. + // Within a single slice of matchers, it is an intersection. Between the slices, it is a union. + Select(start, end int64, matchers ...[]*labels.Matcher) ([]exemplar.QueryResult, error) +} + // SelectHints specifies hints passed for data selections. // This is used only as an option for implementation to use. type SelectHints struct { @@ -136,18 +157,15 @@ func (f QueryableFunc) Querier(ctx context.Context, mint, maxt int64) (Querier, // // Operations on the Appender interface are not goroutine-safe. type Appender interface { - // Add adds a sample pair for the given series. A reference number is - // returned which can be used to add further samples in the same or later - // transactions. + // Append adds a sample pair for the given series. + // An optional reference number can be provided to accelerate calls. + // A reference number is returned which can be used to add further + // samples in the same or later transactions. // Returned reference numbers are ephemeral and may be rejected in calls - // to AddFast() at any point. Adding the sample via Add() returns a new + // to Append() at any point. Adding the sample via Append() returns a new // reference number. // If the reference is 0 it must not be used for caching. - Add(l labels.Labels, t int64, v float64) (uint64, error) - - // AddFast adds a sample pair for the referenced series. It is generally - // faster than adding a sample by providing its full label set. - AddFast(ref uint64, t int64, v float64) error + Append(ref uint64, l labels.Labels, t int64, v float64) (uint64, error) // Commit submits the collected samples and purges the batch. If Commit // returns a non-nil error, it also rolls back all modifications made in @@ -158,12 +176,40 @@ type Appender interface { // Rollback rolls back all modifications made in the appender so far. // Appender has to be discarded after rollback. Rollback() error + + ExemplarAppender +} + +// GetRef is an extra interface on Appenders used by downstream projects +// (e.g. Cortex) to avoid maintaining a parallel set of references. +type GetRef interface { + // Returns reference number that can be used to pass to Appender.Append(), + // and a set of labels that will not cause another copy when passed to Appender.Append(). + // 0 means the appender does not have a reference to this series. + GetRef(lset labels.Labels) (uint64, labels.Labels) +} + +// ExemplarAppender provides an interface for adding samples to exemplar storage, which +// within Prometheus is in-memory only. +type ExemplarAppender interface { + // AppendExemplar adds an exemplar for the given series labels. + // An optional reference number can be provided to accelerate calls. + // A reference number is returned which can be used to add further + // exemplars in the same or later transactions. + // Returned reference numbers are ephemeral and may be rejected in calls + // to Append() at any point. Adding the sample via Append() returns a new + // reference number. + // If the reference is 0 it must not be used for caching. + // Note that in our current implementation of Prometheus' exemplar storage + // calls to Append should generate the reference numbers, AppendExemplar + // generating a new reference number should be considered possible erroneous behaviour and be logged. + AppendExemplar(ref uint64, l labels.Labels, e exemplar.Exemplar) (uint64, error) } // SeriesSet contains a set of series. type SeriesSet interface { Next() bool - // At returns full series. Returned series should be iteratable even after Next is called. + // At returns full series. Returned series should be iterable even after Next is called. At() Series // The error that iteration as failed with. // When an error occurs, set cannot continue to iterate. @@ -218,13 +264,13 @@ func ErrChunkSeriesSet(err error) ChunkSeriesSet { // Series exposes a single time series and allows iterating over samples. type Series interface { Labels - SampleIteratable + SampleIterable } // ChunkSeriesSet contains a set of chunked series. type ChunkSeriesSet interface { Next() bool - // At returns full chunk series. Returned series should be iteratable even after Next is called. + // At returns full chunk series. Returned series should be iterable even after Next is called. At() ChunkSeries // The error that iteration has failed with. // When an error occurs, set cannot continue to iterate. @@ -237,7 +283,7 @@ type ChunkSeriesSet interface { // ChunkSeries exposes a single time series and allows iterating over chunks. type ChunkSeries interface { Labels - ChunkIteratable + ChunkIterable } // Labels represents an item that has labels e.g. time series. @@ -246,12 +292,12 @@ type Labels interface { Labels() labels.Labels } -type SampleIteratable interface { +type SampleIterable interface { // Iterator returns a new, independent iterator of the data of the series. Iterator() chunkenc.Iterator } -type ChunkIteratable interface { +type ChunkIterable interface { // Iterator returns a new, independent iterator that iterates over potentially overlapping // chunks of the series, sorted by min time. Iterator() chunks.Iterator diff --git a/vendor/github.com/prometheus/prometheus/storage/memoized_iterator.go b/vendor/github.com/prometheus/prometheus/storage/memoized_iterator.go new file mode 100644 index 0000000000..0c40bb9d0e --- /dev/null +++ b/vendor/github.com/prometheus/prometheus/storage/memoized_iterator.go @@ -0,0 +1,123 @@ +// Copyright 2021 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package storage + +import ( + "math" + + "github.com/prometheus/prometheus/tsdb/chunkenc" +) + +// MemoizedSeriesIterator wraps an iterator with a buffer to look back the previous element. +type MemoizedSeriesIterator struct { + it chunkenc.Iterator + delta int64 + + lastTime int64 + ok bool + + // Keep track of the previously returned value. + prevTime int64 + prevValue float64 +} + +// NewMemoizedEmptyIterator is like NewMemoizedIterator but it's initialised with an empty iterator. +func NewMemoizedEmptyIterator(delta int64) *MemoizedSeriesIterator { + return NewMemoizedIterator(chunkenc.NewNopIterator(), delta) +} + +// NewMemoizedIterator returns a new iterator that buffers the values within the +// time range of the current element and the duration of delta before. +func NewMemoizedIterator(it chunkenc.Iterator, delta int64) *MemoizedSeriesIterator { + bit := &MemoizedSeriesIterator{ + delta: delta, + prevTime: math.MinInt64, + } + bit.Reset(it) + + return bit +} + +// Reset the internal state to reuse the wrapper with the provided iterator. +func (b *MemoizedSeriesIterator) Reset(it chunkenc.Iterator) { + b.it = it + b.lastTime = math.MinInt64 + b.ok = true + b.prevTime = math.MinInt64 + it.Next() +} + +// PeekPrev returns the previous element of the iterator. If there is none buffered, +// ok is false. +func (b *MemoizedSeriesIterator) PeekPrev() (t int64, v float64, ok bool) { + if b.prevTime == math.MinInt64 { + return 0, 0, false + } + return b.prevTime, b.prevValue, true +} + +// Seek advances the iterator to the element at time t or greater. +func (b *MemoizedSeriesIterator) Seek(t int64) bool { + t0 := t - b.delta + + if t0 > b.lastTime { + // Reset the previously stored element because the seek advanced + // more than the delta. + b.prevTime = math.MinInt64 + + b.ok = b.it.Seek(t0) + if !b.ok { + return false + } + b.lastTime, _ = b.it.At() + } + + if b.lastTime >= t { + return true + } + for b.Next() { + if b.lastTime >= t { + return true + } + } + + return false +} + +// Next advances the iterator to the next element. +func (b *MemoizedSeriesIterator) Next() bool { + if !b.ok { + return false + } + + // Keep track of the previous element. + b.prevTime, b.prevValue = b.it.At() + + b.ok = b.it.Next() + if b.ok { + b.lastTime, _ = b.it.At() + } + + return b.ok +} + +// Values returns the current element of the iterator. +func (b *MemoizedSeriesIterator) Values() (int64, float64) { + return b.it.At() +} + +// Err returns the last encountered error. +func (b *MemoizedSeriesIterator) Err() error { + return b.it.Err() +} diff --git a/vendor/github.com/prometheus/prometheus/storage/merge.go b/vendor/github.com/prometheus/prometheus/storage/merge.go index c57a24c762..fca052ca1e 100644 --- a/vendor/github.com/prometheus/prometheus/storage/merge.go +++ b/vendor/github.com/prometheus/prometheus/storage/merge.go @@ -467,6 +467,7 @@ func (c *chainSampleIterator) Seek(t int64) bool { } if len(c.h) > 0 { c.curr = heap.Pop(&c.h).(chunkenc.Iterator) + c.lastt, _ = c.curr.At() return true } c.curr = nil diff --git a/vendor/github.com/prometheus/prometheus/template/template.go b/vendor/github.com/prometheus/prometheus/template/template.go index 10a9241c79..ae427738ef 100644 --- a/vendor/github.com/prometheus/prometheus/template/template.go +++ b/vendor/github.com/prometheus/prometheus/template/template.go @@ -22,6 +22,7 @@ import ( "net/url" "regexp" "sort" + "strconv" "strings" text_template "text/template" "time" @@ -97,6 +98,17 @@ func query(ctx context.Context, q string, ts time.Time, queryFn QueryFunc) (quer return result, nil } +func convertToFloat(i interface{}) (float64, error) { + switch v := i.(type) { + case float64: + return v, nil + case string: + return strconv.ParseFloat(v, 64) + default: + return 0, fmt.Errorf("can't convert %T to float", v) + } +} + // Expander executes templates in text or HTML mode with a common set of Prometheus template functions. type Expander struct { text string @@ -163,9 +175,13 @@ func NewTemplateExpander( sort.Stable(sorter) return v }, - "humanize": func(v float64) string { + "humanize": func(i interface{}) (string, error) { + v, err := convertToFloat(i) + if err != nil { + return "", err + } if v == 0 || math.IsNaN(v) || math.IsInf(v, 0) { - return fmt.Sprintf("%.4g", v) + return fmt.Sprintf("%.4g", v), nil } if math.Abs(v) >= 1 { prefix := "" @@ -176,7 +192,7 @@ func NewTemplateExpander( prefix = p v /= 1000 } - return fmt.Sprintf("%.4g%s", v, prefix) + return fmt.Sprintf("%.4g%s", v, prefix), nil } prefix := "" for _, p := range []string{"m", "u", "n", "p", "f", "a", "z", "y"} { @@ -186,11 +202,15 @@ func NewTemplateExpander( prefix = p v *= 1000 } - return fmt.Sprintf("%.4g%s", v, prefix) + return fmt.Sprintf("%.4g%s", v, prefix), nil }, - "humanize1024": func(v float64) string { + "humanize1024": func(i interface{}) (string, error) { + v, err := convertToFloat(i) + if err != nil { + return "", err + } if math.Abs(v) <= 1 || math.IsNaN(v) || math.IsInf(v, 0) { - return fmt.Sprintf("%.4g", v) + return fmt.Sprintf("%.4g", v), nil } prefix := "" for _, p := range []string{"ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi"} { @@ -200,14 +220,18 @@ func NewTemplateExpander( prefix = p v /= 1024 } - return fmt.Sprintf("%.4g%s", v, prefix) + return fmt.Sprintf("%.4g%s", v, prefix), nil }, - "humanizeDuration": func(v float64) string { + "humanizeDuration": func(i interface{}) (string, error) { + v, err := convertToFloat(i) + if err != nil { + return "", err + } if math.IsNaN(v) || math.IsInf(v, 0) { - return fmt.Sprintf("%.4g", v) + return fmt.Sprintf("%.4g", v), nil } if v == 0 { - return fmt.Sprintf("%.4gs", v) + return fmt.Sprintf("%.4gs", v), nil } if math.Abs(v) >= 1 { sign := "" @@ -221,16 +245,16 @@ func NewTemplateExpander( days := int64(v) / 60 / 60 / 24 // For days to minutes, we display seconds as an integer. if days != 0 { - return fmt.Sprintf("%s%dd %dh %dm %ds", sign, days, hours, minutes, seconds) + return fmt.Sprintf("%s%dd %dh %dm %ds", sign, days, hours, minutes, seconds), nil } if hours != 0 { - return fmt.Sprintf("%s%dh %dm %ds", sign, hours, minutes, seconds) + return fmt.Sprintf("%s%dh %dm %ds", sign, hours, minutes, seconds), nil } if minutes != 0 { - return fmt.Sprintf("%s%dm %ds", sign, minutes, seconds) + return fmt.Sprintf("%s%dm %ds", sign, minutes, seconds), nil } // For seconds, we display 4 significant digits. - return fmt.Sprintf("%s%.4gs", sign, v) + return fmt.Sprintf("%s%.4gs", sign, v), nil } prefix := "" for _, p := range []string{"m", "u", "n", "p", "f", "a", "z", "y"} { @@ -240,17 +264,25 @@ func NewTemplateExpander( prefix = p v *= 1000 } - return fmt.Sprintf("%.4g%ss", v, prefix) + return fmt.Sprintf("%.4g%ss", v, prefix), nil }, - "humanizePercentage": func(v float64) string { - return fmt.Sprintf("%.4g%%", v*100) + "humanizePercentage": func(i interface{}) (string, error) { + v, err := convertToFloat(i) + if err != nil { + return "", err + } + return fmt.Sprintf("%.4g%%", v*100), nil }, - "humanizeTimestamp": func(v float64) string { + "humanizeTimestamp": func(i interface{}) (string, error) { + v, err := convertToFloat(i) + if err != nil { + return "", err + } if math.IsNaN(v) || math.IsInf(v, 0) { - return fmt.Sprintf("%.4g", v) + return fmt.Sprintf("%.4g", v), nil } t := model.TimeFromUnixNano(int64(v * 1e9)).Time().UTC() - return fmt.Sprint(t) + return fmt.Sprint(t), nil }, "pathPrefix": func() string { return externalURL.Path diff --git a/vendor/github.com/prometheus/prometheus/tsdb/CHANGELOG.md b/vendor/github.com/prometheus/prometheus/tsdb/CHANGELOG.md index 66d07bf3cc..71a67d3b18 100644 --- a/vendor/github.com/prometheus/prometheus/tsdb/CHANGELOG.md +++ b/vendor/github.com/prometheus/prometheus/tsdb/CHANGELOG.md @@ -1,5 +1,3 @@ -## master / unreleased - ## 0.10.0 - [FEATURE] Added `DBReadOnly` to allow opening a database in read only mode. diff --git a/vendor/github.com/prometheus/prometheus/tsdb/block.go b/vendor/github.com/prometheus/prometheus/tsdb/block.go index 7ae8d5bbf1..47c842319f 100644 --- a/vendor/github.com/prometheus/prometheus/tsdb/block.go +++ b/vendor/github.com/prometheus/prometheus/tsdb/block.go @@ -569,7 +569,9 @@ Outer: // CleanTombstones will remove the tombstones and rewrite the block (only if there are any tombstones). // If there was a rewrite, then it returns the ULID of the new block written, else nil. -func (pb *Block) CleanTombstones(dest string, c Compactor) (*ulid.ULID, error) { +// If the resultant block is empty (tombstones covered the whole block), then it deletes the new block and return nil UID. +// It returns a boolean indicating if the parent block can be deleted safely of not. +func (pb *Block) CleanTombstones(dest string, c Compactor) (*ulid.ULID, bool, error) { numStones := 0 if err := pb.tombstones.Iter(func(id uint64, ivs tombstones.Intervals) error { @@ -580,15 +582,16 @@ func (pb *Block) CleanTombstones(dest string, c Compactor) (*ulid.ULID, error) { panic(err) } if numStones == 0 { - return nil, nil + return nil, false, nil } meta := pb.Meta() uid, err := c.Write(dest, pb, pb.meta.MinTime, pb.meta.MaxTime, &meta) if err != nil { - return nil, err + return nil, false, err } - return &uid, nil + + return &uid, true, nil } // Snapshot creates snapshot of the block into dir. diff --git a/vendor/github.com/prometheus/prometheus/tsdb/blockwriter.go b/vendor/github.com/prometheus/prometheus/tsdb/blockwriter.go index 7ede6c6304..2d19c77050 100644 --- a/vendor/github.com/prometheus/prometheus/tsdb/blockwriter.go +++ b/vendor/github.com/prometheus/prometheus/tsdb/blockwriter.go @@ -90,16 +90,11 @@ func (w *BlockWriter) Appender(ctx context.Context) storage.Appender { // Flush implements the Writer interface. This is where actual block writing // happens. After flush completes, no writes can be done. func (w *BlockWriter) Flush(ctx context.Context) (ulid.ULID, error) { - seriesCount := w.head.NumSeries() - if w.head.NumSeries() == 0 { - return ulid.ULID{}, ErrNoSeriesAppended - } - mint := w.head.MinTime() // Add +1 millisecond to block maxt because block intervals are half-open: [b.MinTime, b.MaxTime). // Because of this block intervals are always +1 than the total samples it includes. maxt := w.head.MaxTime() + 1 - level.Info(w.logger).Log("msg", "flushing", "series_count", seriesCount, "mint", timestamp.Time(mint), "maxt", timestamp.Time(maxt)) + level.Info(w.logger).Log("msg", "flushing", "series_count", w.head.NumSeries(), "mint", timestamp.Time(mint), "maxt", timestamp.Time(maxt)) compactor, err := NewLeveledCompactor(ctx, nil, diff --git a/vendor/github.com/prometheus/prometheus/tsdb/chunks/head_chunks.go b/vendor/github.com/prometheus/prometheus/tsdb/chunks/head_chunks.go index 051b9b1a89..d5386f7ea1 100644 --- a/vendor/github.com/prometheus/prometheus/tsdb/chunks/head_chunks.go +++ b/vendor/github.com/prometheus/prometheus/tsdb/chunks/head_chunks.go @@ -605,12 +605,14 @@ func (cdm *ChunkDiskMapper) IterateAllChunks(f func(seriesRef, chunkRef uint64, } } if allZeros { + // End of segment chunk file content. break } return &CorruptionErr{ Dir: cdm.dir.Name(), FileIndex: segID, - Err: errors.Errorf("head chunk file doesn't include enough bytes to read the chunk header - required:%v, available:%v, file:%d", idx+MaxHeadChunkMetaSize, fileEnd, segID), + Err: errors.Errorf("head chunk file has some unread data, but doesn't include enough bytes to read the chunk header"+ + " - required:%v, available:%v, file:%d", idx+MaxHeadChunkMetaSize, fileEnd, segID), } } chkCRC32.Reset() diff --git a/vendor/github.com/prometheus/prometheus/tsdb/compact.go b/vendor/github.com/prometheus/prometheus/tsdb/compact.go index 747f08f9ff..9befdc5528 100644 --- a/vendor/github.com/prometheus/prometheus/tsdb/compact.go +++ b/vendor/github.com/prometheus/prometheus/tsdb/compact.go @@ -76,11 +76,12 @@ type Compactor interface { // LeveledCompactor implements the Compactor interface. type LeveledCompactor struct { - metrics *compactorMetrics - logger log.Logger - ranges []int64 - chunkPool chunkenc.Pool - ctx context.Context + metrics *compactorMetrics + logger log.Logger + ranges []int64 + chunkPool chunkenc.Pool + ctx context.Context + maxBlockChunkSegmentSize int64 } type compactorMetrics struct { @@ -145,6 +146,10 @@ func newCompactorMetrics(r prometheus.Registerer) *compactorMetrics { // NewLeveledCompactor returns a LeveledCompactor. func NewLeveledCompactor(ctx context.Context, r prometheus.Registerer, l log.Logger, ranges []int64, pool chunkenc.Pool) (*LeveledCompactor, error) { + return NewLeveledCompactorWithChunkSize(ctx, r, l, ranges, pool, chunks.DefaultChunkSegmentSize) +} + +func NewLeveledCompactorWithChunkSize(ctx context.Context, r prometheus.Registerer, l log.Logger, ranges []int64, pool chunkenc.Pool, maxBlockChunkSegmentSize int64) (*LeveledCompactor, error) { if len(ranges) == 0 { return nil, errors.Errorf("at least one range must be provided") } @@ -155,11 +160,12 @@ func NewLeveledCompactor(ctx context.Context, r prometheus.Registerer, l log.Log l = log.NewNopLogger() } return &LeveledCompactor{ - ranges: ranges, - chunkPool: pool, - logger: l, - metrics: newCompactorMetrics(r), - ctx: ctx, + ranges: ranges, + chunkPool: pool, + logger: l, + metrics: newCompactorMetrics(r), + ctx: ctx, + maxBlockChunkSegmentSize: maxBlockChunkSegmentSize, }, nil } @@ -561,7 +567,7 @@ func (c *LeveledCompactor) write(dest string, meta *BlockMeta, blocks ...BlockRe // data of all blocks. var chunkw ChunkWriter - chunkw, err = chunks.NewWriter(chunkDir(tmp)) + chunkw, err = chunks.NewWriterWithSegSize(chunkDir(tmp), c.maxBlockChunkSegmentSize) if err != nil { return errors.Wrap(err, "open chunk writer") } diff --git a/vendor/github.com/prometheus/prometheus/tsdb/db.go b/vendor/github.com/prometheus/prometheus/tsdb/db.go index 5c95e02c02..d6036f5e5f 100644 --- a/vendor/github.com/prometheus/prometheus/tsdb/db.go +++ b/vendor/github.com/prometheus/prometheus/tsdb/db.go @@ -70,6 +70,7 @@ var ( func DefaultOptions() *Options { return &Options{ WALSegmentSize: wal.DefaultSegmentSize, + MaxBlockChunkSegmentSize: chunks.DefaultChunkSegmentSize, RetentionDuration: int64(15 * 24 * time.Hour / time.Millisecond), MinBlockDuration: DefaultBlockDuration, MaxBlockDuration: DefaultBlockDuration, @@ -89,6 +90,11 @@ type Options struct { // WALSegmentSize < 0, wal is disabled. WALSegmentSize int + // MaxBlockChunkSegmentSize is the max size of block chunk segment files. + // MaxBlockChunkSegmentSize = 0, chunk segment size is default size. + // MaxBlockChunkSegmentSize > 0, chunk segment size is MaxBlockChunkSegmentSize. + MaxBlockChunkSegmentSize int64 + // Duration of persisted data to keep. // Unit agnostic as long as unit is consistent with MinBlockDuration and MaxBlockDuration. // Typically it is in milliseconds. @@ -136,6 +142,10 @@ type Options struct { // It is always the default time and size based retention in Prometheus and // mainly meant for external users who import TSDB. BlocksToDelete BlocksToDeleteFunc + + // MaxExemplars sets the size, in # of exemplars stored, of the single circular buffer used to store exemplars in memory. + // See tsdb/exemplar.go, specifically the CircularExemplarStorage struct and it's constructor NewCircularExemplarStorage. + MaxExemplars int } type BlocksToDeleteFunc func(blocks []*Block) map[ulid.ULID]struct{} @@ -546,6 +556,9 @@ func validateOpts(opts *Options, rngs []int64) (*Options, []int64) { if opts.HeadChunksWriteBufferSize <= 0 { opts.HeadChunksWriteBufferSize = chunks.DefaultWriteBufferSize } + if opts.MaxBlockChunkSegmentSize <= 0 { + opts.MaxBlockChunkSegmentSize = chunks.DefaultChunkSegmentSize + } if opts.MinBlockDuration <= 0 { opts.MinBlockDuration = DefaultBlockDuration } @@ -635,7 +648,7 @@ func open(dir string, l log.Logger, r prometheus.Registerer, opts *Options, rngs var err error ctx, cancel := context.WithCancel(context.Background()) - db.compactor, err = NewLeveledCompactor(ctx, r, l, rngs, db.chunkPool) + db.compactor, err = NewLeveledCompactorWithChunkSize(ctx, r, l, rngs, db.chunkPool, opts.MaxBlockChunkSegmentSize) if err != nil { cancel() return nil, errors.Wrap(err, "create leveled compactor") @@ -663,6 +676,7 @@ func open(dir string, l log.Logger, r prometheus.Registerer, opts *Options, rngs headOpts.ChunkWriteBufferSize = opts.HeadChunksWriteBufferSize headOpts.StripeSize = opts.StripeSize headOpts.SeriesCallback = opts.SeriesLifecycleCallback + headOpts.NumExemplars = opts.MaxExemplars db.head, err = NewHead(r, l, wlog, headOpts) if err != nil { return nil, err @@ -790,6 +804,15 @@ type dbAppender struct { db *DB } +var _ storage.GetRef = dbAppender{} + +func (a dbAppender) GetRef(lset labels.Labels) (uint64, labels.Labels) { + if g, ok := a.Appender.(storage.GetRef); ok { + return g.GetRef(lset) + } + return 0, nil +} + func (a dbAppender) Commit() error { err := a.Appender.Commit() @@ -979,6 +1002,12 @@ func (db *DB) reloadBlocks() (err error) { db.metrics.reloads.Inc() }() + // Now that we reload TSDB every minute, there is high chance for race condition with a reload + // triggered by CleanTombstones(). We need to lock the reload to avoid the situation where + // a normal reload and CleanTombstones try to delete the same block. + db.mtx.Lock() + defer db.mtx.Unlock() + loadable, corrupted, err := openBlocks(db.logger, db.dir, db.blocks, db.chunkPool) if err != nil { return err @@ -1044,10 +1073,8 @@ func (db *DB) reloadBlocks() (err error) { } // Swap new blocks first for subsequently created readers to be seen. - db.mtx.Lock() oldBlocks := db.blocks db.blocks = toLoad - db.mtx.Unlock() blockMetas := make([]BlockMeta, 0, len(toLoad)) for _, b := range toLoad { @@ -1502,6 +1529,10 @@ func (db *DB) ChunkQuerier(_ context.Context, mint, maxt int64) (storage.ChunkQu return storage.NewMergeChunkQuerier(blockQueriers, nil, storage.NewCompactingChunkSeriesMerger(storage.ChainedSeriesMerge)), nil } +func (db *DB) ExemplarQuerier(ctx context.Context) (storage.ExemplarQuerier, error) { + return db.head.exemplars.ExemplarQuerier(ctx) +} + func rangeForTimestamp(t int64, width int64) (maxt int64) { return (t/width)*width + width } @@ -1537,34 +1568,44 @@ func (db *DB) CleanTombstones() (err error) { start := time.Now() defer db.metrics.tombCleanTimer.Observe(time.Since(start).Seconds()) - newUIDs := []ulid.ULID{} - defer func() { - // If any error is caused, we need to delete all the new directory created. - if err != nil { - for _, uid := range newUIDs { + cleanUpCompleted := false + // Repeat cleanup until there is no tombstones left. + for !cleanUpCompleted { + cleanUpCompleted = true + + for _, pb := range db.Blocks() { + uid, safeToDelete, cleanErr := pb.CleanTombstones(db.Dir(), db.compactor) + if cleanErr != nil { + return errors.Wrapf(cleanErr, "clean tombstones: %s", pb.Dir()) + } + if !safeToDelete { + // There was nothing to clean. + continue + } + + // In case tombstones of the old block covers the whole block, + // then there would be no resultant block to tell the parent. + // The lock protects against race conditions when deleting blocks + // during an already running reload. + db.mtx.Lock() + pb.meta.Compaction.Deletable = safeToDelete + db.mtx.Unlock() + cleanUpCompleted = false + if err = db.reloadBlocks(); err == nil { // Will try to delete old block. + // Successful reload will change the existing blocks. + // We need to loop over the new set of blocks. + break + } + + // Delete new block if it was created. + if uid != nil && *uid != (ulid.ULID{}) { dir := filepath.Join(db.Dir(), uid.String()) if err := os.RemoveAll(dir); err != nil { level.Error(db.logger).Log("msg", "failed to delete block after failed `CleanTombstones`", "dir", dir, "err", err) } } + return errors.Wrap(err, "reload blocks") } - }() - - db.mtx.RLock() - blocks := db.blocks[:] - db.mtx.RUnlock() - - for _, b := range blocks { - if uid, er := b.CleanTombstones(db.Dir(), db.compactor); er != nil { - err = errors.Wrapf(er, "clean tombstones: %s", b.Dir()) - return err - } else if uid != nil { // New block was created. - newUIDs = append(newUIDs, *uid) - } - } - - if err := db.reloadBlocks(); err != nil { - return errors.Wrap(err, "reload blocks") } return nil } diff --git a/vendor/github.com/prometheus/prometheus/tsdb/exemplar.go b/vendor/github.com/prometheus/prometheus/tsdb/exemplar.go new file mode 100644 index 0000000000..e6e6cb4941 --- /dev/null +++ b/vendor/github.com/prometheus/prometheus/tsdb/exemplar.go @@ -0,0 +1,241 @@ +// Copyright 2020 The Prometheus Authors +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package tsdb + +import ( + "context" + "sort" + "sync" + + "github.com/prometheus/client_golang/prometheus" + "github.com/prometheus/prometheus/pkg/exemplar" + "github.com/prometheus/prometheus/pkg/labels" + "github.com/prometheus/prometheus/storage" +) + +type CircularExemplarStorage struct { + exemplarsAppended prometheus.Counter + exemplarsInStorage prometheus.Gauge + seriesWithExemplarsInStorage prometheus.Gauge + lastExemplarsTs prometheus.Gauge + outOfOrderExemplars prometheus.Counter + + lock sync.RWMutex + exemplars []*circularBufferEntry + nextIndex int + + // Map of series labels as a string to index entry, which points to the first + // and last exemplar for the series in the exemplars circular buffer. + index map[string]*indexEntry +} + +type indexEntry struct { + oldest int + newest int +} + +type circularBufferEntry struct { + exemplar exemplar.Exemplar + seriesLabels labels.Labels + next int +} + +// NewCircularExemplarStorage creates an circular in memory exemplar storage. +// If we assume the average case 95 bytes per exemplar we can fit 5651272 exemplars in +// 1GB of extra memory, accounting for the fact that this is heap allocated space. +// If len < 1, then the exemplar storage is disabled. +func NewCircularExemplarStorage(len int, reg prometheus.Registerer) (ExemplarStorage, error) { + if len < 1 { + return &noopExemplarStorage{}, nil + } + c := &CircularExemplarStorage{ + exemplars: make([]*circularBufferEntry, len), + index: make(map[string]*indexEntry), + exemplarsAppended: prometheus.NewCounter(prometheus.CounterOpts{ + Name: "prometheus_tsdb_exemplar_exemplars_appended_total", + Help: "Total number of appended exemplars.", + }), + exemplarsInStorage: prometheus.NewGauge(prometheus.GaugeOpts{ + Name: "prometheus_tsdb_exemplar_exemplars_in_storage", + Help: "Number of exemplars currently in circular storage.", + }), + seriesWithExemplarsInStorage: prometheus.NewGauge(prometheus.GaugeOpts{ + Name: "prometheus_tsdb_exemplar_series_with_exemplars_in_storage", + Help: "Number of series with exemplars currently in circular storage.", + }), + lastExemplarsTs: prometheus.NewGauge(prometheus.GaugeOpts{ + Name: "prometheus_tsdb_exemplar_last_exemplars_timestamp_seconds", + Help: "The timestamp of the oldest exemplar stored in circular storage. Useful to check for what time" + + "range the current exemplar buffer limit allows. This usually means the last timestamp" + + "for all exemplars for a typical setup. This is not true though if one of the series timestamp is in future compared to rest series.", + }), + outOfOrderExemplars: prometheus.NewCounter(prometheus.CounterOpts{ + Name: "prometheus_tsdb_exemplar_out_of_order_exemplars_total", + Help: "Total number of out of order exemplar ingestion failed attempts", + }), + } + if reg != nil { + reg.MustRegister( + c.exemplarsAppended, + c.exemplarsInStorage, + c.seriesWithExemplarsInStorage, + c.lastExemplarsTs, + c.outOfOrderExemplars, + ) + } + + return c, nil +} + +func (ce *CircularExemplarStorage) Appender() *CircularExemplarStorage { + return ce +} + +func (ce *CircularExemplarStorage) ExemplarQuerier(_ context.Context) (storage.ExemplarQuerier, error) { + return ce, nil +} + +func (ce *CircularExemplarStorage) Querier(_ context.Context) (storage.ExemplarQuerier, error) { + return ce, nil +} + +// Select returns exemplars for a given set of label matchers. +func (ce *CircularExemplarStorage) Select(start, end int64, matchers ...[]*labels.Matcher) ([]exemplar.QueryResult, error) { + ret := make([]exemplar.QueryResult, 0) + + ce.lock.RLock() + defer ce.lock.RUnlock() + + // Loop through each index entry, which will point us to first/last exemplar for each series. + for _, idx := range ce.index { + var se exemplar.QueryResult + e := ce.exemplars[idx.oldest] + if !matchesSomeMatcherSet(e.seriesLabels, matchers) { + continue + } + se.SeriesLabels = e.seriesLabels + + // Loop through all exemplars in the circular buffer for the current series. + for e.exemplar.Ts <= end { + if e.exemplar.Ts >= start { + se.Exemplars = append(se.Exemplars, e.exemplar) + } + if e.next == -1 { + break + } + e = ce.exemplars[e.next] + } + if len(se.Exemplars) > 0 { + ret = append(ret, se) + } + } + + sort.Slice(ret, func(i, j int) bool { + return labels.Compare(ret[i].SeriesLabels, ret[j].SeriesLabels) < 0 + }) + + return ret, nil +} + +func matchesSomeMatcherSet(lbls labels.Labels, matchers [][]*labels.Matcher) bool { +Outer: + for _, ms := range matchers { + for _, m := range ms { + if !m.Matches(lbls.Get(m.Name)) { + continue Outer + } + } + return true + } + return false +} + +func (ce *CircularExemplarStorage) AddExemplar(l labels.Labels, e exemplar.Exemplar) error { + seriesLabels := l.String() + + // TODO(bwplotka): This lock can lock all scrapers, there might high contention on this on scale. + // Optimize by moving the lock to be per series (& benchmark it). + ce.lock.Lock() + defer ce.lock.Unlock() + + idx, ok := ce.index[seriesLabels] + if !ok { + ce.index[seriesLabels] = &indexEntry{oldest: ce.nextIndex} + } else { + // Check for duplicate vs last stored exemplar for this series. + // NB these are expected, add appending them is a no-op. + if ce.exemplars[idx.newest].exemplar.Equals(e) { + return nil + } + + if e.Ts <= ce.exemplars[idx.newest].exemplar.Ts { + ce.outOfOrderExemplars.Inc() + return storage.ErrOutOfOrderExemplar + } + + ce.exemplars[ce.index[seriesLabels].newest].next = ce.nextIndex + } + + if prev := ce.exemplars[ce.nextIndex]; prev == nil { + ce.exemplars[ce.nextIndex] = &circularBufferEntry{} + } else { + // There exists exemplar already on this ce.nextIndex entry, drop it, to make place + // for others. + prevLabels := prev.seriesLabels.String() + if prev.next == -1 { + // Last item for this series, remove index entry. + delete(ce.index, prevLabels) + } else { + ce.index[prevLabels].oldest = prev.next + } + } + + // Default the next value to -1 (which we use to detect that we've iterated through all exemplars for a series in Select) + // since this is the first exemplar stored for this series. + ce.exemplars[ce.nextIndex].exemplar = e + ce.exemplars[ce.nextIndex].next = -1 + ce.exemplars[ce.nextIndex].seriesLabels = l + ce.index[seriesLabels].newest = ce.nextIndex + + ce.nextIndex = (ce.nextIndex + 1) % len(ce.exemplars) + + ce.exemplarsAppended.Inc() + ce.seriesWithExemplarsInStorage.Set(float64(len(ce.index))) + if next := ce.exemplars[ce.nextIndex]; next != nil { + ce.exemplarsInStorage.Set(float64(len(ce.exemplars))) + ce.lastExemplarsTs.Set(float64(next.exemplar.Ts)) + return nil + } + + // We did not yet fill the buffer. + ce.exemplarsInStorage.Set(float64(ce.nextIndex)) + ce.lastExemplarsTs.Set(float64(ce.exemplars[0].exemplar.Ts)) + return nil +} + +type noopExemplarStorage struct{} + +func (noopExemplarStorage) AddExemplar(l labels.Labels, e exemplar.Exemplar) error { + return nil +} + +func (noopExemplarStorage) ExemplarQuerier(context.Context) (storage.ExemplarQuerier, error) { + return &noopExemplarQuerier{}, nil +} + +type noopExemplarQuerier struct{} + +func (noopExemplarQuerier) Select(_, _ int64, _ ...[]*labels.Matcher) ([]exemplar.QueryResult, error) { + return nil, nil +} diff --git a/vendor/github.com/prometheus/prometheus/tsdb/head.go b/vendor/github.com/prometheus/prometheus/tsdb/head.go index 4352d86d9e..2a300ce2dd 100644 --- a/vendor/github.com/prometheus/prometheus/tsdb/head.go +++ b/vendor/github.com/prometheus/prometheus/tsdb/head.go @@ -30,6 +30,7 @@ import ( "github.com/prometheus/client_golang/prometheus" "go.uber.org/atomic" + "github.com/prometheus/prometheus/pkg/exemplar" "github.com/prometheus/prometheus/pkg/labels" "github.com/prometheus/prometheus/storage" "github.com/prometheus/prometheus/tsdb/chunkenc" @@ -46,11 +47,19 @@ var ( // ErrInvalidSample is returned if an appended sample is not valid and can't // be ingested. ErrInvalidSample = errors.New("invalid sample") + // ErrInvalidExemplar is returned if an appended exemplar is not valid and can't + // be ingested. + ErrInvalidExemplar = errors.New("invalid exemplar") // ErrAppenderClosed is returned if an appender has already be successfully // rolled back or committed. ErrAppenderClosed = errors.New("appender closed") ) +type ExemplarStorage interface { + storage.ExemplarQueryable + AddExemplar(labels.Labels, exemplar.Exemplar) error +} + // Head handles reads and writes of time series data within a time window. type Head struct { chunkRange atomic.Int64 @@ -60,14 +69,16 @@ type Head struct { lastWALTruncationTime atomic.Int64 lastSeriesID atomic.Uint64 - metrics *headMetrics - opts *HeadOptions - wal *wal.WAL - logger log.Logger - appendPool sync.Pool - seriesPool sync.Pool - bytesPool sync.Pool - memChunkPool sync.Pool + metrics *headMetrics + opts *HeadOptions + wal *wal.WAL + exemplars ExemplarStorage + logger log.Logger + appendPool sync.Pool + exemplarsPool sync.Pool + seriesPool sync.Pool + bytesPool sync.Pool + memChunkPool sync.Pool // All series addressable by their ID or hash. series *stripeSeries @@ -107,6 +118,7 @@ type HeadOptions struct { // A smaller StripeSize reduces the memory allocated, but can decrease performance with large number of series. StripeSize int SeriesCallback SeriesLifecycleCallback + NumExemplars int } func DefaultHeadOptions() *HeadOptions { @@ -325,10 +337,17 @@ func NewHead(r prometheus.Registerer, l log.Logger, wal *wal.WAL, opts *HeadOpti if opts.SeriesCallback == nil { opts.SeriesCallback = &noopSeriesLifecycleCallback{} } + + es, err := NewCircularExemplarStorage(opts.NumExemplars, r) + if err != nil { + return nil, err + } + h := &Head{ wal: wal, logger: l, opts: opts, + exemplars: es, series: newStripeSeries(opts.StripeSize, opts.SeriesCallback), symbols: map[string]struct{}{}, postings: index.NewUnorderedMemPostings(), @@ -351,7 +370,6 @@ func NewHead(r prometheus.Registerer, l log.Logger, wal *wal.WAL, opts *HeadOpti opts.ChunkPool = chunkenc.NewPool() } - var err error h.chunkDiskMapper, err = chunks.NewChunkDiskMapper( mmappedChunksDir(opts.ChunkDirRoot), opts.ChunkPool, @@ -366,6 +384,10 @@ func NewHead(r prometheus.Registerer, l log.Logger, wal *wal.WAL, opts *HeadOpti func mmappedChunksDir(dir string) string { return filepath.Join(dir, "chunks_head") } +func (h *Head) ExemplarQuerier(ctx context.Context) (storage.ExemplarQuerier, error) { + return h.exemplars.ExemplarQuerier(ctx) +} + // processWALSamples adds a partition of samples it receives to the head and passes // them on to other workers. // Samples before the mint timestamp are discarded. @@ -752,6 +774,11 @@ func (h *Head) Init(minValidTime int64) error { return nil } +// SetMinValidTime sets the minimum timestamp the head can ingest. +func (h *Head) SetMinValidTime(minValidTime int64) { + h.minValidTime.Store(minValidTime) +} + func (h *Head) loadMmappedChunks() (map[uint64][]*mmappedChunk, error) { mmappedChunks := map[uint64][]*mmappedChunk{} if err := h.chunkDiskMapper.IterateAllChunks(func(seriesRef, chunkRef uint64, mint, maxt int64, numSamples uint16) error { @@ -1047,21 +1074,40 @@ type initAppender struct { head *Head } -func (a *initAppender) Add(lset labels.Labels, t int64, v float64) (uint64, error) { +func (a *initAppender) Append(ref uint64, lset labels.Labels, t int64, v float64) (uint64, error) { if a.app != nil { - return a.app.Add(lset, t, v) + return a.app.Append(ref, lset, t, v) } + a.head.initTime(t) a.app = a.head.appender() + return a.app.Append(ref, lset, t, v) +} + +func (a *initAppender) AppendExemplar(ref uint64, l labels.Labels, e exemplar.Exemplar) (uint64, error) { + // Check if exemplar storage is enabled. + if a.head.opts.NumExemplars <= 0 { + return 0, nil + } + + if a.app != nil { + return a.app.AppendExemplar(ref, l, e) + } + // We should never reach here given we would call Append before AppendExemplar + // and we probably want to always base head/WAL min time on sample times. + a.head.initTime(e.Ts) + a.app = a.head.appender() - return a.app.Add(lset, t, v) + return a.app.AppendExemplar(ref, l, e) } -func (a *initAppender) AddFast(ref uint64, t int64, v float64) error { - if a.app == nil { - return storage.ErrNotFound +var _ storage.GetRef = &initAppender{} + +func (a *initAppender) GetRef(lset labels.Labels) (uint64, labels.Labels) { + if g, ok := a.app.(storage.GetRef); ok { + return g.GetRef(lset) } - return a.app.AddFast(ref, t, v) + return 0, nil } func (a *initAppender) Commit() error { @@ -1096,6 +1142,12 @@ func (h *Head) appender() *headAppender { appendID := h.iso.newAppendID() cleanupAppendIDsBelow := h.iso.lowWatermark() + // Allocate the exemplars buffer only if exemplars are enabled. + var exemplarsBuf []exemplarWithSeriesRef + if h.opts.NumExemplars > 0 { + exemplarsBuf = h.getExemplarBuffer() + } + return &headAppender{ head: h, minValidTime: h.appendableMinValidTime(), @@ -1103,8 +1155,10 @@ func (h *Head) appender() *headAppender { maxt: math.MinInt64, samples: h.getAppendBuffer(), sampleSeries: h.getSeriesBuffer(), + exemplars: exemplarsBuf, appendID: appendID, cleanupAppendIDsBelow: cleanupAppendIDsBelow, + exemplarAppender: h.exemplars, } } @@ -1121,6 +1175,19 @@ func max(a, b int64) int64 { return b } +func (h *Head) ExemplarAppender() storage.ExemplarAppender { + h.metrics.activeAppenders.Inc() + + // The head cache might not have a starting point yet. The init appender + // picks up the first appended timestamp as the base. + if h.MinTime() == math.MaxInt64 { + return &initAppender{ + head: h, + } + } + return h.appender() +} + func (h *Head) getAppendBuffer() []record.RefSample { b := h.appendPool.Get() if b == nil { @@ -1134,6 +1201,23 @@ func (h *Head) putAppendBuffer(b []record.RefSample) { h.appendPool.Put(b[:0]) } +func (h *Head) getExemplarBuffer() []exemplarWithSeriesRef { + b := h.exemplarsPool.Get() + if b == nil { + return make([]exemplarWithSeriesRef, 0, 512) + } + return b.([]exemplarWithSeriesRef) +} + +func (h *Head) putExemplarBuffer(b []exemplarWithSeriesRef) { + if b == nil { + return + } + + //nolint:staticcheck // Ignore SA6002 safe to ignore and actually fixing it has some performance penalty. + h.exemplarsPool.Put(b[:0]) +} + func (h *Head) getSeriesBuffer() []*memSeries { b := h.seriesPool.Get() if b == nil { @@ -1160,67 +1244,65 @@ func (h *Head) putBytesBuffer(b []byte) { h.bytesPool.Put(b[:0]) } +type exemplarWithSeriesRef struct { + ref uint64 + exemplar exemplar.Exemplar +} + type headAppender struct { - head *Head - minValidTime int64 // No samples below this timestamp are allowed. - mint, maxt int64 + head *Head + minValidTime int64 // No samples below this timestamp are allowed. + mint, maxt int64 + exemplarAppender ExemplarStorage series []record.RefSeries samples []record.RefSample + exemplars []exemplarWithSeriesRef sampleSeries []*memSeries appendID, cleanupAppendIDsBelow uint64 closed bool } -func (a *headAppender) Add(lset labels.Labels, t int64, v float64) (uint64, error) { +func (a *headAppender) Append(ref uint64, lset labels.Labels, t int64, v float64) (uint64, error) { if t < a.minValidTime { a.head.metrics.outOfBoundSamples.Inc() return 0, storage.ErrOutOfBounds } - // Ensure no empty labels have gotten through. - lset = lset.WithoutEmpty() - - if len(lset) == 0 { - return 0, errors.Wrap(ErrInvalidSample, "empty labelset") - } - - if l, dup := lset.HasDuplicateLabelNames(); dup { - return 0, errors.Wrap(ErrInvalidSample, fmt.Sprintf(`label name "%s" is not unique`, l)) - } - - s, created, err := a.head.getOrCreate(lset.Hash(), lset) - if err != nil { - return 0, err - } + s := a.head.series.getByID(ref) + if s == nil { + // Ensure no empty labels have gotten through. + lset = lset.WithoutEmpty() + if len(lset) == 0 { + return 0, errors.Wrap(ErrInvalidSample, "empty labelset") + } - if created { - a.series = append(a.series, record.RefSeries{ - Ref: s.ref, - Labels: lset, - }) - } - return s.ref, a.AddFast(s.ref, t, v) -} + if l, dup := lset.HasDuplicateLabelNames(); dup { + return 0, errors.Wrap(ErrInvalidSample, fmt.Sprintf(`label name "%s" is not unique`, l)) + } -func (a *headAppender) AddFast(ref uint64, t int64, v float64) error { - if t < a.minValidTime { - a.head.metrics.outOfBoundSamples.Inc() - return storage.ErrOutOfBounds + var created bool + var err error + s, created, err = a.head.getOrCreate(lset.Hash(), lset) + if err != nil { + return 0, err + } + if created { + a.series = append(a.series, record.RefSeries{ + Ref: s.ref, + Labels: lset, + }) + } } - s := a.head.series.getByID(ref) - if s == nil { - return errors.Wrap(storage.ErrNotFound, "unknown series") - } s.Lock() if err := s.appendable(t, v); err != nil { s.Unlock() if err == storage.ErrOutOfOrderSample { a.head.metrics.outOfOrderSamples.Inc() } - return err + return 0, err } s.pendingCommit = true s.Unlock() @@ -1233,12 +1315,44 @@ func (a *headAppender) AddFast(ref uint64, t int64, v float64) error { } a.samples = append(a.samples, record.RefSample{ - Ref: ref, + Ref: s.ref, T: t, V: v, }) a.sampleSeries = append(a.sampleSeries, s) - return nil + return s.ref, nil +} + +// AppendExemplar for headAppender assumes the series ref already exists, and so it doesn't +// use getOrCreate or make any of the lset sanity checks that Append does. +func (a *headAppender) AppendExemplar(ref uint64, _ labels.Labels, e exemplar.Exemplar) (uint64, error) { + // Check if exemplar storage is enabled. + if a.head.opts.NumExemplars <= 0 { + return 0, nil + } + + s := a.head.series.getByID(ref) + if s == nil { + return 0, fmt.Errorf("unknown series ref. when trying to add exemplar: %d", ref) + } + + // Ensure no empty labels have gotten through. + e.Labels = e.Labels.WithoutEmpty() + + a.exemplars = append(a.exemplars, exemplarWithSeriesRef{ref, e}) + + return s.ref, nil +} + +var _ storage.GetRef = &headAppender{} + +func (a *headAppender) GetRef(lset labels.Labels) (uint64, labels.Labels) { + s := a.head.series.getByHash(lset.Hash(), lset) + if s == nil { + return 0, nil + } + // returned labels must be suitable to pass to Append() + return s.ref, s.lset } func (a *headAppender) log() error { @@ -1277,14 +1391,27 @@ func (a *headAppender) Commit() (err error) { } defer func() { a.closed = true }() if err := a.log(); err != nil { - //nolint: errcheck - a.Rollback() // Most likely the same error will happen again. + _ = a.Rollback() // Most likely the same error will happen again. return errors.Wrap(err, "write to WAL") } + // No errors logging to WAL, so pass the exemplars along to the in memory storage. + for _, e := range a.exemplars { + s := a.head.series.getByID(e.ref) + // We don't instrument exemplar appends here, all is instrumented by storage. + if err := a.exemplarAppender.AddExemplar(s.lset, e.exemplar); err != nil { + if err == storage.ErrOutOfOrderExemplar { + continue + } + level.Debug(a.head.logger).Log("msg", "Unknown error while adding exemplar", "err", err) + continue + } + } + defer a.head.metrics.activeAppenders.Dec() defer a.head.putAppendBuffer(a.samples) defer a.head.putSeriesBuffer(a.sampleSeries) + defer a.head.putExemplarBuffer(a.exemplars) defer a.head.iso.closeAppend(a.appendID) total := len(a.samples) @@ -1769,7 +1896,7 @@ func (h *headIndexReader) LabelValueFor(id uint64, label string) (string, error) } func (h *Head) getOrCreate(hash uint64, lset labels.Labels) (*memSeries, bool, error) { - // Just using `getOrSet` below would be semantically sufficient, but we'd create + // Just using `getOrCreateWithID` below would be semantically sufficient, but we'd create // a new series on every sample inserted via Add(), which causes allocations // and makes our series IDs rather random and harder to compress in postings. s := h.series.getByHash(hash, lset) @@ -1784,9 +1911,9 @@ func (h *Head) getOrCreate(hash uint64, lset labels.Labels) (*memSeries, bool, e } func (h *Head) getOrCreateWithID(id, hash uint64, lset labels.Labels) (*memSeries, bool, error) { - s := newMemSeries(lset, id, h.chunkRange.Load(), &h.memChunkPool) - - s, created, err := h.series.getOrSet(hash, s) + s, created, err := h.series.getOrSet(hash, lset, func() *memSeries { + return newMemSeries(lset, id, h.chunkRange.Load(), &h.memChunkPool) + }) if err != nil { return nil, false, err } @@ -1975,27 +2102,34 @@ func (s *stripeSeries) getByHash(hash uint64, lset labels.Labels) *memSeries { return series } -func (s *stripeSeries) getOrSet(hash uint64, series *memSeries) (*memSeries, bool, error) { +func (s *stripeSeries) getOrSet(hash uint64, lset labels.Labels, createSeries func() *memSeries) (*memSeries, bool, error) { // PreCreation is called here to avoid calling it inside the lock. // It is not necessary to call it just before creating a series, // rather it gives a 'hint' whether to create a series or not. - createSeriesErr := s.seriesLifecycleCallback.PreCreation(series.lset) + preCreationErr := s.seriesLifecycleCallback.PreCreation(lset) + + // Create the series, unless the PreCreation() callback as failed. + // If failed, we'll not allow to create a new series anyway. + var series *memSeries + if preCreationErr == nil { + series = createSeries() + } i := hash & uint64(s.size-1) s.locks[i].Lock() - if prev := s.hashes[i].get(hash, series.lset); prev != nil { + if prev := s.hashes[i].get(hash, lset); prev != nil { s.locks[i].Unlock() return prev, false, nil } - if createSeriesErr == nil { + if preCreationErr == nil { s.hashes[i].set(hash, series) } s.locks[i].Unlock() - if createSeriesErr != nil { + if preCreationErr != nil { // The callback prevented creation of series. - return nil, false, createSeriesErr + return nil, false, preCreationErr } // Setting the series in the s.hashes marks the creation of series // as any further calls to this methods would return that series. diff --git a/vendor/github.com/prometheus/prometheus/tsdb/querier.go b/vendor/github.com/prometheus/prometheus/tsdb/querier.go index 99038cc3fb..af5007fc18 100644 --- a/vendor/github.com/prometheus/prometheus/tsdb/querier.go +++ b/vendor/github.com/prometheus/prometheus/tsdb/querier.go @@ -453,7 +453,7 @@ func (b *blockBaseSeriesSet) Next() bool { var trimFront, trimBack bool - // Copy chunks as iteratables are reusable. + // Copy chunks as iterables are reusable. chks := make([]chunks.Meta, 0, len(b.bufChks)) // Prefilter chunks and pick those which are not entirely deleted or totally outside of the requested range. diff --git a/vendor/github.com/prometheus/prometheus/tsdb/tsdbblockutil.go b/vendor/github.com/prometheus/prometheus/tsdb/tsdbblockutil.go index be2c63f9f4..8cc0dd1952 100644 --- a/vendor/github.com/prometheus/prometheus/tsdb/tsdbblockutil.go +++ b/vendor/github.com/prometheus/prometheus/tsdb/tsdbblockutil.go @@ -50,14 +50,10 @@ func CreateBlock(series []storage.Series, dir string, chunkRange int64, logger l for _, s := range series { ref := uint64(0) it := s.Iterator() + lset := s.Labels() for it.Next() { t, v := it.At() - if ref != 0 { - if err := app.AddFast(ref, t, v); err == nil { - continue - } - } - ref, err = app.Add(s.Labels(), t, v) + ref, err = app.Append(ref, lset, t, v) if err != nil { return "", err } diff --git a/vendor/github.com/prometheus/prometheus/tsdb/wal/live_reader.go b/vendor/github.com/prometheus/prometheus/tsdb/wal/live_reader.go index 54c4a584e2..9155e4d03f 100644 --- a/vendor/github.com/prometheus/prometheus/tsdb/wal/live_reader.go +++ b/vendor/github.com/prometheus/prometheus/tsdb/wal/live_reader.go @@ -27,7 +27,7 @@ import ( "github.com/prometheus/client_golang/prometheus" ) -// liveReaderMetrics holds all metrics exposed by the LiveReader. +// LiveReaderMetrics holds all metrics exposed by the LiveReader. type LiveReaderMetrics struct { readerCorruptionErrors *prometheus.CounterVec } diff --git a/vendor/github.com/prometheus/prometheus/tsdb/wal/wal.go b/vendor/github.com/prometheus/prometheus/tsdb/wal/wal.go index 3aa87b2c07..7b45e0e912 100644 --- a/vendor/github.com/prometheus/prometheus/tsdb/wal/wal.go +++ b/vendor/github.com/prometheus/prometheus/tsdb/wal/wal.go @@ -613,18 +613,8 @@ func (w *WAL) log(rec []byte, final bool) error { return err } } - // If the record is too big to fit within the active page in the current - // segment, terminate the active segment and advance to the next one. - // This ensures that records do not cross segment boundaries. - left := w.page.remaining() - recordHeaderSize // Free space in the active page. - left += (pageSize - recordHeaderSize) * (w.pagesPerSegment() - w.donePages - 1) // Free pages in the active segment. - - if len(rec) > left { - if err := w.nextSegment(); err != nil { - return err - } - } + // Compress the record before calculating if a new segment is needed. compressed := false if w.compress && len(rec) > 0 { // The snappy library uses `len` to calculate if we need a new buffer. @@ -638,6 +628,18 @@ func (w *WAL) log(rec []byte, final bool) error { } } + // If the record is too big to fit within the active page in the current + // segment, terminate the active segment and advance to the next one. + // This ensures that records do not cross segment boundaries. + left := w.page.remaining() - recordHeaderSize // Free space in the active page. + left += (pageSize - recordHeaderSize) * (w.pagesPerSegment() - w.donePages - 1) // Free pages in the active segment. + + if len(rec) > left { + if err := w.nextSegment(); err != nil { + return err + } + } + // Populate as many pages as necessary to fit the record. // Be careful to always do one pass to ensure we write zero-length records. for i := 0; i == 0 || len(rec) > 0; i++ { diff --git a/vendor/github.com/prometheus/prometheus/util/teststorage/storage.go b/vendor/github.com/prometheus/prometheus/util/teststorage/storage.go index 6fa90781e1..16b3c3c7c6 100644 --- a/vendor/github.com/prometheus/prometheus/util/teststorage/storage.go +++ b/vendor/github.com/prometheus/prometheus/util/teststorage/storage.go @@ -18,6 +18,9 @@ import ( "os" "time" + "github.com/prometheus/prometheus/pkg/exemplar" + "github.com/prometheus/prometheus/pkg/labels" + "github.com/prometheus/prometheus/storage" "github.com/prometheus/prometheus/tsdb" "github.com/prometheus/prometheus/util/testutil" ) @@ -35,16 +38,22 @@ func New(t testutil.T) *TestStorage { opts := tsdb.DefaultOptions() opts.MinBlockDuration = int64(24 * time.Hour / time.Millisecond) opts.MaxBlockDuration = int64(24 * time.Hour / time.Millisecond) + opts.MaxExemplars = 10 db, err := tsdb.Open(dir, nil, nil, opts) if err != nil { t.Fatalf("Opening test storage failed: %s", err) } - return &TestStorage{DB: db, dir: dir} + es, err := tsdb.NewCircularExemplarStorage(10, nil) + if err != nil { + t.Fatalf("Opening test exemplar storage failed: %s", err) + } + return &TestStorage{DB: db, exemplarStorage: es, dir: dir} } type TestStorage struct { *tsdb.DB - dir string + exemplarStorage tsdb.ExemplarStorage + dir string } func (s TestStorage) Close() error { @@ -53,3 +62,15 @@ func (s TestStorage) Close() error { } return os.RemoveAll(s.dir) } + +func (s TestStorage) ExemplarAppender() storage.ExemplarAppender { + return s +} + +func (s TestStorage) ExemplarQueryable() storage.ExemplarQueryable { + return s.exemplarStorage +} + +func (s TestStorage) AppendExemplar(ref uint64, l labels.Labels, e exemplar.Exemplar) (uint64, error) { + return ref, s.exemplarStorage.AddExemplar(l, e) +} diff --git a/vendor/github.com/prometheus/prometheus/util/testutil/testing.go b/vendor/github.com/prometheus/prometheus/util/testutil/testing.go index 8ec50cb00f..31e0ee9bcd 100644 --- a/vendor/github.com/prometheus/prometheus/util/testutil/testing.go +++ b/vendor/github.com/prometheus/prometheus/util/testutil/testing.go @@ -36,5 +36,9 @@ func TolerantVerifyLeak(m *testing.M) { goleak.IgnoreTopFunction("go.opencensus.io/stats/view.(*worker).start"), // https://github.com/kubernetes/klog/blob/c85d02d1c76a9ebafa81eb6d35c980734f2c4727/klog.go#L417 goleak.IgnoreTopFunction("k8s.io/klog/v2.(*loggingT).flushDaemon"), + // This go routine uses a ticker to stop, so it can create false + // positives. + // https://github.com/kubernetes/client-go/blob/f6ce18ae578c8cca64d14ab9687824d9e1305a67/util/workqueue/queue.go#L201 + goleak.IgnoreTopFunction("k8s.io/client-go/util/workqueue.(*Type).updateUnfinishedWorkLoop"), ) } diff --git a/vendor/github.com/thanos-io/thanos/pkg/reloader/reloader.go b/vendor/github.com/thanos-io/thanos/pkg/reloader/reloader.go index ccb862b747..7b28a86ae9 100644 --- a/vendor/github.com/thanos-io/thanos/pkg/reloader/reloader.go +++ b/vendor/github.com/thanos-io/thanos/pkg/reloader/reloader.go @@ -197,6 +197,11 @@ func (r *Reloader) Watch(ctx context.Context) error { } } + if r.watchInterval == 0 { + // Skip watching the file-system. + return nil + } + for _, dir := range r.watchedDirs { if err := r.watcher.addDirectory(dir); err != nil { return errors.Wrapf(err, "add directory %s to watcher", dir) @@ -336,6 +341,9 @@ func (r *Reloader) apply(ctx context.Context) error { } if err := runutil.RetryWithLog(r.logger, r.retryInterval, ctx.Done(), func() error { + if r.watchInterval == 0 { + return nil + } r.reloads.Inc() if err := r.triggerReload(ctx); err != nil { r.reloadErrors.Inc() diff --git a/vendor/github.com/thanos-io/thanos/pkg/runutil/runutil.go b/vendor/github.com/thanos-io/thanos/pkg/runutil/runutil.go index f726eb25c3..77652cbb9f 100644 --- a/vendor/github.com/thanos-io/thanos/pkg/runutil/runutil.go +++ b/vendor/github.com/thanos-io/thanos/pkg/runutil/runutil.go @@ -166,6 +166,9 @@ func ExhaustCloseWithErrCapture(err *error, r io.ReadCloser, format string, a .. // NOTE: DeleteAll is not idempotent. func DeleteAll(dir string, ignoreDirs ...string) error { entries, err := ioutil.ReadDir(dir) + if os.IsNotExist(err) { + return nil + } if err != nil { return errors.Wrap(err, "read dir") } diff --git a/vendor/golang.org/x/net/http2/server.go b/vendor/golang.org/x/net/http2/server.go index 2aa859f76f..e125bbd2a2 100644 --- a/vendor/golang.org/x/net/http2/server.go +++ b/vendor/golang.org/x/net/http2/server.go @@ -1293,7 +1293,9 @@ func (sc *serverConn) startGracefulShutdown() { sc.shutdownOnce.Do(func() { sc.sendServeMsg(gracefulShutdownMsg) }) } -// After sending GOAWAY, the connection will close after goAwayTimeout. +// After sending GOAWAY with an error code (non-graceful shutdown), the +// connection will close after goAwayTimeout. +// // If we close the connection immediately after sending GOAWAY, there may // be unsent data in our kernel receive buffer, which will cause the kernel // to send a TCP RST on close() instead of a FIN. This RST will abort the @@ -1629,23 +1631,37 @@ func (sc *serverConn) processSettingInitialWindowSize(val uint32) error { func (sc *serverConn) processData(f *DataFrame) error { sc.serveG.check() - if sc.inGoAway && sc.goAwayCode != ErrCodeNo { + id := f.Header().StreamID + if sc.inGoAway && (sc.goAwayCode != ErrCodeNo || id > sc.maxClientStreamID) { + // Discard all DATA frames if the GOAWAY is due to an + // error, or: + // + // Section 6.8: After sending a GOAWAY frame, the sender + // can discard frames for streams initiated by the + // receiver with identifiers higher than the identified + // last stream. return nil } - data := f.Data() - // "If a DATA frame is received whose stream is not in "open" - // or "half closed (local)" state, the recipient MUST respond - // with a stream error (Section 5.4.2) of type STREAM_CLOSED." - id := f.Header().StreamID + data := f.Data() state, st := sc.state(id) if id == 0 || state == stateIdle { + // Section 6.1: "DATA frames MUST be associated with a + // stream. If a DATA frame is received whose stream + // identifier field is 0x0, the recipient MUST respond + // with a connection error (Section 5.4.1) of type + // PROTOCOL_ERROR." + // // Section 5.1: "Receiving any frame other than HEADERS // or PRIORITY on a stream in this state MUST be // treated as a connection error (Section 5.4.1) of // type PROTOCOL_ERROR." return ConnectionError(ErrCodeProtocol) } + + // "If a DATA frame is received whose stream is not in "open" + // or "half closed (local)" state, the recipient MUST respond + // with a stream error (Section 5.4.2) of type STREAM_CLOSED." if st == nil || state != stateOpen || st.gotTrailerHeader || st.resetQueued { // This includes sending a RST_STREAM if the stream is // in stateHalfClosedLocal (which currently means that diff --git a/vendor/golang.org/x/oauth2/internal/client_appengine.go b/vendor/golang.org/x/oauth2/internal/client_appengine.go index 7434871880..e1755d1d9a 100644 --- a/vendor/golang.org/x/oauth2/internal/client_appengine.go +++ b/vendor/golang.org/x/oauth2/internal/client_appengine.go @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +//go:build appengine // +build appengine package internal diff --git a/vendor/golang.org/x/sys/unix/asm_darwin_386.s b/vendor/golang.org/x/sys/unix/asm_bsd_386.s similarity index 70% rename from vendor/golang.org/x/sys/unix/asm_darwin_386.s rename to vendor/golang.org/x/sys/unix/asm_bsd_386.s index 8a06b87d71..7f29275fa0 100644 --- a/vendor/golang.org/x/sys/unix/asm_darwin_386.s +++ b/vendor/golang.org/x/sys/unix/asm_bsd_386.s @@ -1,14 +1,14 @@ -// Copyright 2009 The Go Authors. All rights reserved. +// Copyright 2021 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +//go:build (darwin || freebsd || netbsd || openbsd) && gc +// +build darwin freebsd netbsd openbsd // +build gc #include "textflag.h" -// -// System call support for 386, Darwin -// +// System call support for 386 BSD // Just jump to package syscall's implementation for all these functions. // The runtime may know about them. @@ -22,7 +22,7 @@ TEXT ·Syscall6(SB),NOSPLIT,$0-40 TEXT ·Syscall9(SB),NOSPLIT,$0-52 JMP syscall·Syscall9(SB) -TEXT ·RawSyscall(SB),NOSPLIT,$0-28 +TEXT ·RawSyscall(SB),NOSPLIT,$0-28 JMP syscall·RawSyscall(SB) TEXT ·RawSyscall6(SB),NOSPLIT,$0-40 diff --git a/vendor/golang.org/x/sys/unix/asm_darwin_amd64.s b/vendor/golang.org/x/sys/unix/asm_bsd_amd64.s similarity index 72% rename from vendor/golang.org/x/sys/unix/asm_darwin_amd64.s rename to vendor/golang.org/x/sys/unix/asm_bsd_amd64.s index f2397fde55..2b99c349a2 100644 --- a/vendor/golang.org/x/sys/unix/asm_darwin_amd64.s +++ b/vendor/golang.org/x/sys/unix/asm_bsd_amd64.s @@ -1,14 +1,14 @@ -// Copyright 2009 The Go Authors. All rights reserved. +// Copyright 2021 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +//go:build (darwin || dragonfly || freebsd || netbsd || openbsd) && gc +// +build darwin dragonfly freebsd netbsd openbsd // +build gc #include "textflag.h" -// -// System call support for AMD64, Darwin -// +// System call support for AMD64 BSD // Just jump to package syscall's implementation for all these functions. // The runtime may know about them. diff --git a/vendor/golang.org/x/sys/unix/asm_netbsd_arm.s b/vendor/golang.org/x/sys/unix/asm_bsd_arm.s similarity index 74% rename from vendor/golang.org/x/sys/unix/asm_netbsd_arm.s rename to vendor/golang.org/x/sys/unix/asm_bsd_arm.s index d7da175e1a..98ebfad9d5 100644 --- a/vendor/golang.org/x/sys/unix/asm_netbsd_arm.s +++ b/vendor/golang.org/x/sys/unix/asm_bsd_arm.s @@ -1,14 +1,14 @@ -// Copyright 2013 The Go Authors. All rights reserved. +// Copyright 2021 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +//go:build (darwin || freebsd || netbsd || openbsd) && gc +// +build darwin freebsd netbsd openbsd // +build gc #include "textflag.h" -// -// System call support for ARM, NetBSD -// +// System call support for ARM BSD // Just jump to package syscall's implementation for all these functions. // The runtime may know about them. diff --git a/vendor/golang.org/x/sys/unix/asm_netbsd_amd64.s b/vendor/golang.org/x/sys/unix/asm_bsd_arm64.s similarity index 75% rename from vendor/golang.org/x/sys/unix/asm_netbsd_amd64.s rename to vendor/golang.org/x/sys/unix/asm_bsd_arm64.s index e57367c17a..fe36a7391a 100644 --- a/vendor/golang.org/x/sys/unix/asm_netbsd_amd64.s +++ b/vendor/golang.org/x/sys/unix/asm_bsd_arm64.s @@ -1,14 +1,14 @@ -// Copyright 2009 The Go Authors. All rights reserved. +// Copyright 2021 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. +//go:build (darwin || freebsd || netbsd || openbsd) && gc +// +build darwin freebsd netbsd openbsd // +build gc #include "textflag.h" -// -// System call support for AMD64, NetBSD -// +// System call support for ARM64 BSD // Just jump to package syscall's implementation for all these functions. // The runtime may know about them. diff --git a/vendor/golang.org/x/sys/unix/asm_darwin_arm.s b/vendor/golang.org/x/sys/unix/asm_darwin_arm.s deleted file mode 100644 index c9e6b6fc8b..0000000000 --- a/vendor/golang.org/x/sys/unix/asm_darwin_arm.s +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build gc -// +build arm,darwin - -#include "textflag.h" - -// -// System call support for ARM, Darwin -// - -// Just jump to package syscall's implementation for all these functions. -// The runtime may know about them. - -TEXT ·Syscall(SB),NOSPLIT,$0-28 - B syscall·Syscall(SB) - -TEXT ·Syscall6(SB),NOSPLIT,$0-40 - B syscall·Syscall6(SB) - -TEXT ·Syscall9(SB),NOSPLIT,$0-52 - B syscall·Syscall9(SB) - -TEXT ·RawSyscall(SB),NOSPLIT,$0-28 - B syscall·RawSyscall(SB) - -TEXT ·RawSyscall6(SB),NOSPLIT,$0-40 - B syscall·RawSyscall6(SB) diff --git a/vendor/golang.org/x/sys/unix/asm_darwin_arm64.s b/vendor/golang.org/x/sys/unix/asm_darwin_arm64.s deleted file mode 100644 index 89843f8f4b..0000000000 --- a/vendor/golang.org/x/sys/unix/asm_darwin_arm64.s +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2015 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build gc -// +build arm64,darwin - -#include "textflag.h" - -// -// System call support for AMD64, Darwin -// - -// Just jump to package syscall's implementation for all these functions. -// The runtime may know about them. - -TEXT ·Syscall(SB),NOSPLIT,$0-56 - B syscall·Syscall(SB) - -TEXT ·Syscall6(SB),NOSPLIT,$0-80 - B syscall·Syscall6(SB) - -TEXT ·Syscall9(SB),NOSPLIT,$0-104 - B syscall·Syscall9(SB) - -TEXT ·RawSyscall(SB),NOSPLIT,$0-56 - B syscall·RawSyscall(SB) - -TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 - B syscall·RawSyscall6(SB) diff --git a/vendor/golang.org/x/sys/unix/asm_dragonfly_amd64.s b/vendor/golang.org/x/sys/unix/asm_dragonfly_amd64.s deleted file mode 100644 index 27674e1caf..0000000000 --- a/vendor/golang.org/x/sys/unix/asm_dragonfly_amd64.s +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build gc - -#include "textflag.h" - -// -// System call support for AMD64, DragonFly -// - -// Just jump to package syscall's implementation for all these functions. -// The runtime may know about them. - -TEXT ·Syscall(SB),NOSPLIT,$0-56 - JMP syscall·Syscall(SB) - -TEXT ·Syscall6(SB),NOSPLIT,$0-80 - JMP syscall·Syscall6(SB) - -TEXT ·Syscall9(SB),NOSPLIT,$0-104 - JMP syscall·Syscall9(SB) - -TEXT ·RawSyscall(SB),NOSPLIT,$0-56 - JMP syscall·RawSyscall(SB) - -TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 - JMP syscall·RawSyscall6(SB) diff --git a/vendor/golang.org/x/sys/unix/asm_freebsd_386.s b/vendor/golang.org/x/sys/unix/asm_freebsd_386.s deleted file mode 100644 index 49f0ac2364..0000000000 --- a/vendor/golang.org/x/sys/unix/asm_freebsd_386.s +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build gc - -#include "textflag.h" - -// -// System call support for 386, FreeBSD -// - -// Just jump to package syscall's implementation for all these functions. -// The runtime may know about them. - -TEXT ·Syscall(SB),NOSPLIT,$0-28 - JMP syscall·Syscall(SB) - -TEXT ·Syscall6(SB),NOSPLIT,$0-40 - JMP syscall·Syscall6(SB) - -TEXT ·Syscall9(SB),NOSPLIT,$0-52 - JMP syscall·Syscall9(SB) - -TEXT ·RawSyscall(SB),NOSPLIT,$0-28 - JMP syscall·RawSyscall(SB) - -TEXT ·RawSyscall6(SB),NOSPLIT,$0-40 - JMP syscall·RawSyscall6(SB) diff --git a/vendor/golang.org/x/sys/unix/asm_freebsd_amd64.s b/vendor/golang.org/x/sys/unix/asm_freebsd_amd64.s deleted file mode 100644 index f2dfc57b83..0000000000 --- a/vendor/golang.org/x/sys/unix/asm_freebsd_amd64.s +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build gc - -#include "textflag.h" - -// -// System call support for AMD64, FreeBSD -// - -// Just jump to package syscall's implementation for all these functions. -// The runtime may know about them. - -TEXT ·Syscall(SB),NOSPLIT,$0-56 - JMP syscall·Syscall(SB) - -TEXT ·Syscall6(SB),NOSPLIT,$0-80 - JMP syscall·Syscall6(SB) - -TEXT ·Syscall9(SB),NOSPLIT,$0-104 - JMP syscall·Syscall9(SB) - -TEXT ·RawSyscall(SB),NOSPLIT,$0-56 - JMP syscall·RawSyscall(SB) - -TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 - JMP syscall·RawSyscall6(SB) diff --git a/vendor/golang.org/x/sys/unix/asm_freebsd_arm.s b/vendor/golang.org/x/sys/unix/asm_freebsd_arm.s deleted file mode 100644 index 6d740db2c0..0000000000 --- a/vendor/golang.org/x/sys/unix/asm_freebsd_arm.s +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2012 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build gc - -#include "textflag.h" - -// -// System call support for ARM, FreeBSD -// - -// Just jump to package syscall's implementation for all these functions. -// The runtime may know about them. - -TEXT ·Syscall(SB),NOSPLIT,$0-28 - B syscall·Syscall(SB) - -TEXT ·Syscall6(SB),NOSPLIT,$0-40 - B syscall·Syscall6(SB) - -TEXT ·Syscall9(SB),NOSPLIT,$0-52 - B syscall·Syscall9(SB) - -TEXT ·RawSyscall(SB),NOSPLIT,$0-28 - B syscall·RawSyscall(SB) - -TEXT ·RawSyscall6(SB),NOSPLIT,$0-40 - B syscall·RawSyscall6(SB) diff --git a/vendor/golang.org/x/sys/unix/asm_freebsd_arm64.s b/vendor/golang.org/x/sys/unix/asm_freebsd_arm64.s deleted file mode 100644 index a8f5a29b35..0000000000 --- a/vendor/golang.org/x/sys/unix/asm_freebsd_arm64.s +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2018 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build gc - -#include "textflag.h" - -// -// System call support for ARM64, FreeBSD -// - -// Just jump to package syscall's implementation for all these functions. -// The runtime may know about them. - -TEXT ·Syscall(SB),NOSPLIT,$0-56 - JMP syscall·Syscall(SB) - -TEXT ·Syscall6(SB),NOSPLIT,$0-80 - JMP syscall·Syscall6(SB) - -TEXT ·Syscall9(SB),NOSPLIT,$0-104 - JMP syscall·Syscall9(SB) - -TEXT ·RawSyscall(SB),NOSPLIT,$0-56 - JMP syscall·RawSyscall(SB) - -TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 - JMP syscall·RawSyscall6(SB) diff --git a/vendor/golang.org/x/sys/unix/asm_netbsd_386.s b/vendor/golang.org/x/sys/unix/asm_netbsd_386.s deleted file mode 100644 index ae7b498d50..0000000000 --- a/vendor/golang.org/x/sys/unix/asm_netbsd_386.s +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build gc - -#include "textflag.h" - -// -// System call support for 386, NetBSD -// - -// Just jump to package syscall's implementation for all these functions. -// The runtime may know about them. - -TEXT ·Syscall(SB),NOSPLIT,$0-28 - JMP syscall·Syscall(SB) - -TEXT ·Syscall6(SB),NOSPLIT,$0-40 - JMP syscall·Syscall6(SB) - -TEXT ·Syscall9(SB),NOSPLIT,$0-52 - JMP syscall·Syscall9(SB) - -TEXT ·RawSyscall(SB),NOSPLIT,$0-28 - JMP syscall·RawSyscall(SB) - -TEXT ·RawSyscall6(SB),NOSPLIT,$0-40 - JMP syscall·RawSyscall6(SB) diff --git a/vendor/golang.org/x/sys/unix/asm_netbsd_arm64.s b/vendor/golang.org/x/sys/unix/asm_netbsd_arm64.s deleted file mode 100644 index e7cbe1904c..0000000000 --- a/vendor/golang.org/x/sys/unix/asm_netbsd_arm64.s +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build gc - -#include "textflag.h" - -// -// System call support for ARM64, NetBSD -// - -// Just jump to package syscall's implementation for all these functions. -// The runtime may know about them. - -TEXT ·Syscall(SB),NOSPLIT,$0-56 - B syscall·Syscall(SB) - -TEXT ·Syscall6(SB),NOSPLIT,$0-80 - B syscall·Syscall6(SB) - -TEXT ·Syscall9(SB),NOSPLIT,$0-104 - B syscall·Syscall9(SB) - -TEXT ·RawSyscall(SB),NOSPLIT,$0-56 - B syscall·RawSyscall(SB) - -TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 - B syscall·RawSyscall6(SB) diff --git a/vendor/golang.org/x/sys/unix/asm_openbsd_386.s b/vendor/golang.org/x/sys/unix/asm_openbsd_386.s deleted file mode 100644 index 2f00b0310f..0000000000 --- a/vendor/golang.org/x/sys/unix/asm_openbsd_386.s +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build gc - -#include "textflag.h" - -// -// System call support for 386, OpenBSD -// - -// Just jump to package syscall's implementation for all these functions. -// The runtime may know about them. - -TEXT ·Syscall(SB),NOSPLIT,$0-28 - JMP syscall·Syscall(SB) - -TEXT ·Syscall6(SB),NOSPLIT,$0-40 - JMP syscall·Syscall6(SB) - -TEXT ·Syscall9(SB),NOSPLIT,$0-52 - JMP syscall·Syscall9(SB) - -TEXT ·RawSyscall(SB),NOSPLIT,$0-28 - JMP syscall·RawSyscall(SB) - -TEXT ·RawSyscall6(SB),NOSPLIT,$0-40 - JMP syscall·RawSyscall6(SB) diff --git a/vendor/golang.org/x/sys/unix/asm_openbsd_amd64.s b/vendor/golang.org/x/sys/unix/asm_openbsd_amd64.s deleted file mode 100644 index 07632c99ce..0000000000 --- a/vendor/golang.org/x/sys/unix/asm_openbsd_amd64.s +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2009 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build gc - -#include "textflag.h" - -// -// System call support for AMD64, OpenBSD -// - -// Just jump to package syscall's implementation for all these functions. -// The runtime may know about them. - -TEXT ·Syscall(SB),NOSPLIT,$0-56 - JMP syscall·Syscall(SB) - -TEXT ·Syscall6(SB),NOSPLIT,$0-80 - JMP syscall·Syscall6(SB) - -TEXT ·Syscall9(SB),NOSPLIT,$0-104 - JMP syscall·Syscall9(SB) - -TEXT ·RawSyscall(SB),NOSPLIT,$0-56 - JMP syscall·RawSyscall(SB) - -TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 - JMP syscall·RawSyscall6(SB) diff --git a/vendor/golang.org/x/sys/unix/asm_openbsd_arm.s b/vendor/golang.org/x/sys/unix/asm_openbsd_arm.s deleted file mode 100644 index 73e997320f..0000000000 --- a/vendor/golang.org/x/sys/unix/asm_openbsd_arm.s +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2017 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build gc - -#include "textflag.h" - -// -// System call support for ARM, OpenBSD -// - -// Just jump to package syscall's implementation for all these functions. -// The runtime may know about them. - -TEXT ·Syscall(SB),NOSPLIT,$0-28 - B syscall·Syscall(SB) - -TEXT ·Syscall6(SB),NOSPLIT,$0-40 - B syscall·Syscall6(SB) - -TEXT ·Syscall9(SB),NOSPLIT,$0-52 - B syscall·Syscall9(SB) - -TEXT ·RawSyscall(SB),NOSPLIT,$0-28 - B syscall·RawSyscall(SB) - -TEXT ·RawSyscall6(SB),NOSPLIT,$0-40 - B syscall·RawSyscall6(SB) diff --git a/vendor/golang.org/x/sys/unix/asm_openbsd_arm64.s b/vendor/golang.org/x/sys/unix/asm_openbsd_arm64.s deleted file mode 100644 index c47302aa46..0000000000 --- a/vendor/golang.org/x/sys/unix/asm_openbsd_arm64.s +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2019 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -// +build gc - -#include "textflag.h" - -// -// System call support for arm64, OpenBSD -// - -// Just jump to package syscall's implementation for all these functions. -// The runtime may know about them. - -TEXT ·Syscall(SB),NOSPLIT,$0-56 - JMP syscall·Syscall(SB) - -TEXT ·Syscall6(SB),NOSPLIT,$0-80 - JMP syscall·Syscall6(SB) - -TEXT ·Syscall9(SB),NOSPLIT,$0-104 - JMP syscall·Syscall9(SB) - -TEXT ·RawSyscall(SB),NOSPLIT,$0-56 - JMP syscall·RawSyscall(SB) - -TEXT ·RawSyscall6(SB),NOSPLIT,$0-80 - JMP syscall·RawSyscall6(SB) diff --git a/vendor/golang.org/x/sys/unix/mkall.sh b/vendor/golang.org/x/sys/unix/mkall.sh index d257fac505..d727cad19c 100644 --- a/vendor/golang.org/x/sys/unix/mkall.sh +++ b/vendor/golang.org/x/sys/unix/mkall.sh @@ -199,7 +199,7 @@ illumos_amd64) mksyscall="go run mksyscall_solaris.go" mkerrors= mksysnum= - mktypes= + mktypes="GOARCH=$GOARCH go tool cgo -godefs" ;; *) echo 'unrecognized $GOOS_$GOARCH: ' "$GOOSARCH" 1>&2 diff --git a/vendor/golang.org/x/sys/unix/mkerrors.sh b/vendor/golang.org/x/sys/unix/mkerrors.sh index 87f9d1e351..086d69411b 100644 --- a/vendor/golang.org/x/sys/unix/mkerrors.sh +++ b/vendor/golang.org/x/sys/unix/mkerrors.sh @@ -56,6 +56,7 @@ includes_Darwin=' #define _DARWIN_C_SOURCE #define KERNEL #define _DARWIN_USE_64_BIT_INODE +#define __APPLE_USE_RFC_3542 #include #include #include @@ -216,6 +217,7 @@ struct ltchars { #include #include #include +#include #include #include #include @@ -500,7 +502,7 @@ ccflags="$@" $2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|ICMP6|TCP|MCAST|EVFILT|NOTE|SHUT|PROT|MAP|MFD|T?PACKET|MSG|SCM|MCL|DT|MADV|PR|LOCAL)_/ || $2 ~ /^TP_STATUS_/ || $2 ~ /^FALLOC_/ || - $2 == "ICMPV6_FILTER" || + $2 ~ /^ICMP(V6)?_FILTER$/ || $2 == "SOMAXCONN" || $2 == "NAME_MAX" || $2 == "IFNAMSIZ" || diff --git a/vendor/golang.org/x/sys/unix/syscall_aix.go b/vendor/golang.org/x/sys/unix/syscall_aix.go index d2723225ec..d8efb715ff 100644 --- a/vendor/golang.org/x/sys/unix/syscall_aix.go +++ b/vendor/golang.org/x/sys/unix/syscall_aix.go @@ -252,7 +252,7 @@ func anyToSockaddr(fd int, rsa *RawSockaddrAny) (Sockaddr, error) { } } - bytes := (*[10000]byte)(unsafe.Pointer(&pp.Path[0]))[0:n] + bytes := (*[len(pp.Path)]byte)(unsafe.Pointer(&pp.Path[0]))[0:n] sa.Name = string(bytes) return sa, nil diff --git a/vendor/golang.org/x/sys/unix/syscall_illumos.go b/vendor/golang.org/x/sys/unix/syscall_illumos.go index bc442e3bac..c5c58806ca 100644 --- a/vendor/golang.org/x/sys/unix/syscall_illumos.go +++ b/vendor/golang.org/x/sys/unix/syscall_illumos.go @@ -9,7 +9,9 @@ package unix -import "unsafe" +import ( + "unsafe" +) func bytes2iovec(bs [][]byte) []Iovec { iovecs := make([]Iovec, len(bs)) @@ -76,3 +78,52 @@ func Accept4(fd int, flags int) (nfd int, sa Sockaddr, err error) { } return } + +//sys putmsg(fd int, clptr *strbuf, dataptr *strbuf, flags int) (err error) + +func Putmsg(fd int, cl []byte, data []byte, flags int) (err error) { + var clp, datap *strbuf + if len(cl) > 0 { + clp = &strbuf{ + Len: int32(len(cl)), + Buf: (*int8)(unsafe.Pointer(&cl[0])), + } + } + if len(data) > 0 { + datap = &strbuf{ + Len: int32(len(data)), + Buf: (*int8)(unsafe.Pointer(&data[0])), + } + } + return putmsg(fd, clp, datap, flags) +} + +//sys getmsg(fd int, clptr *strbuf, dataptr *strbuf, flags *int) (err error) + +func Getmsg(fd int, cl []byte, data []byte) (retCl []byte, retData []byte, flags int, err error) { + var clp, datap *strbuf + if len(cl) > 0 { + clp = &strbuf{ + Maxlen: int32(len(cl)), + Buf: (*int8)(unsafe.Pointer(&cl[0])), + } + } + if len(data) > 0 { + datap = &strbuf{ + Maxlen: int32(len(data)), + Buf: (*int8)(unsafe.Pointer(&data[0])), + } + } + + if err = getmsg(fd, clp, datap, &flags); err != nil { + return nil, nil, 0, err + } + + if len(cl) > 0 { + retCl = cl[:clp.Len] + } + if len(data) > 0 { + retData = data[:datap.Len] + } + return retCl, retData, flags, nil +} diff --git a/vendor/golang.org/x/sys/unix/syscall_linux.go b/vendor/golang.org/x/sys/unix/syscall_linux.go index 0a48548e80..44ea96e39c 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux.go @@ -1877,6 +1877,7 @@ func Sendfile(outfd int, infd int, offset *int64, count int) (written int, err e //sys ClockGettime(clockid int32, time *Timespec) (err error) //sys ClockNanosleep(clockid int32, flags int, request *Timespec, remain *Timespec) (err error) //sys Close(fd int) (err error) +//sys CloseRange(first uint, last uint, flags uint) (err error) //sys CopyFileRange(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error) //sys DeleteModule(name string, flags int) (err error) //sys Dup(oldfd int) (fd int, err error) diff --git a/vendor/golang.org/x/sys/unix/syscall_linux_s390x.go b/vendor/golang.org/x/sys/unix/syscall_linux_s390x.go index a941d88815..a1e45694b4 100644 --- a/vendor/golang.org/x/sys/unix/syscall_linux_s390x.go +++ b/vendor/golang.org/x/sys/unix/syscall_linux_s390x.go @@ -250,7 +250,7 @@ func getsockopt(s int, level int, name int, val unsafe.Pointer, vallen *_Socklen } func setsockopt(s int, level int, name int, val unsafe.Pointer, vallen uintptr) error { - args := [4]uintptr{uintptr(s), uintptr(level), uintptr(name), uintptr(val)} + args := [5]uintptr{uintptr(s), uintptr(level), uintptr(name), uintptr(val), vallen} _, _, err := Syscall(SYS_SOCKETCALL, netSetSockOpt, uintptr(unsafe.Pointer(&args)), 0) if err != 0 { return err diff --git a/vendor/golang.org/x/sys/unix/syscall_solaris.go b/vendor/golang.org/x/sys/unix/syscall_solaris.go index 169497f062..77fcde7c18 100644 --- a/vendor/golang.org/x/sys/unix/syscall_solaris.go +++ b/vendor/golang.org/x/sys/unix/syscall_solaris.go @@ -565,7 +565,12 @@ func Minor(dev uint64) uint32 { * Expose the ioctl function */ -//sys ioctl(fd int, req uint, arg uintptr) (err error) +//sys ioctlRet(fd int, req uint, arg uintptr) (ret int, err error) = libc.ioctl + +func ioctl(fd int, req uint, arg uintptr) (err error) { + _, err = ioctlRet(fd, req, arg) + return err +} func IoctlSetTermio(fd int, req uint, value *Termio) error { err := ioctl(fd, req, uintptr(unsafe.Pointer(value))) diff --git a/vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go b/vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go index 0100cb12f1..991996b609 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_darwin_amd64.go @@ -776,15 +776,24 @@ const ( IPV6_2292PKTINFO = 0x13 IPV6_2292PKTOPTIONS = 0x19 IPV6_2292RTHDR = 0x18 + IPV6_3542DSTOPTS = 0x32 + IPV6_3542HOPLIMIT = 0x2f + IPV6_3542HOPOPTS = 0x31 + IPV6_3542NEXTHOP = 0x30 + IPV6_3542PKTINFO = 0x2e + IPV6_3542RTHDR = 0x33 IPV6_ADDR_MC_FLAGS_PREFIX = 0x20 IPV6_ADDR_MC_FLAGS_TRANSIENT = 0x10 IPV6_ADDR_MC_FLAGS_UNICAST_BASED = 0x30 + IPV6_AUTOFLOWLABEL = 0x3b IPV6_BINDV6ONLY = 0x1b IPV6_BOUND_IF = 0x7d IPV6_CHECKSUM = 0x1a IPV6_DEFAULT_MULTICAST_HOPS = 0x1 IPV6_DEFAULT_MULTICAST_LOOP = 0x1 IPV6_DEFHLIM = 0x40 + IPV6_DONTFRAG = 0x3e + IPV6_DSTOPTS = 0x32 IPV6_FAITH = 0x1d IPV6_FLOWINFO_MASK = 0xffffff0f IPV6_FLOWLABEL_MASK = 0xffff0f00 @@ -796,6 +805,8 @@ const ( IPV6_FW_GET = 0x22 IPV6_FW_ZERO = 0x21 IPV6_HLIMDEC = 0x1 + IPV6_HOPLIMIT = 0x2f + IPV6_HOPOPTS = 0x31 IPV6_IPSEC_POLICY = 0x1c IPV6_JOIN_GROUP = 0xc IPV6_LEAVE_GROUP = 0xd @@ -807,20 +818,34 @@ const ( IPV6_MAX_SOCK_SRC_FILTER = 0x80 IPV6_MIN_MEMBERSHIPS = 0x1f IPV6_MMTU = 0x500 + IPV6_MSFILTER = 0x4a IPV6_MULTICAST_HOPS = 0xa IPV6_MULTICAST_IF = 0x9 IPV6_MULTICAST_LOOP = 0xb + IPV6_NEXTHOP = 0x30 + IPV6_PATHMTU = 0x2c + IPV6_PKTINFO = 0x2e IPV6_PORTRANGE = 0xe IPV6_PORTRANGE_DEFAULT = 0x0 IPV6_PORTRANGE_HIGH = 0x1 IPV6_PORTRANGE_LOW = 0x2 + IPV6_PREFER_TEMPADDR = 0x3f + IPV6_RECVDSTOPTS = 0x28 + IPV6_RECVHOPLIMIT = 0x25 + IPV6_RECVHOPOPTS = 0x27 + IPV6_RECVPATHMTU = 0x2b + IPV6_RECVPKTINFO = 0x3d + IPV6_RECVRTHDR = 0x26 IPV6_RECVTCLASS = 0x23 + IPV6_RTHDR = 0x33 + IPV6_RTHDRDSTOPTS = 0x39 IPV6_RTHDR_LOOSE = 0x0 IPV6_RTHDR_STRICT = 0x1 IPV6_RTHDR_TYPE_0 = 0x0 IPV6_SOCKOPT_RESERVED1 = 0x3 IPV6_TCLASS = 0x24 IPV6_UNICAST_HOPS = 0x4 + IPV6_USE_MIN_MTU = 0x2a IPV6_V6ONLY = 0x1b IPV6_VERSION = 0x60 IPV6_VERSION_MASK = 0xf0 diff --git a/vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go b/vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go index df26a19681..e644eaf5e7 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go +++ b/vendor/golang.org/x/sys/unix/zerrors_darwin_arm64.go @@ -776,15 +776,24 @@ const ( IPV6_2292PKTINFO = 0x13 IPV6_2292PKTOPTIONS = 0x19 IPV6_2292RTHDR = 0x18 + IPV6_3542DSTOPTS = 0x32 + IPV6_3542HOPLIMIT = 0x2f + IPV6_3542HOPOPTS = 0x31 + IPV6_3542NEXTHOP = 0x30 + IPV6_3542PKTINFO = 0x2e + IPV6_3542RTHDR = 0x33 IPV6_ADDR_MC_FLAGS_PREFIX = 0x20 IPV6_ADDR_MC_FLAGS_TRANSIENT = 0x10 IPV6_ADDR_MC_FLAGS_UNICAST_BASED = 0x30 + IPV6_AUTOFLOWLABEL = 0x3b IPV6_BINDV6ONLY = 0x1b IPV6_BOUND_IF = 0x7d IPV6_CHECKSUM = 0x1a IPV6_DEFAULT_MULTICAST_HOPS = 0x1 IPV6_DEFAULT_MULTICAST_LOOP = 0x1 IPV6_DEFHLIM = 0x40 + IPV6_DONTFRAG = 0x3e + IPV6_DSTOPTS = 0x32 IPV6_FAITH = 0x1d IPV6_FLOWINFO_MASK = 0xffffff0f IPV6_FLOWLABEL_MASK = 0xffff0f00 @@ -796,6 +805,8 @@ const ( IPV6_FW_GET = 0x22 IPV6_FW_ZERO = 0x21 IPV6_HLIMDEC = 0x1 + IPV6_HOPLIMIT = 0x2f + IPV6_HOPOPTS = 0x31 IPV6_IPSEC_POLICY = 0x1c IPV6_JOIN_GROUP = 0xc IPV6_LEAVE_GROUP = 0xd @@ -807,20 +818,34 @@ const ( IPV6_MAX_SOCK_SRC_FILTER = 0x80 IPV6_MIN_MEMBERSHIPS = 0x1f IPV6_MMTU = 0x500 + IPV6_MSFILTER = 0x4a IPV6_MULTICAST_HOPS = 0xa IPV6_MULTICAST_IF = 0x9 IPV6_MULTICAST_LOOP = 0xb + IPV6_NEXTHOP = 0x30 + IPV6_PATHMTU = 0x2c + IPV6_PKTINFO = 0x2e IPV6_PORTRANGE = 0xe IPV6_PORTRANGE_DEFAULT = 0x0 IPV6_PORTRANGE_HIGH = 0x1 IPV6_PORTRANGE_LOW = 0x2 + IPV6_PREFER_TEMPADDR = 0x3f + IPV6_RECVDSTOPTS = 0x28 + IPV6_RECVHOPLIMIT = 0x25 + IPV6_RECVHOPOPTS = 0x27 + IPV6_RECVPATHMTU = 0x2b + IPV6_RECVPKTINFO = 0x3d + IPV6_RECVRTHDR = 0x26 IPV6_RECVTCLASS = 0x23 + IPV6_RTHDR = 0x33 + IPV6_RTHDRDSTOPTS = 0x39 IPV6_RTHDR_LOOSE = 0x0 IPV6_RTHDR_STRICT = 0x1 IPV6_RTHDR_TYPE_0 = 0x0 IPV6_SOCKOPT_RESERVED1 = 0x3 IPV6_TCLASS = 0x24 IPV6_UNICAST_HOPS = 0x4 + IPV6_USE_MIN_MTU = 0x2a IPV6_V6ONLY = 0x1b IPV6_VERSION = 0x60 IPV6_VERSION_MASK = 0xf0 diff --git a/vendor/golang.org/x/sys/unix/zerrors_linux.go b/vendor/golang.org/x/sys/unix/zerrors_linux.go index 504dd6cd2d..3b1b9287bb 100644 --- a/vendor/golang.org/x/sys/unix/zerrors_linux.go +++ b/vendor/golang.org/x/sys/unix/zerrors_linux.go @@ -974,6 +974,7 @@ const ( HUGETLBFS_MAGIC = 0x958458f6 IBSHIFT = 0x10 ICMPV6_FILTER = 0x1 + ICMP_FILTER = 0x1 ICRNL = 0x100 IFA_F_DADFAILED = 0x8 IFA_F_DEPRECATED = 0x20 diff --git a/vendor/golang.org/x/sys/unix/zsyscall_illumos_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_illumos_amd64.go index b57c7050d7..af5cb064ec 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_illumos_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_illumos_amd64.go @@ -15,19 +15,25 @@ import ( //go:cgo_import_dynamic libc_writev writev "libc.so" //go:cgo_import_dynamic libc_pwritev pwritev "libc.so" //go:cgo_import_dynamic libc_accept4 accept4 "libsocket.so" +//go:cgo_import_dynamic libc_putmsg putmsg "libc.so" +//go:cgo_import_dynamic libc_getmsg getmsg "libc.so" //go:linkname procreadv libc_readv //go:linkname procpreadv libc_preadv //go:linkname procwritev libc_writev //go:linkname procpwritev libc_pwritev //go:linkname procaccept4 libc_accept4 +//go:linkname procputmsg libc_putmsg +//go:linkname procgetmsg libc_getmsg var ( procreadv, procpreadv, procwritev, procpwritev, - procaccept4 syscallFunc + procaccept4, + procputmsg, + procgetmsg syscallFunc ) // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT @@ -100,3 +106,23 @@ func accept4(s int, rsa *RawSockaddrAny, addrlen *_Socklen, flags int) (fd int, } return } + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func putmsg(fd int, clptr *strbuf, dataptr *strbuf, flags int) (err error) { + _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procputmsg)), 4, uintptr(fd), uintptr(unsafe.Pointer(clptr)), uintptr(unsafe.Pointer(dataptr)), uintptr(flags), 0, 0) + if e1 != 0 { + err = e1 + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + +func getmsg(fd int, clptr *strbuf, dataptr *strbuf, flags *int) (err error) { + _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procgetmsg)), 4, uintptr(fd), uintptr(unsafe.Pointer(clptr)), uintptr(unsafe.Pointer(dataptr)), uintptr(unsafe.Pointer(flags)), 0, 0) + if e1 != 0 { + err = e1 + } + return +} diff --git a/vendor/golang.org/x/sys/unix/zsyscall_linux.go b/vendor/golang.org/x/sys/unix/zsyscall_linux.go index 3ee26f4ad1..7305cc915b 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_linux.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_linux.go @@ -532,6 +532,16 @@ func Close(fd int) (err error) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT +func CloseRange(first uint, last uint, flags uint) (err error) { + _, _, e1 := Syscall(SYS_CLOSE_RANGE, uintptr(first), uintptr(last), uintptr(flags)) + if e1 != 0 { + err = errnoErr(e1) + } + return +} + +// THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT + func CopyFileRange(rfd int, roff *int64, wfd int, woff *int64, len int, flags int) (n int, err error) { r0, _, e1 := Syscall6(SYS_COPY_FILE_RANGE, uintptr(rfd), uintptr(unsafe.Pointer(roff)), uintptr(wfd), uintptr(unsafe.Pointer(woff)), uintptr(len), uintptr(flags)) n = int(r0) diff --git a/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go b/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go index 7099f555aa..4e18d5c99f 100644 --- a/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go +++ b/vendor/golang.org/x/sys/unix/zsyscall_solaris_amd64.go @@ -619,8 +619,9 @@ func __minor(version int, dev uint64) (val uint) { // THIS FILE IS GENERATED BY THE COMMAND AT THE TOP; DO NOT EDIT -func ioctl(fd int, req uint, arg uintptr) (err error) { - _, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procioctl)), 3, uintptr(fd), uintptr(req), uintptr(arg), 0, 0, 0) +func ioctlRet(fd int, req uint, arg uintptr) (ret int, err error) { + r0, _, e1 := sysvicall6(uintptr(unsafe.Pointer(&procioctl)), 3, uintptr(fd), uintptr(req), uintptr(arg), 0, 0, 0) + ret = int(r0) if e1 != 0 { err = e1 } diff --git a/vendor/golang.org/x/sys/unix/ztypes_illumos_amd64.go b/vendor/golang.org/x/sys/unix/ztypes_illumos_amd64.go new file mode 100644 index 0000000000..1137a5a1f4 --- /dev/null +++ b/vendor/golang.org/x/sys/unix/ztypes_illumos_amd64.go @@ -0,0 +1,40 @@ +// cgo -godefs types_illumos.go | go run mkpost.go +// Code generated by the command above; see README.md. DO NOT EDIT. + +//go:build amd64 && illumos +// +build amd64,illumos + +package unix + +const ( + TUNNEWPPA = 0x540001 + TUNSETPPA = 0x540002 + + I_STR = 0x5308 + I_POP = 0x5303 + I_PUSH = 0x5302 + I_PLINK = 0x5316 + I_PUNLINK = 0x5317 + + IF_UNITSEL = -0x7ffb8cca +) + +type strbuf struct { + Maxlen int32 + Len int32 + Buf *int8 +} + +type strioctl struct { + Cmd int32 + Timout int32 + Len int32 + Dp *int8 +} + +type lifreq struct { + Name [32]int8 + Lifru1 [4]byte + Type uint32 + Lifru [336]byte +} diff --git a/vendor/golang.org/x/sys/unix/ztypes_linux.go b/vendor/golang.org/x/sys/unix/ztypes_linux.go index d3a18713bb..c769e73cd6 100644 --- a/vendor/golang.org/x/sys/unix/ztypes_linux.go +++ b/vendor/golang.org/x/sys/unix/ztypes_linux.go @@ -3709,3 +3709,14 @@ type ( Product int16 } ) + +const ( + CLOSE_RANGE_UNSHARE = 0x2 + CLOSE_RANGE_CLOEXEC = 0x4 +) + +const ( + NLMSGERR_ATTR_MSG = 0x1 + NLMSGERR_ATTR_OFFS = 0x2 + NLMSGERR_ATTR_COOKIE = 0x3 +) diff --git a/vendor/golang.org/x/sys/windows/types_windows.go b/vendor/golang.org/x/sys/windows/types_windows.go index 369cc91da7..23fe18ecef 100644 --- a/vendor/golang.org/x/sys/windows/types_windows.go +++ b/vendor/golang.org/x/sys/windows/types_windows.go @@ -1020,6 +1020,7 @@ const ( // cf. http://support.microsoft.com/default.aspx?scid=kb;en-us;257460 + IP_HDRINCL = 0x2 IP_TOS = 0x3 IP_TTL = 0x4 IP_MULTICAST_IF = 0x9 @@ -1027,6 +1028,7 @@ const ( IP_MULTICAST_LOOP = 0xb IP_ADD_MEMBERSHIP = 0xc IP_DROP_MEMBERSHIP = 0xd + IP_PKTINFO = 0x13 IPV6_V6ONLY = 0x1b IPV6_UNICAST_HOPS = 0x4 @@ -1035,6 +1037,7 @@ const ( IPV6_MULTICAST_LOOP = 0xb IPV6_JOIN_GROUP = 0xc IPV6_LEAVE_GROUP = 0xd + IPV6_PKTINFO = 0x13 MSG_OOB = 0x1 MSG_PEEK = 0x2 diff --git a/vendor/modules.txt b/vendor/modules.txt index a02fddbd74..5180abe73b 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -46,7 +46,7 @@ github.com/go-logfmt/logfmt # github.com/go-openapi/analysis v0.20.0 github.com/go-openapi/analysis github.com/go-openapi/analysis/internal -# github.com/go-openapi/errors v0.19.9 +# github.com/go-openapi/errors v0.20.0 github.com/go-openapi/errors # github.com/go-openapi/jsonpointer v0.19.5 github.com/go-openapi/jsonpointer @@ -54,7 +54,7 @@ github.com/go-openapi/jsonpointer github.com/go-openapi/jsonreference # github.com/go-openapi/loads v0.20.2 github.com/go-openapi/loads -# github.com/go-openapi/runtime v0.19.24 +# github.com/go-openapi/runtime v0.19.26 github.com/go-openapi/runtime github.com/go-openapi/runtime/client github.com/go-openapi/runtime/logger @@ -85,7 +85,7 @@ github.com/golang/protobuf/ptypes github.com/golang/protobuf/ptypes/any github.com/golang/protobuf/ptypes/duration github.com/golang/protobuf/ptypes/timestamp -# github.com/golang/snappy v0.0.3-0.20201103224600-674baa8c7fc3 +# github.com/golang/snappy v0.0.3 github.com/golang/snappy # github.com/google/go-cmp v0.5.5 ## explicit @@ -157,12 +157,12 @@ github.com/pmezard/go-difflib/difflib # github.com/prometheus-community/prom-label-proxy v0.2.0 ## explicit github.com/prometheus-community/prom-label-proxy/injectproxy -# github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.47.1 => ./pkg/apis/monitoring +# github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.48.1 => ./pkg/apis/monitoring ## explicit github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1 github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1alpha1 -# github.com/prometheus-operator/prometheus-operator/pkg/client v0.47.1 => ./pkg/client +# github.com/prometheus-operator/prometheus-operator/pkg/client v0.48.1 => ./pkg/client ## explicit github.com/prometheus-operator/prometheus-operator/pkg/client/informers/externalversions github.com/prometheus-operator/prometheus-operator/pkg/client/informers/externalversions/internalinterfaces @@ -178,7 +178,7 @@ github.com/prometheus-operator/prometheus-operator/pkg/client/versioned/typed/mo github.com/prometheus-operator/prometheus-operator/pkg/client/versioned/typed/monitoring/v1/fake github.com/prometheus-operator/prometheus-operator/pkg/client/versioned/typed/monitoring/v1alpha1 github.com/prometheus-operator/prometheus-operator/pkg/client/versioned/typed/monitoring/v1alpha1/fake -# github.com/prometheus/alertmanager v0.21.1-0.20201106142418-c39b78780054 +# github.com/prometheus/alertmanager v0.21.1-0.20210422101724-8176f78a70e1 ## explicit github.com/prometheus/alertmanager/api/v2/client github.com/prometheus/alertmanager/api/v2/client/alert @@ -189,6 +189,7 @@ github.com/prometheus/alertmanager/api/v2/client/silence github.com/prometheus/alertmanager/api/v2/models github.com/prometheus/alertmanager/config github.com/prometheus/alertmanager/pkg/labels +github.com/prometheus/alertmanager/timeinterval # github.com/prometheus/client_golang v1.10.0 ## explicit github.com/prometheus/client_golang/prometheus @@ -197,7 +198,7 @@ github.com/prometheus/client_golang/prometheus/promauto github.com/prometheus/client_golang/prometheus/promhttp # github.com/prometheus/client_model v0.2.0 github.com/prometheus/client_model/go -# github.com/prometheus/common v0.20.0 +# github.com/prometheus/common v0.21.0 ## explicit github.com/prometheus/common/config github.com/prometheus/common/expfmt @@ -208,7 +209,7 @@ github.com/prometheus/common/version github.com/prometheus/procfs github.com/prometheus/procfs/internal/fs github.com/prometheus/procfs/internal/util -# github.com/prometheus/prometheus v1.8.2-0.20210215121130-6f488061dfb4 +# github.com/prometheus/prometheus v1.8.2-0.20210421143221-52df5ef7a3be ## explicit github.com/prometheus/prometheus/pkg/exemplar github.com/prometheus/prometheus/pkg/labels @@ -242,7 +243,7 @@ github.com/spf13/pflag ## explicit github.com/stretchr/testify/assert github.com/stretchr/testify/require -# github.com/thanos-io/thanos v0.19.0 +# github.com/thanos-io/thanos v0.20.1 ## explicit github.com/thanos-io/thanos/pkg/errutil github.com/thanos-io/thanos/pkg/reloader @@ -278,7 +279,7 @@ go.uber.org/goleak/internal/stack # golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5 golang.org/x/lint golang.org/x/lint/golint -# golang.org/x/net v0.0.0-20210224082022-3d97a244fca7 +# golang.org/x/net v0.0.0-20210324051636-2c4c8ecb7826 golang.org/x/net/context golang.org/x/net/context/ctxhttp golang.org/x/net/http/httpguts @@ -287,13 +288,13 @@ golang.org/x/net/http2/hpack golang.org/x/net/idna golang.org/x/net/internal/timeseries golang.org/x/net/trace -# golang.org/x/oauth2 v0.0.0-20210210192628-66670185b0cd +# golang.org/x/oauth2 v0.0.0-20210323180902-22b0adad7558 golang.org/x/oauth2 golang.org/x/oauth2/internal # golang.org/x/sync v0.0.0-20210220032951-036812b2e83c ## explicit golang.org/x/sync/errgroup -# golang.org/x/sys v0.0.0-20210309074719-68d13333faf2 +# golang.org/x/sys v0.0.0-20210324051608-47abb6519492 golang.org/x/sys/internal/unsafeheader golang.org/x/sys/plan9 golang.org/x/sys/unix