Skip to content

Commit ef1d7b2

Browse files
committed
Ensure ServiceMonitor's endpoints are protected
1 parent 848143e commit ef1d7b2

File tree

1 file changed

+89
-0
lines changed

1 file changed

+89
-0
lines changed

test/extended/prometheus/prometheus.go

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
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,92 @@ 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+
client, err := prometheusoperatorv1client.NewForConfig(oc.AdminConfig())
75+
o.Expect(err).NotTo(o.HaveOccurred(), "Create monitoring client")
76+
77+
g.By("verifying all service monitors are configured with authorization")
78+
serviceMonitorList, err := client.ServiceMonitors("").List(context.Background(), metav1.ListOptions{})
79+
o.Expect(err).NotTo(o.HaveOccurred(), "List service monitors")
80+
81+
for _, sm := range serviceMonitorList.Items {
82+
// we do not check service monitors for user-workload-monitoring
83+
if !strings.HasPrefix(sm.Namespace, "openshift-") {
84+
continue
85+
}
86+
if componentNamespace != "" && sm.Namespace != componentNamespace {
87+
continue
88+
}
89+
if !authorizationConfigured(sm) {
90+
errs = append(errs, fmt.Errorf("service monitor %s/%s has no authorization", sm.Namespace, sm.Name))
91+
} else {
92+
e2e.Logf("service monitor %s/%s has authorization", sm.Namespace, sm.Name)
93+
}
94+
}
95+
96+
g.By("verifying all targets returns 401 or 403 without authorization")
97+
contents, err := helper.GetURLWithToken(helper.MustJoinUrlPath(prometheusURL, "api/v1/targets"), bearerToken)
98+
o.Expect(err).NotTo(o.HaveOccurred())
99+
100+
targets := &prometheusTargets{}
101+
err = json.Unmarshal([]byte(contents), targets)
102+
o.Expect(err).NotTo(o.HaveOccurred())
103+
104+
for _, target := range targets.Data.ActiveTargets {
105+
ns := target.Labels["namespace"]
106+
if !strings.HasPrefix(ns, "openshift-") {
107+
continue
108+
}
109+
if componentNamespace != "" && ns != componentNamespace {
110+
continue
111+
}
112+
err = helper.ExpectURLStatusCodeExecViaPod("openshift-monitoring", "prometheus-k8s-0", target.ScrapeUrl, 401, 403)
113+
if err != nil {
114+
errs = append(errs, fmt.Errorf("the scaple url %s for namespace %s is accessible without authorization: %w", target.ScrapeUrl, ns, err))
115+
} else {
116+
e2e.Logf("the scaple url %s for namespace %s is not accessible without authorization", target.ScrapeUrl, ns)
117+
}
118+
}
119+
o.Expect(errs).To(o.BeEmpty())
120+
})
121+
122+
})
123+
124+
// authorizationConfigured returns true if the service monitor is configured with authorization
125+
func authorizationConfigured(sm *prometheusoperatorv1.ServiceMonitor) bool {
126+
if sm == nil {
127+
return false
128+
}
129+
for _, e := range sm.Spec.Endpoints {
130+
if e.BasicAuth != nil ||
131+
e.OAuth2 != nil ||
132+
e.Authorization != nil ||
133+
e.BearerTokenFile != "" ||
134+
e.BearerTokenSecret != nil {
135+
return true
136+
}
137+
}
138+
return false
139+
}
140+
52141
var _ = g.Describe("[sig-instrumentation][Late] OpenShift alerting rules [apigroup:image.openshift.io]", func() {
53142
defer g.GinkgoRecover()
54143

0 commit comments

Comments
 (0)