diff --git a/cmd/analyze.go b/cmd/analyze.go new file mode 100644 index 0000000..ddc5f99 --- /dev/null +++ b/cmd/analyze.go @@ -0,0 +1,86 @@ +// Copyright 2024 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 cmd + +import ( + "fmt" + "strings" + + "github.com/prometheus-operator/poctl/internal/analyzers" + "github.com/prometheus-operator/poctl/internal/k8sutil" + "github.com/spf13/cobra" +) + +type AnalyzeKind string + +const ( + ServiceMonitor AnalyzeKind = "servicemonitor" +) + +type AnalyzeFlags struct { + Kind string + Name string + Namespace string +} + +var ( + analyzerFlags = AnalyzeFlags{} + analyzeCmd = &cobra.Command{ + Use: "analyze", + Short: "Analyzes the given object and runs a set of rules on it to determine if it is compliant with the given rules.", + Long: `Analyzes the given object and runs a set of rules on it to determine if it is compliant with the given rules. + For example: + - Analyze if the service monitor is selecting any service or using the correct service port.`, + RunE: run, + } +) + +func run(cmd *cobra.Command, _ []string) error { + if analyzerFlags.Kind == "" { + return fmt.Errorf("kind is required") + } + + if analyzerFlags.Name == "" { + return fmt.Errorf("name is required") + } + + if analyzerFlags.Namespace == "" { + return fmt.Errorf("namespace is required") + } + + kClient, mClient, err := k8sutil.GetClientSets(kubeconfig) + if err != nil { + return fmt.Errorf("error while getting clientsets: %v", err) + } + + clientSets := k8sutil.ClientSets{ + KClient: kClient, + MClient: mClient, + } + + switch AnalyzeKind(strings.ToLower(analyzerFlags.Kind)) { + case ServiceMonitor: + return analyzers.RunServiceMonitorAnalyzer(cmd.Context(), clientSets, analyzerFlags.Name, analyzerFlags.Namespace) + default: + return fmt.Errorf("kind %s not supported", analyzerFlags.Kind) + } +} + +func init() { + rootCmd.AddCommand(analyzeCmd) + analyzeCmd.PersistentFlags().StringVarP(&analyzerFlags.Kind, "kind", "k", "", "The kind of object to analyze. For example, ServiceMonitor") + analyzeCmd.PersistentFlags().StringVarP(&analyzerFlags.Name, "name", "n", "", "The name of the object to analyze") + analyzeCmd.PersistentFlags().StringVarP(&analyzerFlags.Namespace, "namespace", "s", "", "The namespace of the object to analyze") +} diff --git a/cmd/servicemonitor.go b/cmd/servicemonitor.go index f014d38..1ef55b5 100644 --- a/cmd/servicemonitor.go +++ b/cmd/servicemonitor.go @@ -26,6 +26,7 @@ import ( "github.com/spf13/cobra" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" applyConfigMetav1 "k8s.io/client-go/applyconfigurations/meta/v1" + "k8s.io/client-go/kubernetes" "k8s.io/utils/ptr" ) @@ -93,7 +94,7 @@ func createFromService( Labels: service.Labels, }, Spec: &monitoringv1.ServiceMonitorSpecApplyConfiguration{ - Selector: &metav1.LabelSelector{ + Selector: &applyConfigMetav1.LabelSelectorApplyConfiguration{ MatchLabels: service.Spec.Selector, }, }, diff --git a/go.mod b/go.mod index d40f3d4..ccff686 100644 --- a/go.mod +++ b/go.mod @@ -3,19 +3,23 @@ module github.com/prometheus-operator/poctl go 1.22.0 require ( - k8s.io/apiextensions-apiserver v0.30.1 - k8s.io/client-go v0.30.1 + github.com/stretchr/testify v1.9.0 + k8s.io/apiextensions-apiserver v0.30.2 + k8s.io/client-go v0.30.2 ) require ( + github.com/evanphx/json-patch v5.9.0+incompatible // indirect github.com/google/go-querystring v1.1.0 // indirect - sigs.k8s.io/controller-runtime v0.18.2 // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + sigs.k8s.io/controller-runtime v0.18.4 // indirect ) require ( github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect - github.com/emicklei/go-restful/v3 v3.12.0 // indirect - github.com/go-logr/logr v1.4.1 // indirect + github.com/emicklei/go-restful/v3 v3.12.1 // indirect + github.com/go-logr/logr v1.4.2 // indirect github.com/go-openapi/jsonpointer v0.21.0 // indirect github.com/go-openapi/jsonreference v0.21.0 // indirect github.com/go-openapi/swag v0.23.0 // indirect @@ -31,24 +35,24 @@ require ( github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect - github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.74.0 + github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.75.1 github.com/spf13/cobra v1.8.0 github.com/spf13/pflag v1.0.5 - golang.org/x/net v0.25.0 // indirect - golang.org/x/oauth2 v0.19.0 // indirect - golang.org/x/sys v0.20.0 // indirect - golang.org/x/term v0.20.0 // indirect - golang.org/x/text v0.15.0 // indirect + golang.org/x/net v0.26.0 // indirect + golang.org/x/oauth2 v0.21.0 // indirect + golang.org/x/sys v0.21.0 // indirect + golang.org/x/term v0.21.0 // indirect + golang.org/x/text v0.16.0 // indirect golang.org/x/time v0.5.0 // indirect - google.golang.org/protobuf v1.34.1 // indirect + google.golang.org/protobuf v1.34.2 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/api v0.30.1 - k8s.io/apimachinery v0.30.1 - k8s.io/klog/v2 v2.120.1 // indirect - k8s.io/kube-openapi v0.0.0-20240322212309-b815d8309940 // indirect - k8s.io/utils v0.0.0-20240310230437-4693a0247e57 + k8s.io/api v0.30.2 + k8s.io/apimachinery v0.30.2 + k8s.io/klog/v2 v2.130.1 // indirect + k8s.io/kube-openapi v0.0.0-20240620174524-b456828f718b // indirect + k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect sigs.k8s.io/yaml v1.4.0 // indirect @@ -57,5 +61,5 @@ require ( require ( github.com/google/go-github/v62 v62.0.0 github.com/inconshreveable/mousetrap v1.1.0 // indirect - github.com/prometheus-operator/prometheus-operator/pkg/client v0.74.0 + github.com/prometheus-operator/prometheus-operator/pkg/client v0.75.1 ) diff --git a/go.sum b/go.sum index c53fbed..c45f3e9 100644 --- a/go.sum +++ b/go.sum @@ -3,10 +3,12 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/emicklei/go-restful/v3 v3.12.0 h1:y2DdzBAURM29NFF94q6RaY4vjIH1rtwDapwQtU84iWk= -github.com/emicklei/go-restful/v3 v3.12.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= -github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= -github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/emicklei/go-restful/v3 v3.12.1 h1:PJMDIM/ak7btuL8Ex0iYET9hxM3CI2sjZtzpL63nKAU= +github.com/emicklei/go-restful/v3 v3.12.1/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/evanphx/json-patch v5.9.0+incompatible h1:fBXyNpNMuTTDdquAq/uisOr2lShz4oaXpDTX2bLe7ls= +github.com/evanphx/json-patch v5.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-openapi/jsonpointer v0.21.0 h1:YgdVicSA9vH5RiHs9TZW5oyafXZFc6+2Vc1rr/O9oNQ= github.com/go-openapi/jsonpointer v0.21.0/go.mod h1:IUyH9l/+uyhIYQ/PXVA41Rexl+kOkAPDdXEYns6fzUY= github.com/go-openapi/jsonreference v0.21.0 h1:Rs+Y7hSXT83Jacb7kFyjn4ijOuVGSvOdF2+tg1TRrwQ= @@ -14,7 +16,8 @@ github.com/go-openapi/jsonreference v0.21.0/go.mod h1:LmZmgsrTkVg9LG4EaHeY8cBDsl github.com/go-openapi/swag v0.23.0 h1:vsEVJDUo2hPJ2tu0/Xc+4noaxyEffXNIs3cOULZ+GrE= github.com/go-openapi/swag v0.23.0/go.mod h1:esZ8ITTYEsH1V2trKHjAN8Ai7xHb8RV+YSZ577vPjgQ= github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI= -github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls= +github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= +github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= @@ -32,8 +35,8 @@ github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17 github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 h1:k7nVchz72niMH6YLQNvHSdIE7iqsQxK1P41mySCvssg= +github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= @@ -59,17 +62,19 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/onsi/ginkgo/v2 v2.17.1 h1:V++EzdbhI4ZV4ev0UTIj0PzhzOcReJFyJaLjtSF55M8= -github.com/onsi/ginkgo/v2 v2.17.1/go.mod h1:llBI3WDLL9Z6taip6f33H76YcWtJv+7R3HigUjbIBOs= -github.com/onsi/gomega v1.32.0 h1:JRYU78fJ1LPxlckP6Txi/EYqJvjtMrDC04/MM5XRHPk= -github.com/onsi/gomega v1.32.0/go.mod h1:a4x4gW6Pz2yK1MAmvluYme5lvYTn61afQ2ETw/8n4Lg= +github.com/onsi/ginkgo/v2 v2.17.2 h1:7eMhcy3GimbsA3hEnVKdw/PQM9XN9krpKVXsZdph0/g= +github.com/onsi/ginkgo/v2 v2.17.2/go.mod h1:nP2DPOQoNsQmsVyv5rDA8JkXQoCs6goXIvr/PRJ1eCc= +github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= +github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.74.0 h1:AHzMWDxNiAVscJL6+4wkvFRTpMnJqiaZFEKA/osaBXE= -github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.74.0/go.mod h1:wAR5JopumPtAZnu0Cjv2PSqV4p4QB09LMhc6fZZTXuA= -github.com/prometheus-operator/prometheus-operator/pkg/client v0.74.0 h1:SyBTzvFuVshDNjDVALs6+NgOy3qh8/xlAsyqB1SzHbI= -github.com/prometheus-operator/prometheus-operator/pkg/client v0.74.0/go.mod h1:FlcnLo14zQxL6P1yPrV22kYBqyAT0ZRRytv98+B7lBQ= +github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.75.1 h1:+iiljhJV6niK7MuifJs/n3NeLxikd85nrQfn53sLJkU= +github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring v0.75.1/go.mod h1:XYrdZw5dW12Cjkt4ndbeNZZTBp4UCHtW0ccR9+sTtPU= +github.com/prometheus-operator/prometheus-operator/pkg/client v0.75.1 h1:s7GlsRYGLWP+L1eQKy6RmLatX+k3v9NQwutUix4l5uM= +github.com/prometheus-operator/prometheus-operator/pkg/client v0.75.1/go.mod h1:qca3qWGdknRpHvPyThepe5a6QYAh38IQ2ml93E6V3NY= github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= @@ -92,38 +97,38 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= -golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= -golang.org/x/oauth2 v0.19.0 h1:9+E/EZBCbTLNrbN35fHv/a/d/mOBatymz1zbtQrXpIg= -golang.org/x/oauth2 v0.19.0/go.mod h1:vYi7skDa1x015PmRRYZ7+s1cWyPgrPiSYRe4rnsexc8= +golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= +golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= +golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= +golang.org/x/oauth2 v0.21.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= -golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= -golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= +golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= +golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA= +golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= -golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= +golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.18.0 h1:k8NLag8AGHnn+PHbl7g43CtqZAwG60vZkLqgyZgIHgQ= -golang.org/x/tools v0.18.0/go.mod h1:GL7B4CwcLLeo59yx/9UWWuNOW1n3VZ4f5axWfML7Lcg= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v1.34.1 h1:9ddQBjfCyZPOHPUiPxpYESBLc+T8P3E+Vo4IbKZgFWg= -google.golang.org/protobuf v1.34.1/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= @@ -134,22 +139,22 @@ gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -k8s.io/api v0.30.1 h1:kCm/6mADMdbAxmIh0LBjS54nQBE+U4KmbCfIkF5CpJY= -k8s.io/api v0.30.1/go.mod h1:ddbN2C0+0DIiPntan/bye3SW3PdwLa11/0yqwvuRrJM= -k8s.io/apiextensions-apiserver v0.30.1 h1:4fAJZ9985BmpJG6PkoxVRpXv9vmPUOVzl614xarePws= -k8s.io/apiextensions-apiserver v0.30.1/go.mod h1:R4GuSrlhgq43oRY9sF2IToFh7PVlF1JjfWdoG3pixk4= -k8s.io/apimachinery v0.30.1 h1:ZQStsEfo4n65yAdlGTfP/uSHMQSoYzU/oeEbkmF7P2U= -k8s.io/apimachinery v0.30.1/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc= -k8s.io/client-go v0.30.1 h1:uC/Ir6A3R46wdkgCV3vbLyNOYyCJ8oZnjtJGKfytl/Q= -k8s.io/client-go v0.30.1/go.mod h1:wrAqLNs2trwiCH/wxxmT/x3hKVH9PuV0GGW0oDoHVqc= -k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw= -k8s.io/klog/v2 v2.120.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20240322212309-b815d8309940 h1:qVoMaQV5t62UUvHe16Q3eb2c5HPzLHYzsi0Tu/xLndo= -k8s.io/kube-openapi v0.0.0-20240322212309-b815d8309940/go.mod h1:yD4MZYeKMBwQKVht279WycxKyM84kkAx2DPrTXaeb98= -k8s.io/utils v0.0.0-20240310230437-4693a0247e57 h1:gbqbevonBh57eILzModw6mrkbwM0gQBEuevE/AaBsHY= -k8s.io/utils v0.0.0-20240310230437-4693a0247e57/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -sigs.k8s.io/controller-runtime v0.18.2 h1:RqVW6Kpeaji67CY5nPEfRz6ZfFMk0lWQlNrLqlNpx+Q= -sigs.k8s.io/controller-runtime v0.18.2/go.mod h1:tuAt1+wbVsXIT8lPtk5RURxqAnq7xkpv2Mhttslg7Hw= +k8s.io/api v0.30.2 h1:+ZhRj+28QT4UOH+BKznu4CBgPWgkXO7XAvMcMl0qKvI= +k8s.io/api v0.30.2/go.mod h1:ULg5g9JvOev2dG0u2hig4Z7tQ2hHIuS+m8MNZ+X6EmI= +k8s.io/apiextensions-apiserver v0.30.2 h1:l7Eue2t6QiLHErfn2vwK4KgF4NeDgjQkCXtEbOocKIE= +k8s.io/apiextensions-apiserver v0.30.2/go.mod h1:lsJFLYyK40iguuinsb3nt+Sj6CmodSI4ACDLep1rgjw= +k8s.io/apimachinery v0.30.2 h1:fEMcnBj6qkzzPGSVsAZtQThU62SmQ4ZymlXRC5yFSCg= +k8s.io/apimachinery v0.30.2/go.mod h1:iexa2somDaxdnj7bha06bhb43Zpa6eWH8N8dbqVjTUc= +k8s.io/client-go v0.30.2 h1:sBIVJdojUNPDU/jObC+18tXWcTJVcwyqS9diGdWHk50= +k8s.io/client-go v0.30.2/go.mod h1:JglKSWULm9xlJLx4KCkfLLQ7XwtlbflV6uFFSHTMgVs= +k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= +k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= +k8s.io/kube-openapi v0.0.0-20240620174524-b456828f718b h1:Q9xmGWBvOGd8UJyccgpYlLosk/JlfP3xQLNkQlHJeXw= +k8s.io/kube-openapi v0.0.0-20240620174524-b456828f718b/go.mod h1:UxDHUPsUwTOOxSU+oXURfFBcAS6JwiRXTYqYwfuGowc= +k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0 h1:jgGTlFYnhF1PM1Ax/lAlxUPE+KfCIXHaathvJg1C3ak= +k8s.io/utils v0.0.0-20240502163921-fe8a2dddb1d0/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +sigs.k8s.io/controller-runtime v0.18.4 h1:87+guW1zhvuPLh1PHybKdYFLU0YJp4FhJRmiHvm5BZw= +sigs.k8s.io/controller-runtime v0.18.4/go.mod h1:TVoGrfdpbA9VRFaRnKgk9P5/atA0pMwq+f+msb9M8Sg= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo= sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0= sigs.k8s.io/structured-merge-diff/v4 v4.4.1 h1:150L+0vs/8DA78h1u02ooW1/fFq/Lwr+sGiqlzvrtq4= diff --git a/internal/analyzers/servicemonitor.go b/internal/analyzers/servicemonitor.go new file mode 100644 index 0000000..b6e19f8 --- /dev/null +++ b/internal/analyzers/servicemonitor.go @@ -0,0 +1,100 @@ +// Copyright 2024 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 analyzers + +import ( + "context" + "fmt" + + "github.com/prometheus-operator/poctl/internal/k8sutil" + monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" + v1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func RunServiceMonitorAnalyzer(ctx context.Context, clientSets k8sutil.ClientSets, name, namespace string) error { + serviceMonitor, err := clientSets.MClient.MonitoringV1().ServiceMonitors(namespace).Get(ctx, name, metav1.GetOptions{}) + if err != nil { + if errors.IsNotFound(err) { + return fmt.Errorf("ServiceMonitor %s not found in namespace %s", name, namespace) + } + return fmt.Errorf("error while getting ServiceMonitor: %v", err) + } + + if len(serviceMonitor.Spec.Selector.MatchLabels) == 0 && len(serviceMonitor.Spec.Selector.MatchExpressions) == 0 { + return fmt.Errorf("ServiceMonitor %s in namespace %s does not have a selector", name, namespace) + } + + if len(serviceMonitor.Spec.Selector.MatchLabels) > 0 { + services, err := clientSets.KClient.CoreV1().Services(namespace).List(ctx, metav1.ListOptions{ + LabelSelector: metav1.FormatLabelSelector(&serviceMonitor.Spec.Selector), + }) + + if err != nil { + return fmt.Errorf("error while listing services: %v", err) + } + + if len(services.Items) == 0 { + return fmt.Errorf("ServiceMonitor %s in namespace %s has no services matching the selector", name, namespace) + } + + if err = evaluatePortMatches(serviceMonitor, services, name, namespace); err != nil { + return err + } + } + + if len(serviceMonitor.Spec.Selector.MatchExpressions) > 0 { + services, err := clientSets.KClient.CoreV1().Services(namespace).List(ctx, metav1.ListOptions{ + LabelSelector: metav1.FormatLabelSelector(&serviceMonitor.Spec.Selector), + }) + + if err != nil { + return fmt.Errorf("error while listing services: %v", err) + } + + if len(services.Items) == 0 { + return fmt.Errorf("ServiceMonitor %s in namespace %s has no services matching the selector", name, namespace) + } + + if err = evaluatePortMatches(serviceMonitor, services, name, namespace); err != nil { + return err + } + } + + return nil +} + +func evaluatePortMatches(serviceMonitor *monitoringv1.ServiceMonitor, services *v1.ServiceList, name string, namespace string) error { + for _, endpoint := range serviceMonitor.Spec.Endpoints { + found := false + for _, service := range services.Items { + for _, port := range service.Spec.Ports { + if port.Name == endpoint.Port { + found = true + break + } + } + if found { + break + } + } + + if !found { + return fmt.Errorf("ServiceMonitor %s in namespace %s has no services with port %s", name, namespace, endpoint.Port) + } + } + return nil +} diff --git a/internal/analyzers/servicemonitor_test.go b/internal/analyzers/servicemonitor_test.go new file mode 100644 index 0000000..476c0f1 --- /dev/null +++ b/internal/analyzers/servicemonitor_test.go @@ -0,0 +1,186 @@ +// Copyright 2024 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 analyzers + +import ( + "context" + "testing" + + "github.com/prometheus-operator/poctl/internal/k8sutil" + monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1" + monitoringclient "github.com/prometheus-operator/prometheus-operator/pkg/client/versioned/fake" + "github.com/stretchr/testify/assert" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/client-go/kubernetes/fake" + clienttesting "k8s.io/client-go/testing" +) + +func TestServiceMonitorAnalyzer(t *testing.T) { + type testCase struct { + name string + namespace string + getMockedClientSets func(tc testCase) k8sutil.ClientSets + shouldFail bool + } + + // table test + tests := []testCase{ + { + name: "ServiceMonitorEmptySelector", + namespace: "test", + shouldFail: true, + getMockedClientSets: func(tc testCase) k8sutil.ClientSets { + mClient := monitoringclient.NewSimpleClientset(&monitoringv1.ServiceMonitorList{}) + mClient.PrependReactor("get", "servicemonitors", func(_ clienttesting.Action) (bool, runtime.Object, error) { + return true, &monitoringv1.ServiceMonitor{ + ObjectMeta: metav1.ObjectMeta{ + Name: tc.name, + Namespace: tc.namespace, + }, + Spec: monitoringv1.ServiceMonitorSpec{ + Endpoints: []monitoringv1.Endpoint{ + { + Port: "http", + }, + }, + Selector: metav1.LabelSelector{ + MatchLabels: map[string]string{}, + MatchExpressions: []metav1.LabelSelectorRequirement{}, + }, + }, + }, nil + }) + + return k8sutil.ClientSets{ + MClient: mClient, + } + }, + }, + { + name: "ServiceMonitorMatchLabelsNoServices", + namespace: "test", + shouldFail: true, + getMockedClientSets: func(tc testCase) k8sutil.ClientSets { + mClient := monitoringclient.NewSimpleClientset(&monitoringv1.ServiceMonitorList{}) + mClient.PrependReactor("get", "servicemonitors", func(_ clienttesting.Action) (bool, runtime.Object, error) { + return true, &monitoringv1.ServiceMonitor{ + ObjectMeta: metav1.ObjectMeta{ + Name: tc.name, + Namespace: tc.namespace, + }, + Spec: monitoringv1.ServiceMonitorSpec{ + Endpoints: []monitoringv1.Endpoint{ + { + Port: "http", + }, + }, + Selector: metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app": "test", + }, + }, + }, + }, nil + }) + + kClient := fake.NewSimpleClientset(&v1.ServiceList{}) + kClient.PrependReactor("list", "services", func(_ clienttesting.Action) (bool, runtime.Object, error) { + return true, &v1.ServiceList{ + Items: []v1.Service{}, + }, nil + }) + + return k8sutil.ClientSets{ + MClient: mClient, + KClient: kClient, + } + }, + }, + { + name: "ServiceMonitorMatchLabelsNoMatchingPorts", + namespace: "test", + shouldFail: true, + getMockedClientSets: func(tc testCase) k8sutil.ClientSets { + mClient := monitoringclient.NewSimpleClientset(&monitoringv1.ServiceMonitorList{}) + mClient.PrependReactor("get", "servicemonitors", func(_ clienttesting.Action) (bool, runtime.Object, error) { + return true, &monitoringv1.ServiceMonitor{ + ObjectMeta: metav1.ObjectMeta{ + Name: tc.name, + Namespace: tc.namespace, + }, + Spec: monitoringv1.ServiceMonitorSpec{ + Endpoints: []monitoringv1.Endpoint{ + { + Port: "http", + }, + }, + Selector: metav1.LabelSelector{ + MatchLabels: map[string]string{ + "app": "test", + }, + }, + }, + }, nil + }) + + kClient := fake.NewSimpleClientset(&v1.ServiceList{}) + kClient.PrependReactor("list", "services", func(_ clienttesting.Action) (bool, runtime.Object, error) { + return true, &v1.ServiceList{ + Items: []v1.Service{ + { + ObjectMeta: metav1.ObjectMeta{ + Name: "test", + Namespace: tc.namespace, + Labels: map[string]string{ + "app": "test", + }, + }, + Spec: v1.ServiceSpec{ + Ports: []v1.ServicePort{ + { + Name: "https", + }, + }, + Selector: map[string]string{ + "app": "test", + }, + }, + }, + }, + }, nil + }) + + return k8sutil.ClientSets{ + MClient: mClient, + KClient: kClient, + } + }, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + clientSets := tc.getMockedClientSets(tc) + err := RunServiceMonitorAnalyzer(context.Background(), clientSets, tc.name, tc.namespace) + if tc.shouldFail { + assert.Error(t, err) + } else { + assert.NoError(t, err) + } + }) + } +} diff --git a/internal/builder/alertmanager.go b/internal/builder/alertmanager.go index c32bb3a..0d35042 100644 --- a/internal/builder/alertmanager.go +++ b/internal/builder/alertmanager.go @@ -17,10 +17,10 @@ package builder import ( monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/client/applyconfiguration/monitoring/v1" corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" applyConfigCorev1 "k8s.io/client-go/applyconfigurations/core/v1" applyConfigMetav1 "k8s.io/client-go/applyconfigurations/meta/v1" + metav1 "k8s.io/client-go/applyconfigurations/meta/v1" "k8s.io/utils/ptr" ) @@ -81,8 +81,8 @@ func (a *AlertManagerBuilder) WithAlertManager() *AlertManagerBuilder { Spec: &monitoringv1.AlertmanagerSpecApplyConfiguration{ ServiceAccountName: a.manifets.ServiceAccount.Name, Replicas: ptr.To(int32(1)), - AlertmanagerConfigSelector: &metav1.LabelSelector{}, - AlertmanagerConfigNamespaceSelector: &metav1.LabelSelector{}, + AlertmanagerConfigSelector: &metav1.LabelSelectorApplyConfiguration{}, + AlertmanagerConfigNamespaceSelector: &metav1.LabelSelectorApplyConfiguration{}, }, } return a @@ -131,7 +131,7 @@ func (a *AlertManagerBuilder) WithServiceMonitor() *AlertManagerBuilder { Namespace: ptr.To(a.namespace), }, Spec: &monitoringv1.ServiceMonitorSpecApplyConfiguration{ - Selector: &metav1.LabelSelector{ + Selector: &metav1.LabelSelectorApplyConfiguration{ MatchLabels: a.labelSelectors, }, Endpoints: []monitoringv1.EndpointApplyConfiguration{ diff --git a/internal/builder/operator.go b/internal/builder/operator.go index 257262b..04f2bdf 100644 --- a/internal/builder/operator.go +++ b/internal/builder/operator.go @@ -20,11 +20,11 @@ import ( monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/client/applyconfiguration/monitoring/v1" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" applyCofongiAppsv1 "k8s.io/client-go/applyconfigurations/apps/v1" applyConfigCorev1 "k8s.io/client-go/applyconfigurations/core/v1" applyConfigMetav1 "k8s.io/client-go/applyconfigurations/meta/v1" + metav1 "k8s.io/client-go/applyconfigurations/meta/v1" applyConfigRbacv1 "k8s.io/client-go/applyconfigurations/rbac/v1" "k8s.io/utils/ptr" ) @@ -310,7 +310,7 @@ func (o *OperatorBuilder) WithServiceMonitor() *OperatorBuilder { Namespace: ptr.To(o.namespace), }, Spec: &monitoringv1.ServiceMonitorSpecApplyConfiguration{ - Selector: &metav1.LabelSelector{ + Selector: &metav1.LabelSelectorApplyConfiguration{ MatchLabels: o.labelSelectors, }, Endpoints: []monitoringv1.EndpointApplyConfiguration{ diff --git a/internal/builder/prometheus.go b/internal/builder/prometheus.go index 3a6b9cc..7acb480 100644 --- a/internal/builder/prometheus.go +++ b/internal/builder/prometheus.go @@ -17,10 +17,10 @@ package builder import ( monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/client/applyconfiguration/monitoring/v1" corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" applyConfigCorev1 "k8s.io/client-go/applyconfigurations/core/v1" applyConfigMetav1 "k8s.io/client-go/applyconfigurations/meta/v1" + metav1 "k8s.io/client-go/applyconfigurations/meta/v1" applyConfigRbacv1 "k8s.io/client-go/applyconfigurations/rbac/v1" "k8s.io/utils/ptr" ) @@ -145,19 +145,19 @@ func (p *PrometheusBuilder) WithPrometheus() *PrometheusBuilder { Spec: &monitoringv1.PrometheusSpecApplyConfiguration{ CommonPrometheusFieldsApplyConfiguration: monitoringv1.CommonPrometheusFieldsApplyConfiguration{ ServiceAccountName: p.manifets.ServiceAccount.Name, - ServiceMonitorSelector: &metav1.LabelSelector{}, - ServiceMonitorNamespaceSelector: &metav1.LabelSelector{}, - PodMonitorSelector: &metav1.LabelSelector{}, - PodMonitorNamespaceSelector: &metav1.LabelSelector{}, - ProbeSelector: &metav1.LabelSelector{}, - ProbeNamespaceSelector: &metav1.LabelSelector{}, - ScrapeConfigSelector: &metav1.LabelSelector{}, - ScrapeConfigNamespaceSelector: &metav1.LabelSelector{}, + ServiceMonitorSelector: &metav1.LabelSelectorApplyConfiguration{}, + ServiceMonitorNamespaceSelector: &metav1.LabelSelectorApplyConfiguration{}, + PodMonitorSelector: &metav1.LabelSelectorApplyConfiguration{}, + PodMonitorNamespaceSelector: &metav1.LabelSelectorApplyConfiguration{}, + ProbeSelector: &metav1.LabelSelectorApplyConfiguration{}, + ProbeNamespaceSelector: &metav1.LabelSelectorApplyConfiguration{}, + ScrapeConfigSelector: &metav1.LabelSelectorApplyConfiguration{}, + ScrapeConfigNamespaceSelector: &metav1.LabelSelectorApplyConfiguration{}, ImagePullPolicy: ptr.To(corev1.PullIfNotPresent), Replicas: ptr.To(int32(2)), }, - RuleSelector: &metav1.LabelSelector{}, - RuleNamespaceSelector: &metav1.LabelSelector{}, + RuleSelector: &metav1.LabelSelectorApplyConfiguration{}, + RuleNamespaceSelector: &metav1.LabelSelectorApplyConfiguration{}, Alerting: &monitoringv1.AlertingSpecApplyConfiguration{ Alertmanagers: []monitoringv1.AlertmanagerEndpointsApplyConfiguration{ { @@ -209,7 +209,7 @@ func (p *PrometheusBuilder) WithServiceMonitor() *PrometheusBuilder { Namespace: ptr.To(p.namespace), }, Spec: &monitoringv1.ServiceMonitorSpecApplyConfiguration{ - Selector: &metav1.LabelSelector{ + Selector: &metav1.LabelSelectorApplyConfiguration{ MatchLabels: p.labelSelectors, }, Endpoints: []monitoringv1.EndpointApplyConfiguration{ diff --git a/internal/k8sutil/k8sutil.go b/internal/k8sutil/k8sutil.go index d4452ae..6b0e948 100644 --- a/internal/k8sutil/k8sutil.go +++ b/internal/k8sutil/k8sutil.go @@ -101,6 +101,11 @@ func CrdDeserilezer(logger *slog.Logger, reader io.ReadCloser) (runtime.Object, return obj, nil } +type ClientSets struct { + KClient kubernetes.Interface + MClient monitoringclient.Interface +} + func GetClientSets(kubeconfig string) (*kubernetes.Clientset, *monitoringclient.Clientset, error) { restConfig, err := GetRestConfig(kubeconfig) if err != nil {