55 "context"
66 "encoding/json"
77 "fmt"
8+ "os"
89 "regexp"
910 "strings"
1011 "time"
@@ -14,6 +15,8 @@ import (
1415
1516 g "github.com/onsi/ginkgo/v2"
1617 o "github.com/onsi/gomega"
18+ prometheusoperatorv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
19+ prometheusoperatorv1client "github.com/prometheus-operator/prometheus-operator/pkg/client/versioned/typed/monitoring/v1"
1720 promv1 "github.com/prometheus/client_golang/api/prometheus/v1"
1821 dto "github.com/prometheus/client_model/go"
1922 "github.com/prometheus/common/expfmt"
@@ -49,6 +52,97 @@ type TelemeterClientConfig struct {
4952 Enabled * bool `json:"enabled"`
5053}
5154
55+ var componentNamespace = os .Getenv ("COMPONENT_NAMESPACE" )
56+
57+ var _ = g .Describe ("[sig-instrumentation][Late] OpenShift service monitors [apigroup:image.openshift.io]" , func () {
58+ defer g .GinkgoRecover ()
59+ var (
60+ oc = exutil .NewCLIWithoutNamespace ("prometheus" )
61+ prometheusURL , bearerToken string
62+ )
63+
64+ g .BeforeEach (func (ctx g.SpecContext ) {
65+ var err error
66+ prometheusURL , err = helper .PrometheusRouteURL (ctx , oc )
67+ o .Expect (err ).NotTo (o .HaveOccurred (), "Get public url of prometheus" )
68+ bearerToken , err = helper .RequestPrometheusServiceAccountAPIToken (ctx , oc )
69+ o .Expect (err ).NotTo (o .HaveOccurred (), "Request prometheus service account API token" )
70+ })
71+
72+ g .It ("should not be accessible without authorization" , func () {
73+ var errs []error
74+
75+ g .By ("verifying all targets returns 401 or 403 without authorization" )
76+ contents , err := helper .GetURLWithToken (helper .MustJoinUrlPath (prometheusURL , "api/v1/targets" ), bearerToken )
77+ o .Expect (err ).NotTo (o .HaveOccurred ())
78+
79+ targets := & prometheusTargets {}
80+ err = json .Unmarshal ([]byte (contents ), targets )
81+ o .Expect (err ).NotTo (o .HaveOccurred ())
82+
83+ for _ , target := range targets .Data .ActiveTargets {
84+ ns := target .Labels ["namespace" ]
85+ if ! strings .HasPrefix (ns , "openshift-" ) {
86+ continue
87+ }
88+ if componentNamespace != "" && ns != componentNamespace {
89+ continue
90+ }
91+ // Error out only when the status code is obtained
92+ // Error on executing the cmd is skipped here because the endpoint does not expose any information.
93+ // Promethus may have troubles to scrape it but that is out of the scape of this test
94+ err = helper .ExpectURLStatusCodeExecViaPod ("openshift-monitoring" , "prometheus-k8s-0" , target .ScrapeUrl , true , 401 , 403 )
95+ if err != nil {
96+ errs = append (errs , fmt .Errorf ("the scaple url %s for namespace %s is accessible without authorization: %w" , target .ScrapeUrl , ns , err ))
97+ } else {
98+ e2e .Logf ("the scaple url %s for namespace %s is not accessible without authorization" , target .ScrapeUrl , ns )
99+ }
100+ }
101+
102+ g .By ("verifying all service monitors are configured with authorization" )
103+ client , err := prometheusoperatorv1client .NewForConfig (oc .AdminConfig ())
104+ o .Expect (err ).NotTo (o .HaveOccurred (), "Create monitoring client" )
105+
106+ serviceMonitorList , err := client .ServiceMonitors ("" ).List (context .Background (), metav1.ListOptions {})
107+ o .Expect (err ).NotTo (o .HaveOccurred (), "List service monitors" )
108+
109+ for _ , sm := range serviceMonitorList .Items {
110+ // we do not check service monitors for user-workload-monitoring
111+ if ! strings .HasPrefix (sm .Namespace , "openshift-" ) {
112+ continue
113+ }
114+ if componentNamespace != "" && sm .Namespace != componentNamespace {
115+ continue
116+ }
117+ if ! authorizationConfigured (sm ) {
118+ errs = append (errs , fmt .Errorf ("service monitor %s/%s has no authorization" , sm .Namespace , sm .Name ))
119+ } else {
120+ e2e .Logf ("service monitor %s/%s has authorization" , sm .Namespace , sm .Name )
121+ }
122+ }
123+
124+ o .Expect (errs ).To (o .BeEmpty ())
125+ })
126+
127+ })
128+
129+ // authorizationConfigured returns true if the service monitor is configured with authorization
130+ func authorizationConfigured (sm * prometheusoperatorv1.ServiceMonitor ) bool {
131+ if sm == nil {
132+ return false
133+ }
134+ for _ , e := range sm .Spec .Endpoints {
135+ if e .BasicAuth != nil ||
136+ e .OAuth2 != nil ||
137+ e .Authorization != nil ||
138+ e .BearerTokenFile != "" ||
139+ e .BearerTokenSecret != nil {
140+ return true
141+ }
142+ }
143+ return false
144+ }
145+
52146var _ = g .Describe ("[sig-instrumentation][Late] OpenShift alerting rules [apigroup:image.openshift.io]" , func () {
53147 defer g .GinkgoRecover ()
54148
@@ -549,7 +643,7 @@ var _ = g.Describe("[sig-instrumentation] Prometheus [apigroup:image.openshift.i
549643 })).NotTo (o .HaveOccurred (), fmt .Sprintf ("Did not find tsdb_samples_appended_total, tsdb_head_samples_appended_total, or prometheus_tsdb_head_samples_appended_total" ))
550644
551645 g .By ("verifying the Thanos querier service requires authentication" )
552- err := helper .ExpectURLStatusCodeExecViaPod (ns , execPod .Name , querySvcURL , 401 , 403 )
646+ err := helper .ExpectURLStatusCodeExecViaPod (ns , execPod .Name , querySvcURL , false , 401 , 403 )
553647 o .Expect (err ).NotTo (o .HaveOccurred ())
554648
555649 g .By ("verifying a service account token is able to authenticate" )
0 commit comments