diff --git a/Documentation/user-guides/linting.md b/Documentation/user-guides/linting.md deleted file mode 100644 index 9940b1215..000000000 --- a/Documentation/user-guides/linting.md +++ /dev/null @@ -1,46 +0,0 @@ -# Linting - -This document describes how to use the standalone linting tool to validate your Prometheus Operator [CRD-based](../design.md) configuration files. - -## Getting linter - -To use the linter either get it with `go get -u github.com/prometheus-operator/prometheus-operator/cmd/po-lint` and executable is `$GOPATH/bin/po-lint`, or use the container image from `quay.io/coreos/po-tooling` and executable is `/go/bin/po-lint`. - -## Using linter - -The `po-lint` executable takes a list of yaml files to check as command arguments. It will output any errors to stderr and returns with exit code `1` on errors, `0` otherwise. - -## Example - -Here is an example script to lint a `src` sub-directory full of Prometheus Operator CRD files with ether local `po-lint` or Dockerized version: - -```sh -#!/bin/sh - -LINTER="quay.io/coreos/po-tooling" - -lint_files() { - if [ -x "$(command -v po-lint)" ]; then - echo "Linting '${2}' files in directory '${1}'..." - had_errors=0 - for file in $(find "${1}" -name "${2}"); do - echo "${file}" - po-lint "${file}" - retval=$? - if [ $retval -ne 0 ]; then - had_errors=1 - fi - done - exit ${had_errors} - elif [ -x "$(command -v docker)" ]; then - echo "Using Dockerized linter." - docker run --rm --volume "$PWD:/data:ro" --workdir /data ${LINTER} \ - /bin/bash -c "/go/bin/po-lint $1/$2" - else - echo "Linter executable not found." - exit 1 - fi -} - -lint_files "./src" "*.yaml" -``` diff --git a/Makefile b/Makefile index 34a15c76e..a772623c6 100644 --- a/Makefile +++ b/Makefile @@ -102,7 +102,7 @@ clean: ############ .PHONY: build -build: operator prometheus-config-reloader admission-webhook k8s-gen po-lint +build: operator prometheus-config-reloader admission-webhook k8s-gen .PHONY: operator operator: @@ -116,9 +116,6 @@ prometheus-config-reloader: admission-webhook: $(GO_BUILD_RECIPE) -o $@ cmd/$@/main.go -.PHONY: po-lint -po-lint: - $(GO_BUILD_RECIPE) -o po-lint cmd/po-lint/main.go DEEPCOPY_TARGETS := pkg/apis/monitoring/v1/zz_generated.deepcopy.go pkg/apis/monitoring/v1alpha1/zz_generated.deepcopy.go pkg/apis/monitoring/v1beta1/zz_generated.deepcopy.go $(DEEPCOPY_TARGETS): $(CONTROLLER_GEN_BINARY) diff --git a/README.md b/README.md index f113ef450..67c85caa7 100644 --- a/README.md +++ b/README.md @@ -97,8 +97,6 @@ matching deployments and configurations are kept in sync. To learn more about the CRDs introduced by the Prometheus Operator have a look at the [design](https://prometheus-operator.dev/docs/operator/design/) page. -To automate the validation of your CRD configuration files, see the [linting](Documentation/user-guides/linting.md) page. - ## Dynamic Admission Control To prevent invalid Prometheus alerting and recording rules from causing failures in a deployed Prometheus instance, diff --git a/cmd/po-lint/main.go b/cmd/po-lint/main.go deleted file mode 100644 index 91497ea9c..000000000 --- a/cmd/po-lint/main.go +++ /dev/null @@ -1,203 +0,0 @@ -// Copyright 2019 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 main - -import ( - "bytes" - "encoding/json" - "errors" - "fmt" - "log" - "os" - - "github.com/prometheus/prometheus/model/rulefmt" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "sigs.k8s.io/yaml" - - "github.com/prometheus-operator/prometheus-operator/pkg/admission" - v1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" - v1alpha1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1alpha1" - "github.com/prometheus-operator/prometheus-operator/pkg/versionutil" -) - -func main() { - versionutil.RegisterParseFlags() - if versionutil.ShouldPrintVersion() { - versionutil.Print(os.Stdout, "po-lint") - os.Exit(0) - } - log.SetFlags(0) - - files := os.Args[1:] - - for _, filename := range files { - log.SetPrefix(fmt.Sprintf("%s: ", filename)) - content, err := os.ReadFile(filename) - if err != nil { - log.Fatal(err) - } - - var meta metav1.TypeMeta - - err = yaml.Unmarshal(content, &meta) - if err != nil { - log.Fatal(err) - } - - switch meta.Kind { - case v1.AlertmanagersKind: - j, err := yaml.YAMLToJSON(content) - if err != nil { - log.Fatalf("unable to convert YAML to JSON: %v", err) - } - - decoder := json.NewDecoder(bytes.NewBuffer(j)) - decoder.DisallowUnknownFields() - - var alertmanager v1.Alertmanager - err = decoder.Decode(&alertmanager) - if err != nil { - log.Fatalf("alertmanager is invalid: %v", err) - } - case v1.PrometheusesKind: - j, err := yaml.YAMLToJSON(content) - if err != nil { - log.Fatalf("unable to convert YAML to JSON: %v", err) - } - - decoder := json.NewDecoder(bytes.NewBuffer(j)) - decoder.DisallowUnknownFields() - - var prometheus v1.Prometheus - err = decoder.Decode(&prometheus) - if err != nil { - log.Fatalf("prometheus is invalid: %v", err) - } - case v1.PrometheusRuleKind: - j, err := yaml.YAMLToJSON(content) - if err != nil { - log.Fatalf("unable to convert YAML to JSON: %v", err) - } - - decoder := json.NewDecoder(bytes.NewBuffer(j)) - decoder.DisallowUnknownFields() - - var rule v1.PrometheusRule - err = decoder.Decode(&rule) - if err != nil { - log.Fatalf("prometheus rule is invalid: %v", err) - } - err = validateRules(content) - if err != nil { - log.Fatalf("prometheus rule validation failed: %v", err) - } - case v1.ServiceMonitorsKind: - j, err := yaml.YAMLToJSON(content) - if err != nil { - log.Fatalf("unable to convert YAML to JSON: %v", err) - } - - decoder := json.NewDecoder(bytes.NewBuffer(j)) - decoder.DisallowUnknownFields() - - var serviceMonitor v1.ServiceMonitor - err = decoder.Decode(&serviceMonitor) - if err != nil { - log.Fatalf("serviceMonitor is invalid: %v", err) - } - case v1.PodMonitorsKind: - j, err := yaml.YAMLToJSON(content) - if err != nil { - log.Fatalf("unable to convert YAML to JSON: %v", err) - } - - decoder := json.NewDecoder(bytes.NewBuffer(j)) - decoder.DisallowUnknownFields() - - var podMonitor v1.PodMonitor - err = decoder.Decode(&podMonitor) - if err != nil { - log.Fatalf("podMonitor is invalid: %v", err) - } - case v1.ProbesKind: - j, err := yaml.YAMLToJSON(content) - if err != nil { - log.Fatalf("unable to convert YAML to JSON: %v", err) - } - - decoder := json.NewDecoder(bytes.NewBuffer(j)) - decoder.DisallowUnknownFields() - - var probe v1.Probe - if err := decoder.Decode(&probe); err != nil { - log.Fatalf("probe is invalid: %v", err) - } - case v1.ThanosRulerKind: - j, err := yaml.YAMLToJSON(content) - if err != nil { - log.Fatalf("unable to convert YAML to JSON: %v", err) - } - - decoder := json.NewDecoder(bytes.NewBuffer(j)) - decoder.DisallowUnknownFields() - - var thanosRuler v1.ThanosRuler - err = decoder.Decode(&thanosRuler) - if err != nil { - log.Fatalf("thanosRuler is invalid: %v", err) - } - case v1alpha1.AlertmanagerConfigKind: - j, err := yaml.YAMLToJSON(content) - if err != nil { - log.Fatalf("unable to convert YAML to JSON: %v", err) - } - - decoder := json.NewDecoder(bytes.NewBuffer(j)) - decoder.DisallowUnknownFields() - - var alertmanagerConfig v1alpha1.AlertmanagerConfig - err = decoder.Decode(&alertmanagerConfig) - if err != nil { - log.Fatalf("alertmanagerConfig is invalid: %v", err) - } - default: - log.Print("MetaType is unknown to linter. Not in Alertmanager, Prometheus, PrometheusRule, ServiceMonitor, PodMonitor, Probe, ThanosRuler, AlertmanagerConfig") - } - } -} - -func validateRules(content []byte) error { - rule := &admission.PrometheusRules{} - err := yaml.Unmarshal(content, rule) - if err != nil { - return fmt.Errorf("unable load prometheus rule: %w", err) - } - rules, errorsArray := rulefmt.Parse(rule.Spec.Raw) - if len(errorsArray) != 0 { - for _, err := range errorsArray { - log.Println(err) - } - return errors.New("rules are not valid") - } - if len(rules.Groups) == 0 { - return errors.New("no group found") - } - for _, group := range rules.Groups { - if len(group.Rules) == 0 { - return fmt.Errorf("no rules found in group: %s: %w", group.Name, err) - } - } - return nil -} diff --git a/scripts/tooling/Dockerfile b/scripts/tooling/Dockerfile index ee23b99df..e4a38d45d 100644 --- a/scripts/tooling/Dockerfile +++ b/scripts/tooling/Dockerfile @@ -23,10 +23,6 @@ RUN go get github.com/brancz/gojsontoyaml RUN go get github.com/campoy/embedmd RUN GO111MODULE=on go get github.com/go-bindata/go-bindata/v3/go-bindata@${GO_BINDATA_VERSION} -# Add po-lint -WORKDIR /go/src/github.com/prometheus-operator/prometheus-operator -COPY . . -RUN GO111MODULE=on make po-lint && chmod +x po-lint && mv po-lint /go/bin/ FROM golang:1.14 RUN apt-get update -y && apt-get install -y make git jq gawk python-yaml && \