Skip to content

Commit a04d850

Browse files
committed
MON-3134: allow to query alerts from thanos-querier tenancy port
Allows to query alerts from application namespaces as an application user. Add e2e test to verify alerts tenancy Signed-off-by: Jayapriya Pai <[email protected]>
1 parent 8377489 commit a04d850

File tree

4 files changed

+66
-39
lines changed

4 files changed

+66
-39
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
- [#2022](https://github.com/openshift/cluster-monitoring-operator/pull/2022) Add support to switch to metrics server from prometheus-adapter when the `MetricsServer` feature gate is enabled.
66
- [#2161](https://github.com/openshift/cluster-monitoring-operator/pull/2161) Add `PrometheusRestrictedConfig.RemoteWrite[].SendExemplars`.
7+
- [#2184](https://github.com/openshift/cluster-monitoring-operator/issues/2184) Allow to query alerts of application namespaces as an application user from command line.
78

89
## 4.14
910

assets/thanos-querier/deployment.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ spec:
201201
- --tls-cert-file=/etc/tls/private/tls.crt
202202
- --tls-private-key-file=/etc/tls/private/tls.key
203203
- --tls-cipher-suites=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305
204-
- --allow-paths=/api/v1/rules
204+
- --allow-paths=/api/v1/rules,/api/v1/alerts
205205
image: quay.io/brancz/kube-rbac-proxy:v0.15.0
206206
name: kube-rbac-proxy-rules
207207
ports:

jsonnet/components/thanos-querier.libsonnet

+4-1
Original file line numberDiff line numberDiff line change
@@ -555,7 +555,10 @@ function(params)
555555
'--tls-cert-file=/etc/tls/private/tls.crt',
556556
'--tls-private-key-file=/etc/tls/private/tls.key',
557557
'--tls-cipher-suites=' + cfg.tlsCipherSuites,
558-
'--allow-paths=/api/v1/rules',
558+
'--allow-paths=' + std.join(',', [
559+
'/api/v1/rules',
560+
'/api/v1/alerts',
561+
]),
559562
],
560563
terminationMessagePolicy: 'FallbackToLogsOnError',
561564
volumeMounts: [

test/e2e/user_workload_monitoring_test.go

+60-37
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,8 @@ func TestUserWorkloadMonitoringAlerting(t *testing.T) {
129129
f: assertUserWorkloadRules,
130130
},
131131
{
132-
name: "assert tenancy model is enforced for rules",
133-
f: assertTenancyForRules,
132+
name: "assert tenancy model is enforced for rules and alerts",
133+
f: assertTenancyForRulesAndAlerts,
134134
},
135135
{
136136
name: "assert prometheus is not deployed in user namespace",
@@ -664,44 +664,46 @@ func assertTenancyForMetrics(t *testing.T) {
664664
})
665665
}
666666

667-
// Check that the account doesn't have to access the rules endpoint.
668-
err = framework.Poll(5*time.Second, time.Minute, func() error {
669-
// The tenancy port (9092) is only exposed in-cluster so we need to use
670-
// port forwarding to access kube-rbac-proxy.
671-
host, cleanUp, err := f.ForwardPort(t, f.Ns, "thanos-querier", 9092)
672-
if err != nil {
673-
t.Fatal(err)
674-
}
675-
defer cleanUp()
667+
// Check that the account doesn't have to access the rules and alerts endpoint.
668+
for _, path := range []string{"/api/v1/rules", "/api/v1/alerts"} {
669+
err = framework.Poll(5*time.Second, time.Minute, func() error {
670+
// The tenancy port (9092) is only exposed in-cluster so we need to use
671+
// port forwarding to access kube-rbac-proxy.
672+
host, cleanUp, err := f.ForwardPort(t, f.Ns, "thanos-querier", 9092)
673+
if err != nil {
674+
t.Fatal(err)
675+
}
676+
defer cleanUp()
676677

677-
client := framework.NewPrometheusClient(
678-
host,
679-
token,
680-
&framework.QueryParameterInjector{
681-
Name: "namespace",
682-
Value: userWorkloadTestNs,
683-
},
684-
)
678+
client := framework.NewPrometheusClient(
679+
host,
680+
token,
681+
&framework.QueryParameterInjector{
682+
Name: "namespace",
683+
Value: userWorkloadTestNs,
684+
},
685+
)
685686

686-
resp, err := client.Do("GET", "/api/v1/rules", nil)
687-
if err != nil {
688-
return err
689-
}
690-
defer resp.Body.Close()
687+
resp, err := client.Do("GET", path, nil)
688+
if err != nil {
689+
return err
690+
}
691+
defer resp.Body.Close()
691692

692-
b, err := io.ReadAll(resp.Body)
693-
if err != nil {
694-
return err
695-
}
693+
b, err := io.ReadAll(resp.Body)
694+
if err != nil {
695+
return err
696+
}
696697

697-
if resp.StatusCode/100 == 2 {
698-
return fmt.Errorf("expected request to be rejected, but got status code %d (%s)", resp.StatusCode, framework.ClampMax(b))
699-
}
698+
if resp.StatusCode/100 == 2 {
699+
return fmt.Errorf("expected request to be rejected, but got status code %d (%s)", resp.StatusCode, framework.ClampMax(b))
700+
}
700701

701-
return nil
702-
})
703-
if err != nil {
704-
t.Fatalf("the account has access to the rules endpoint of Thanos querier: %v", err)
702+
return nil
703+
})
704+
if err != nil {
705+
t.Fatalf("the account has access to the %q endpoint of Thanos querier: %v", path, err)
706+
}
705707
}
706708

707709
for _, tc := range []struct {
@@ -821,8 +823,8 @@ func assertTenancyForMetrics(t *testing.T) {
821823
}
822824
}
823825

824-
// assertTenancyForRules ensures that a tenant can access rules from her namespace (and only from this one).
825-
func assertTenancyForRules(t *testing.T) {
826+
// assertTenancyForRulesAndAlerts ensures that a tenant can access rules and alerts from her namespace (and only from this one).
827+
func assertTenancyForRulesAndAlerts(t *testing.T) {
826828
const testAccount = "test-rules"
827829

828830
_, err := f.CreateServiceAccount(userWorkloadTestNs, testAccount)
@@ -951,6 +953,27 @@ func assertTenancyForRules(t *testing.T) {
951953
t.Fatalf("failed to query rules from Thanos querier: %v", err)
952954
}
953955

956+
err = framework.Poll(5*time.Second, time.Minute, func() error {
957+
resp, err := client.Do("GET", "/api/v1/alerts", nil)
958+
if err != nil {
959+
return err
960+
}
961+
defer resp.Body.Close()
962+
963+
b, err := io.ReadAll(resp.Body)
964+
if err != nil {
965+
return err
966+
}
967+
968+
if resp.StatusCode != http.StatusOK {
969+
return fmt.Errorf("unexpected status code response, want %d, got %d (%s)", http.StatusOK, resp.StatusCode, framework.ClampMax(b))
970+
}
971+
return nil
972+
})
973+
if err != nil {
974+
t.Fatalf("failed to query alerts from Thanos querier: %v", err)
975+
}
976+
954977
// Check that the account doesn't have to access the query endpoints.
955978
for _, path := range []string{"/api/v1/range?query=up", "/api/v1/query_range?query=up&start=0&end=0&step=1s"} {
956979
err = framework.Poll(5*time.Second, time.Minute, func() error {

0 commit comments

Comments
 (0)