1+ //nolint:gosec
12package e2e
23
34import (
@@ -7,9 +8,10 @@ import (
78 "testing"
89
910 "github.com/stretchr/testify/require"
11+
12+ "github.com/operator-framework/operator-controller/test/utils"
1013)
1114
12- // nolint:gosec
1315// TestOperatorControllerMetricsExportedEndpoint verifies that the metrics endpoint for the operator controller
1416// is exported correctly and accessible by authorized users through RBAC and a ServiceAccount token.
1517// The test performs the following steps:
@@ -20,103 +22,15 @@ import (
2022// 5. Executes a curl command from the pod to validate the metrics endpoint.
2123// 6. Cleans up all resources created during the test, such as the ClusterRoleBinding and curl pod.
2224func TestOperatorControllerMetricsExportedEndpoint (t * testing.T ) {
23- var (
24- token string
25- curlPod = "curl-metrics"
26- client = ""
27- clients = []string {"kubectl" , "oc" }
28- )
29-
30- t .Log ("Looking for k8s client" )
31- for _ , c := range clients {
32- // Would prefer to use `command -v`, but even that may not be installed!
33- err := exec .Command (c , "version" , "--client" ).Run ()
34- if err == nil {
35- client = c
36- break
37- }
38- }
39- if client == "" {
40- t .Fatal ("k8s client not found" )
41- }
42- t .Logf ("Using %q as k8s client" , client )
43-
44- t .Log ("Determining operator-controller namespace" )
45- cmd := exec .Command (client , "get" , "pods" , "--all-namespaces" , "--selector=control-plane=operator-controller-controller-manager" , "--output=jsonpath={.items[0].metadata.namespace}" )
46- output , err := cmd .CombinedOutput ()
47- require .NoError (t , err , "Error creating determining operator-controller namespace: %s" , string (output ))
48- namespace := string (output )
49- if namespace == "" {
50- t .Fatal ("No operator-controller namespace found" )
51- }
52- t .Logf ("Using %q as operator-controller namespace" , namespace )
53-
54- t .Log ("Creating ClusterRoleBinding for operator controller metrics" )
55- cmd = exec .Command (client , "create" , "clusterrolebinding" , "operator-controller-metrics-binding" ,
56- "--clusterrole=operator-controller-metrics-reader" ,
57- "--serviceaccount=" + namespace + ":operator-controller-controller-manager" )
58- output , err = cmd .CombinedOutput ()
59- require .NoError (t , err , "Error creating ClusterRoleBinding: %s" , string (output ))
60-
61- defer func () {
62- t .Log ("Cleaning up ClusterRoleBinding" )
63- _ = exec .Command (client , "delete" , "clusterrolebinding" , "operator-controller-metrics-binding" , "--ignore-not-found=true" ).Run ()
64- }()
65-
66- t .Log ("Generating ServiceAccount token" )
67- tokenCmd := exec .Command (client , "create" , "token" , "operator-controller-controller-manager" , "-n" , namespace )
68- tokenOutput , tokenCombinedOutput , err := stdoutAndCombined (tokenCmd )
69- require .NoError (t , err , "Error creating token: %s" , string (tokenCombinedOutput ))
70- token = string (bytes .TrimSpace (tokenOutput ))
71-
72- t .Log ("Creating curl pod to validate the metrics endpoint" )
73- cmd = exec .Command (client , "run" , curlPod ,
74- "--image=curlimages/curl:7.87.0" , "-n" , namespace ,
75- "--restart=Never" ,
76- "--overrides" , `{
77- "spec": {
78- "containers": [{
79- "name": "curl",
80- "image": "curlimages/curl:7.87.0",
81- "command": ["sh", "-c", "sleep 3600"],
82- "securityContext": {
83- "allowPrivilegeEscalation": false,
84- "capabilities": {
85- "drop": ["ALL"]
86- },
87- "runAsNonRoot": true,
88- "runAsUser": 1000,
89- "seccompProfile": {
90- "type": "RuntimeDefault"
91- }
92- }
93- }],
94- "serviceAccountName": "operator-controller-controller-manager"
95- }
96- }` )
97- output , err = cmd .CombinedOutput ()
98- require .NoError (t , err , "Error creating curl pod: %s" , string (output ))
99-
100- defer func () {
101- t .Log ("Cleaning up curl pod" )
102- _ = exec .Command (client , "delete" , "pod" , curlPod , "-n" , namespace , "--ignore-not-found=true" ).Run ()
103- }()
104-
105- t .Log ("Waiting for the curl pod to be ready" )
106- waitCmd := exec .Command (client , "wait" , "--for=condition=Ready" , "pod" , curlPod , "-n" , namespace , "--timeout=60s" )
107- waitOutput , waitErr := waitCmd .CombinedOutput ()
108- require .NoError (t , waitErr , "Error waiting for curl pod to be ready: %s" , string (waitOutput ))
109-
110- t .Log ("Validating the metrics endpoint" )
111- metricsURL := "https://operator-controller-service." + namespace + ".svc.cluster.local:8443/metrics"
112- curlCmd := exec .Command (client , "exec" , curlPod , "-n" , namespace , "--" ,
113- "curl" , "-v" , "-k" , "-H" , "Authorization: Bearer " + token , metricsURL )
114- output , err = curlCmd .CombinedOutput ()
115- require .NoError (t , err , "Error calling metrics endpoint: %s" , string (output ))
116- require .Contains (t , string (output ), "200 OK" , "Metrics endpoint did not return 200 OK" )
25+ client := utils .FindK8sClient (t )
26+ namespace := getNamespace (t , client , "control-plane=operator-controller-controller-manager" )
27+ createClusterRoleBinding (t , client , "operator-controller-metrics-binding" , "operator-controller-metrics-reader" , namespace , "operator-controller-controller-manager" )
28+ token := createServiceAccountToken (t , client , namespace , "operator-controller-controller-manager" )
29+ createCurlPod (t , client , namespace , "curl-metrics" , "operator-controller-controller-manager" )
30+ waitForPodReady (t , client , namespace , "curl-metrics" )
31+ validateMetricsEndpoint (t , client , namespace , "curl-metrics" , token , "https://operator-controller-service." + namespace + ".svc.cluster.local:8443/metrics" )
11732}
11833
119- // nolint:gosec
12034// TestCatalogdMetricsExportedEndpoint verifies that the metrics endpoint for the catalogd
12135// is exported correctly and accessible by authorized users through RBAC and a ServiceAccount token.
12236// The test performs the following steps:
@@ -127,57 +41,52 @@ func TestOperatorControllerMetricsExportedEndpoint(t *testing.T) {
12741// 5. Executes a curl command from the pod to validate the metrics endpoint.
12842// 6. Cleans up all resources created during the test, such as the ClusterRoleBinding and curl pod.
12943func TestCatalogdMetricsExportedEndpoint (t * testing.T ) {
130- var (
131- token string
132- curlPod = "curl-metrics"
133- client = ""
134- clients = []string {"kubectl" , "oc" }
135- )
136-
137- t .Log ("Looking for k8s client" )
138- for _ , c := range clients {
139- // Would prefer to use `command -v`, but even that may not be installed!
140- err := exec .Command (c , "version" , "--client" ).Run ()
141- if err == nil {
142- client = c
143- break
144- }
145- }
146- if client == "" {
147- t .Fatal ("k8s client not found" )
148- }
149- t .Logf ("Using %q as k8s client" , client )
44+ client := utils .FindK8sClient (t )
45+ namespace := getNamespace (t , client , "control-plane=catalogd-controller-manager" )
46+ createClusterRoleBinding (t , client , "catalogd-metrics-binding" , "catalogd-metrics-reader" , namespace , "catalogd-controller-manager" )
47+ token := createServiceAccountToken (t , client , namespace , "catalogd-controller-manager" )
48+ createCurlPod (t , client , namespace , "curl-metrics" , "catalogd-controller-manager" )
49+ waitForPodReady (t , client , namespace , "curl-metrics" )
50+ validateMetricsEndpoint (t , client , namespace , "curl-metrics" , token , "https://catalogd-service." + namespace + ".svc.cluster.local:7443/metrics" )
51+ }
15052
151- t . Log ( "Determining catalogd namespace" )
152- cmd := exec .Command (client , "get" , "pods" , "--all-namespaces" , "--selector=control-plane=catalogd-controller-manager" , "--output=jsonpath={.items[0].metadata.namespace}" )
53+ func getNamespace ( t * testing. T , client , selector string ) string {
54+ cmd := exec .Command (client , "get" , "pods" , "--all-namespaces" , "--selector=" + selector , "--output=jsonpath={.items[0].metadata.namespace}" )
15355 output , err := cmd .CombinedOutput ()
154- require .NoError (t , err , "Error creating determining catalogd namespace: %s" , string (output ))
155- namespace := string (output )
56+ require .NoError (t , err , "Error determining namespace: %s" , string (output ))
57+
58+ namespace := string (bytes .TrimSpace (output ))
15659 if namespace == "" {
157- t .Fatal ("No catalogd namespace found" )
60+ t .Fatal ("No namespace found for selector " + selector )
15861 }
159- t .Logf ("Using %q as catalogd namespace" , namespace )
62+ return namespace
63+ }
16064
161- t .Log ("Creating ClusterRoleBinding for metrics access" )
162- cmd = exec .Command (client , "create" , "clusterrolebinding" , "catalogd-metrics-binding" ,
163- "--clusterrole=catalogd-metrics-reader" ,
164- "--serviceaccount=" + namespace + ":catalogd-controller-manager" )
165- output , err = cmd .CombinedOutput ()
65+ func createClusterRoleBinding (t * testing.T , client , name , clusterRole , namespace , serviceAccount string ) {
66+ t .Logf ("Creating ClusterRoleBinding %s" , name )
67+ cmd := exec .Command (client , "create" , "clusterrolebinding" , name ,
68+ "--clusterrole=" + clusterRole ,
69+ "--serviceaccount=" + namespace + ":" + serviceAccount )
70+ output , err := cmd .CombinedOutput ()
16671 require .NoError (t , err , "Error creating ClusterRoleBinding: %s" , string (output ))
16772
16873 defer func () {
169- t .Log ("Cleaning up ClusterRoleBinding" )
170- _ = exec .Command (client , "delete" , "clusterrolebinding" , "catalogd-metrics-binding" , "--ignore-not-found=true" ).Run ()
74+ t .Logf ("Cleaning up ClusterRoleBinding %s" , name )
75+ _ = exec .Command (client , "delete" , "clusterrolebinding" , name , "--ignore-not-found=true" ).Run ()
17176 }()
77+ }
17278
173- t .Log ("Creating service account token for authentication" )
174- tokenCmd := exec .Command (client , "create" , "token" , "catalogd-controller-manager" , "-n" , namespace )
175- tokenOutput , tokenCombinedOutput , err := stdoutAndCombined (tokenCmd )
79+ func createServiceAccountToken (t * testing.T , client , namespace , serviceAccount string ) string {
80+ t .Log ("Generating ServiceAccount token" )
81+ cmd := exec .Command (client , "create" , "token" , serviceAccount , "-n" , namespace )
82+ tokenOutput , tokenCombinedOutput , err := stdoutAndCombined (cmd )
17683 require .NoError (t , err , "Error creating token: %s" , string (tokenCombinedOutput ))
177- token = string (bytes .TrimSpace (tokenOutput ))
84+ return string (bytes .TrimSpace (tokenOutput ))
85+ }
17886
179- t .Log ("Creating a pod to run curl commands" )
180- cmd = exec .Command (client , "run" , curlPod ,
87+ func createCurlPod (t * testing.T , client , namespace , podName , serviceAccount string ) {
88+ t .Log ("Creating curl pod to validate the metrics endpoint" )
89+ cmd := exec .Command (client , "run" , podName ,
18190 "--image=curlimages/curl:7.87.0" , "-n" , namespace ,
18291 "--restart=Never" ,
18392 "--overrides" , `{
@@ -188,47 +97,44 @@ func TestCatalogdMetricsExportedEndpoint(t *testing.T) {
18897 "command": ["sh", "-c", "sleep 3600"],
18998 "securityContext": {
19099 "allowPrivilegeEscalation": false,
191- "capabilities": {
192- "drop": ["ALL"]
193- },
100+ "capabilities": {"drop": ["ALL"]},
194101 "runAsNonRoot": true,
195102 "runAsUser": 1000,
196- "seccompProfile": {
197- "type": "RuntimeDefault"
198- }
103+ "seccompProfile": {"type": "RuntimeDefault"}
199104 }
200105 }],
201- "serviceAccountName": "catalogd-controller-manager "
106+ "serviceAccountName": "` + serviceAccount + ` "
202107 }
203108 }` )
204- output , err = cmd .CombinedOutput ()
109+ output , err : = cmd .CombinedOutput ()
205110 require .NoError (t , err , "Error creating curl pod: %s" , string (output ))
206111
207112 defer func () {
208113 t .Log ("Cleaning up curl pod" )
209- _ = exec .Command (client , "delete" , "pod" , curlPod , "-n" , namespace , "--ignore-not-found=true" ).Run ()
114+ _ = exec .Command (client , "delete" , "pod" , podName , "-n" , namespace , "--ignore-not-found=true" ).Run ()
210115 }()
116+ }
211117
212- t .Log ("Waiting for the curl pod to become ready" )
213- waitCmd := exec .Command (client , "wait" , "--for=condition=Ready" , "pod" , curlPod , "-n" , namespace , "--timeout=60s" )
214- waitOutput , waitErr := waitCmd .CombinedOutput ()
215- require .NoError (t , waitErr , "Error waiting for curl pod to be ready: %s" , string (waitOutput ))
118+ func waitForPodReady (t * testing.T , client , namespace , podName string ) {
119+ t .Log ("Waiting for the curl pod to be ready" )
120+ cmd := exec .Command (client , "wait" , "--for=condition=Ready" , "pod" , podName , "-n" , namespace , "--timeout=60s" )
121+ output , err := cmd .CombinedOutput ()
122+ require .NoError (t , err , "Error waiting for curl pod to be ready: %s" , string (output ))
123+ }
216124
125+ func validateMetricsEndpoint (t * testing.T , client , namespace , podName , token , metricsURL string ) {
217126 t .Log ("Validating the metrics endpoint" )
218- metricsURL := "https://catalogd-service." + namespace + ".svc.cluster.local:7443/metrics"
219- curlCmd := exec .Command (client , "exec" , curlPod , "-n" , namespace , "--" ,
127+ cmd := exec .Command (client , "exec" , podName , "-n" , namespace , "--" ,
220128 "curl" , "-v" , "-k" , "-H" , "Authorization: Bearer " + token , metricsURL )
221- output , err = curlCmd .CombinedOutput ()
129+ output , err := cmd .CombinedOutput ()
222130 require .NoError (t , err , "Error calling metrics endpoint: %s" , string (output ))
223131 require .Contains (t , string (output ), "200 OK" , "Metrics endpoint did not return 200 OK" )
224132}
225133
226134func stdoutAndCombined (cmd * exec.Cmd ) ([]byte , []byte , error ) {
227- var outOnly bytes.Buffer
228- var outAndErr bytes.Buffer
229- allWriter := io .MultiWriter (& outOnly , & outAndErr )
135+ var outOnly , outAndErr bytes.Buffer
136+ cmd .Stdout = io .MultiWriter (& outOnly , & outAndErr )
230137 cmd .Stderr = & outAndErr
231- cmd .Stdout = allWriter
232138 err := cmd .Run ()
233139 return outOnly .Bytes (), outAndErr .Bytes (), err
234140}
0 commit comments