Skip to content

Commit 709876a

Browse files
Merge pull request #1299 from raptorsun/feature/MON-1695
[MON-1695] expose /api/v1/labels end point for Thanos query.
2 parents e8df44e + 14bf8bc commit 709876a

File tree

5 files changed

+173
-5
lines changed

5 files changed

+173
-5
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Note: This CHANGELOG is only for the monitoring team to track all monitoring related changes. Please see OpenShift release notes for official changes.
22

3+
## 4.10
4+
5+
- [#1299](https://github.com/openshift/cluster-monitoring-operator/pull/1299) Expose expose /api/v1/labels endpoint for Thanos query.
6+
37
## 4.9
48

59
- [#1312](https://github.com/openshift/cluster-monitoring-operator/pull/1312) Support label to exclude namespaces from user-workload monitoring.

assets/thanos-querier/deployment.yaml

+2-1
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ spec:
140140
- --tls-private-key-file=/etc/tls/private/tls.key
141141
- --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
142142
- --logtostderr=true
143-
- --allow-paths=/api/v1/query,/api/v1/query_range
143+
- --allow-paths=/api/v1/query,/api/v1/query_range,/api/v1/labels,/api/v1/label/*/values
144144
image: quay.io/brancz/kube-rbac-proxy:v0.11.0
145145
name: kube-rbac-proxy
146146
ports:
@@ -160,6 +160,7 @@ spec:
160160
- --insecure-listen-address=127.0.0.1:9095
161161
- --upstream=http://127.0.0.1:9090
162162
- --label=namespace
163+
- --enable-label-apis
163164
image: quay.io/prometheuscommunity/prom-label-proxy:v0.3.0
164165
name: prom-label-proxy
165166
resources:

jsonnet/components/thanos-querier.libsonnet

+2-1
Original file line numberDiff line numberDiff line change
@@ -484,7 +484,7 @@ function(params)
484484
'--tls-private-key-file=/etc/tls/private/tls.key',
485485
'--tls-cipher-suites=' + cfg.tlsCipherSuites,
486486
'--logtostderr=true',
487-
'--allow-paths=/api/v1/query,/api/v1/query_range',
487+
'--allow-paths=/api/v1/query,/api/v1/query_range,/api/v1/labels,/api/v1/label/*/values',
488488
],
489489
terminationMessagePolicy: 'FallbackToLogsOnError',
490490
volumeMounts: [
@@ -505,6 +505,7 @@ function(params)
505505
'--insecure-listen-address=127.0.0.1:9095',
506506
'--upstream=http://127.0.0.1:9090',
507507
'--label=namespace',
508+
'--enable-label-apis',
508509
],
509510
resources: {
510511
requests: {

test/e2e/framework/client.go

+21
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,27 @@ func (c *PrometheusClient) PrometheusRules() ([]byte, error) {
211211
return body, nil
212212
}
213213

214+
// PrometheusRules runs an HTTP GET request against the Prometheus label API and returns
215+
// the response body.
216+
func (c *PrometheusClient) PrometheusLabel(label string) ([]byte, error) {
217+
resp, err := c.Do("GET", fmt.Sprintf("/api/v1/label/%s/values", url.QueryEscape(label)), nil)
218+
if err != nil {
219+
return nil, err
220+
}
221+
defer resp.Body.Close()
222+
223+
body, err := ioutil.ReadAll(resp.Body)
224+
if err != nil {
225+
return nil, err
226+
}
227+
228+
if resp.StatusCode != http.StatusOK {
229+
return nil, fmt.Errorf("unexpected status code response, want %d, got %d (%q)", http.StatusOK, resp.StatusCode, ClampMax(body))
230+
}
231+
232+
return body, nil
233+
}
234+
214235
// AlertmanagerQueryAlerts runs an HTTP GET request against the Alertmanager
215236
// /api/v2/alerts endpoint and returns the response body.
216237
func (c *PrometheusClient) AlertmanagerQueryAlerts(kvs ...string) ([]byte, error) {

test/e2e/user_workload_monitoring_test.go

+144-3
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,10 @@ func TestUserWorkloadMonitoringMetrics(t *testing.T) {
8787
name: "assert tenancy model is enforced for metrics",
8888
f: assertTenancyForMetrics,
8989
},
90+
{
91+
name: "assert tenancy model is enforced for labels",
92+
f: assertTenancyForLabels,
93+
},
9094
{
9195
name: "assert prometheus is not deployed in user namespace",
9296
f: f.AssertStatefulsetDoesNotExist("prometheus-not-to-be-reconciled", userWorkloadTestNs),
@@ -247,13 +251,13 @@ func TestUserWorkloadMonitoringWithAdditionalAlertmanagerConfigs(t *testing.T) {
247251
timeout: "30s"
248252
apiVersion: v1
249253
tlsConfig:
250-
key:
254+
key:
251255
name: alertmanager-tls
252256
key: tls.key
253-
cert:
257+
cert:
254258
name: alertmanager-tls
255259
key: tls.crt
256-
ca:
260+
ca:
257261
name: alertmanager-tls
258262
key: tls.ca
259263
staticConfigs: ["127.0.0.1", "127.0.0.2"]
@@ -860,6 +864,143 @@ func assertTenancyForRules(t *testing.T) {
860864
}
861865
}
862866

867+
func assertTenancyForLabels(t *testing.T) {
868+
const testAccount = "test-labels"
869+
870+
_, err := f.CreateServiceAccount(userWorkloadTestNs, testAccount)
871+
if err != nil {
872+
t.Fatal(err)
873+
}
874+
875+
// Grant enough permissions to read labels.
876+
_, err = f.CreateRoleBindingFromClusterRole(userWorkloadTestNs, testAccount, "admin")
877+
if err != nil {
878+
t.Fatal(err)
879+
}
880+
881+
var token string
882+
err = framework.Poll(5*time.Second, 5*time.Minute, func() error {
883+
token, err = f.GetServiceAccountToken(userWorkloadTestNs, testAccount)
884+
if err != nil {
885+
return err
886+
}
887+
return nil
888+
})
889+
if err != nil {
890+
t.Fatal(err)
891+
}
892+
893+
// The tenancy port (9092) is only exposed in-cluster so we need to use
894+
// port forwarding to access kube-rbac-proxy.
895+
host, cleanUp, err := f.ForwardPort(t, "thanos-querier", 9092)
896+
if err != nil {
897+
t.Fatal(err)
898+
}
899+
defer cleanUp()
900+
901+
client := framework.NewPrometheusClient(
902+
host,
903+
token,
904+
&framework.QueryParameterInjector{
905+
Name: "namespace",
906+
Value: userWorkloadTestNs,
907+
},
908+
)
909+
910+
t.Logf("Checking all labels")
911+
912+
// check /api/v1/labels endpoint
913+
err = framework.Poll(5*time.Second, time.Minute, func() error {
914+
resp, err := client.Do("GET", "/api/v1/labels", nil)
915+
if err != nil {
916+
return err
917+
}
918+
defer resp.Body.Close()
919+
920+
b, err := ioutil.ReadAll(resp.Body)
921+
if err != nil {
922+
return err
923+
}
924+
925+
if resp.StatusCode != http.StatusOK {
926+
return fmt.Errorf("unexpected status code response, want %d, got %d (%s)", http.StatusOK, resp.StatusCode, framework.ClampMax(b))
927+
}
928+
929+
res, err := gabs.ParseJSON(b)
930+
if err != nil {
931+
return err
932+
}
933+
934+
labels, err := res.Path("data").Children()
935+
if err != nil {
936+
return err
937+
}
938+
939+
for _, label := range labels {
940+
t.Logf("label %q", label.Data().(string))
941+
}
942+
943+
if len(labels) == 0 {
944+
return errors.Errorf("expecting a label list with at least one item.")
945+
}
946+
947+
return nil
948+
949+
})
950+
if err != nil {
951+
t.Fatalf("failed to query labels from Thanos querier: %v", err)
952+
}
953+
954+
// check /api/v1/label/namespace/values has a single value
955+
t.Logf("Checking Label namespace having a single value")
956+
const label = "namespace"
957+
958+
err = framework.Poll(5*time.Second, time.Minute, func() error {
959+
// The tenancy port (9092) is only exposed in-cluster so we need to use
960+
// port forwarding to access kube-rbac-proxy.
961+
host, cleanUp, err := f.ForwardPort(t, "thanos-querier", 9092)
962+
if err != nil {
963+
t.Fatal(err)
964+
}
965+
defer cleanUp()
966+
967+
client := framework.NewPrometheusClient(
968+
host,
969+
token,
970+
&framework.QueryParameterInjector{
971+
Name: "namespace",
972+
Value: userWorkloadTestNs,
973+
},
974+
)
975+
976+
b, err := client.PrometheusLabel(label)
977+
if err != nil {
978+
return err
979+
}
980+
981+
res, err := gabs.ParseJSON(b)
982+
if err != nil {
983+
return err
984+
}
985+
986+
values, err := res.Path("data").Children()
987+
if err != nil {
988+
return err
989+
}
990+
991+
if len(values) != 1 {
992+
return errors.Errorf("expecting for label %q value list with exact one item.", label)
993+
}
994+
995+
if values[0].Data().(string) != userWorkloadTestNs {
996+
return errors.Errorf("expecting for label %q having value %q, but got %q .", label, userWorkloadTestNs, values[0].Data().(string))
997+
}
998+
999+
return nil
1000+
})
1001+
1002+
}
1003+
8631004
func assertGRPCTLSRotation(t *testing.T) {
8641005
ctx := context.Background()
8651006
countGRPCSecrets := func(ns string) int {

0 commit comments

Comments
 (0)