diff --git a/Documentation/resources.adoc b/Documentation/resources.adoc index ca237453a9..ba04aec96a 100644 --- a/Documentation/resources.adoc +++ b/Documentation/resources.adoc @@ -70,7 +70,149 @@ Expose the user-defined Alertmanager web server within the cluster on the follow Expose the Alertmanager web server within the cluster on the following ports: * Port 9094 provides access to all the Alertmanager endpoints. Granting access requires binding a user to the `monitoring-alertmanager-view` role (for read-only operations) or `monitoring-alertmanager-edit` role in the `openshift-monitoring` project. ++ +The following example exercises permissions granted by the `monitoring-alertmanager-view` role. The binding commands must be run by a user with the necessary privileges. ++ +[source,terminal] +---- +# Create a test namespace and a service account. +$ oc create namespace test-alertmanager-web-monitoring-alertmanager-view +$ oc create serviceaccount am-client --namespace=test-alertmanager-web-monitoring-alertmanager-view +# Bind the role to the service account. +# The binding in this example is applied to a service account but can also be applied to any user. +$ oc create rolebinding test-alertmanager-web-monitoring-alertmanager-view \ + --namespace=openshift-monitoring \ + --role=monitoring-alertmanager-view \ + --serviceaccount=test-alertmanager-web-monitoring-alertmanager-view:am-client +# Generate a token to access the endpoints. +$ TOKEN=$(oc create token am-client --namespace=test-alertmanager-web-monitoring-alertmanager-view) +# Access Alertmanager endpoints externally. +$ ROUTE=$(oc get route alertmanager-main --namespace=openshift-monitoring -ojsonpath={.spec.host}) +$ curl -k -H "Authorization: Bearer $TOKEN" "https://$ROUTE/api/v2/alerts?filter=alertname=Watchdog" +# Access Alertmanager endpoints from within the cluster. +$ curl -k -H "Authorization: Bearer $TOKEN" "https://alertmanager-main.openshift-monitoring:9094/api/v2/alerts?filter=alertname=Watchdog" +---- ++ +The following example exercises permissions granted by the `monitoring-alertmanager-edit` role. The binding commands must be run by a user with the necessary privileges. ++ +[source,terminal] +---- +# Create a test namespace and a service account. +$ oc create namespace test-alertmanager-web-monitoring-alertmanager-edit +$ oc create serviceaccount am-client --namespace=test-alertmanager-web-monitoring-alertmanager-edit +# Bind the role to the service account. +# The binding in this example is applied to a service account but can also be applied to any user. +$ oc create rolebinding test-alertmanager-web-monitoring-alertmanager-edit \ + --namespace=openshift-monitoring \ + --role=monitoring-alertmanager-edit \ + --serviceaccount=test-alertmanager-web-monitoring-alertmanager-edit:am-client +# Generate a token to access the endpoints. +$ TOKEN=$(oc create token am-client --namespace=test-alertmanager-web-monitoring-alertmanager-edit) +# Access Alertmanager endpoints externally. +$ ROUTE=$(oc get route alertmanager-main --namespace=openshift-monitoring -ojsonpath={.spec.host}) +$ curl -k -X POST "https://$ROUTE/api/v2/silences" \ + -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \ + -d '{ + "matchers": [ + { + "name": "alertname", + "value": "MyTestAlert1", + "isRegex": false + } + ], + "startsAt": "2044-01-01T00:00:00Z", + "endsAt": "2044-01-01T00:00:01Z", + "createdBy": "test-alertmanager-web-monitoring-alertmanager-edit/am-client", + "comment": "Silence test" + }' +# Access Alertmanager endpoints from within the cluster. +$ curl -k -X POST "https://alertmanager-main.openshift-monitoring:9094/api/v2/silences" \ + -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \ + -d '{ + "matchers": [ + { + "name": "alertname", + "value": "MyTestAlert2", + "isRegex": false + } + ], + "startsAt": "2044-01-01T00:00:00Z", + "endsAt": "2044-01-01T00:00:01Z", + "createdBy": "test-alertmanager-web-monitoring-alertmanager-edit/am-client", + "comment": "Silence test" + }' +---- + * Port 9092 provides access to the Alertmanager endpoints restricted to a given project. Granting access requires binding a user to the `monitoring-rules-edit` cluster role or `monitoring-edit` cluster role in the project. ++ +The following example exercises permissions granted by the `monitoring-rules-edit` cluster role. The binding commands must be run by a user with the necessary privileges. ++ +[source,terminal] +---- +# Create a test namespace and a service account. +$ oc create namespace test-alertmanager-tenancy-monitoring-rules-edit +$ oc create serviceaccount am-client --namespace=test-alertmanager-tenancy-monitoring-rules-edit +# Bind the role to the service account. +# The binding in this example is applied to a service account but can also be applied to any user. +$ oc create rolebinding test-alertmanager-tenancy-monitoring-rules-edit \ + --namespace=test-alertmanager-tenancy-monitoring-rules-edit \ + --clusterrole=monitoring-rules-edit \ + --serviceaccount=test-alertmanager-tenancy-monitoring-rules-edit:am-client +# Generate a token to access the endpoints. +$ TOKEN=$(oc create token am-client --namespace=test-alertmanager-tenancy-monitoring-rules-edit) +# Access Alertmanager endpoints from within the cluster. The port is not exposed externally by default. +$ curl -k -f -H "Authorization: Bearer $TOKEN" "https://alertmanager-main.openshift-monitoring:9092/api/v2/alerts?namespace=test-alertmanager-tenancy-monitoring-rules-edit" +$ curl -k -X POST -f "https://alertmanager-main.openshift-monitoring:9092/api/v2/silences?namespace=test-alertmanager-tenancy-monitoring-rules-edit" \ + -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \ + -d '{ + "matchers": [ + { + "name": "alertname", + "value": "MyTestAlert", + "isRegex": false + } + ], + "startsAt": "2044-01-01T00:00:00Z", + "endsAt": "2044-01-01T00:00:01Z", + "createdBy": "test-alertmanager-tenancy-monitoring-rules-edit/am-client", + "comment": "Silence test" + }' +---- ++ +The following example exercises permissions granted by the `monitoring-edit` cluster role. The binding commands must be run by a user with the necessary privileges. ++ +[source,terminal] +---- +# Create a test namespace and a service account. +$ oc create namespace test-alertmanager-tenancy-monitoring-edit +$ oc create serviceaccount am-client --namespace=test-alertmanager-tenancy-monitoring-edit +# Bind the role to the service account. +# The binding in this example is applied to a service account but can also be applied to any user. +$ oc create rolebinding test-alertmanager-tenancy-monitoring-edit \ + --namespace=test-alertmanager-tenancy-monitoring-edit \ + --clusterrole=monitoring-edit \ + --serviceaccount=test-alertmanager-tenancy-monitoring-edit:am-client +# Generate a token to access the endpoints. +$ TOKEN=$(oc create token am-client --namespace=test-alertmanager-tenancy-monitoring-edit) +# Access Alertmanager endpoints from within the cluster. The port is not exposed externally by default. +$ curl -k -f -H "Authorization: Bearer $TOKEN" "https://alertmanager-main.openshift-monitoring:9092/api/v2/alerts?namespace=test-alertmanager-tenancy-monitoring-edit" +$ curl -k -X POST -f "https://alertmanager-main.openshift-monitoring:9092/api/v2/silences?namespace=test-alertmanager-tenancy-monitoring-edit" \ + -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \ + -d '{ + "matchers": [ + { + "name": "alertname", + "value": "MyTestAlert", + "isRegex": false + } + ], + "startsAt": "2044-01-01T00:00:00Z", + "endsAt": "2044-01-01T00:00:01Z", + "createdBy": "test-alertmanager-tenancy-monitoring-edit/am-client", + "comment": "Silence test" + }' +---- + * Port 9097 provides access to the `/metrics` endpoint only. This port is for internal use, and no other usage is guaranteed. === openshift-monitoring/kube-state-metrics @@ -103,7 +245,52 @@ Expose openshift-state-metrics `/metrics` endpoints within the cluster on the fo Expose the Prometheus web server within the cluster on the following ports: -* Port 9091 provides access to all the Prometheus endpoints. Granting access requires binding a user to the `cluster-monitoring-view` cluster role. +* Port 9091 provides access to all the Prometheus endpoints. Granting access requires binding a user to the `cluster-monitoring-view` cluster role or `cluster-monitoring-metrics-api` cluster role in the `openshift-monitoring` project. ++ +The following example exercises permissions granted by the `cluster-monitoring-view` cluster role. The binding commands must be run by a user with the necessary privileges. ++ +[source,terminal] +---- +# Create a test namespace and a service account. +$ oc create namespace test-prometheus-web-cluster-monitoring-view +$ oc create serviceaccount prom-client --namespace=test-prometheus-web-cluster-monitoring-view +# Bind the role to the service account. +# The binding in this example is applied to a service account but can also be applied to any user. +$ oc create rolebinding test-prometheus-web-cluster-monitoring-view \ + --namespace=openshift-monitoring \ + --clusterrole=cluster-monitoring-view \ + --serviceaccount=test-prometheus-web-cluster-monitoring-view:prom-client +# Generate a token to access the endpoints. +$ TOKEN=$(oc create token prom-client --namespace=test-prometheus-web-cluster-monitoring-view) +# Access Prometheus endpoints externally. +$ ROUTE=$(oc get route prometheus-k8s --namespace=openshift-monitoring -ojsonpath={.spec.host}) +$ curl -k -H "Authorization: Bearer $TOKEN" "https://$ROUTE/api/v1/query?query=up" +# Access Prometheus endpoints from within the cluster. +$ curl -k -H "Authorization: Bearer $TOKEN" "https://prometheus-k8s.openshift-monitoring:9091/api/v1/query?query=up" +---- ++ +The following example exercises permissions granted by the `cluster-monitoring-metrics-api` role. The binding commands must be run by a user with the necessary privileges. ++ +[source,terminal] +---- +# Create a test namespace and a service account. +$ oc create namespace test-prometheus-web-cluster-monitoring-metrics-api +$ oc create serviceaccount prom-client --namespace=test-prometheus-web-cluster-monitoring-metrics-api +# Bind the role to the service account. +# The binding in this example is applied to a service account but can also be applied to any user. +$ oc create rolebinding test-prometheus-web-cluster-monitoring-metrics-api \ + --namespace=openshift-monitoring \ + --role=cluster-monitoring-metrics-api \ + --serviceaccount=test-prometheus-web-cluster-monitoring-metrics-api:prom-client +# Generate a token to access the endpoints. +$ TOKEN=$(oc create token prom-client --namespace=test-prometheus-web-cluster-monitoring-metrics-api) +# Access Prometheus endpoints externally. +$ ROUTE=$(oc get route prometheus-k8s --namespace=openshift-monitoring -ojsonpath={.spec.host}) +$ curl -k -H "Authorization: Bearer $TOKEN" "https://$ROUTE/api/v1/query?query=up" +# Access Prometheus endpoints from within the cluster. +$ curl -k -H "Authorization: Bearer $TOKEN" "https://prometheus-k8s.openshift-monitoring:9091/api/v1/query?query=up" +---- + * Port 9092 provides access to the `/metrics` and `/federate` endpoints only. This port is for internal use, and no other usage is guaranteed. === openshift-user-workload-monitoring/prometheus-operator @@ -131,9 +318,135 @@ Expose the `/metrics` endpoint on port 8443. This port is for internal use, and Expose the Thanos Querier web server within the cluster on the following ports: -* Port 9091 provides access to all the Thanos Querier endpoints. Granting access requires binding a user to the `cluster-monitoring-view` cluster role. +* Port 9091 provides access to all the Thanos Querier endpoints. Granting access requires binding a user to the `cluster-monitoring-view` cluster role or `cluster-monitoring-metrics-api` cluster role in the `openshift-monitoring` project. ++ +The following example exercises permissions granted by the `cluster-monitoring-view` cluster role. The binding commands must be run by a user with the necessary privileges. ++ +[source,terminal] +---- +# Create a test namespace and a service account. +$ oc create namespace test-thanos-querier-web-cluster-monitoring-view +$ oc create serviceaccount thanos-client --namespace=test-thanos-querier-web-cluster-monitoring-view +# Bind the role to the service account. +# The binding in this example is applied to a service account but can also be applied to any user. +$ oc create rolebinding test-thanos-querier-web-cluster-monitoring-view \ + --namespace=openshift-monitoring \ + --clusterrole=cluster-monitoring-view \ + --serviceaccount=test-thanos-querier-web-cluster-monitoring-view:thanos-client +# Generate a token to access the endpoints. +$ TOKEN=$(oc create token thanos-client --namespace=test-thanos-querier-web-cluster-monitoring-view) +# Access Thanos Querier endpoints externally. +$ ROUTE=$(oc get route thanos-querier --namespace=openshift-monitoring -ojsonpath={.spec.host}) +$ curl -k -H "Authorization: Bearer $TOKEN" "https://$ROUTE/api/v1/query?query=up" +# Access Thanos Querier endpoints from within the cluster. +$ curl -k -H "Authorization: Bearer $TOKEN" "https://thanos-querier.openshift-monitoring:9091/api/v1/query?query=up" +---- ++ +The following example exercises permissions granted by the `cluster-monitoring-metrics-api` role. The binding commands must be run by a user with the necessary privileges. ++ +[source,terminal] +---- +# Create a test namespace and a service account. +$ oc create namespace test-thanos-querier-web-cluster-monitoring-metrics-api +$ oc create serviceaccount thanos-client --namespace=test-thanos-querier-web-cluster-monitoring-metrics-api +# Bind the role to the service account. +# The binding in this example is applied to a service account but can also be applied to any user. +$ oc create rolebinding test-thanos-querier-web-cluster-monitoring-metrics-api \ + --namespace=openshift-monitoring \ + --role=cluster-monitoring-metrics-api \ + --serviceaccount=test-thanos-querier-web-cluster-monitoring-metrics-api:thanos-client +# Generate a token to access the endpoints. +$ TOKEN=$(oc create token thanos-client --namespace=test-thanos-querier-web-cluster-monitoring-metrics-api) +# Access Thanos Querier endpoints externally. +$ ROUTE=$(oc get route thanos-querier --namespace=openshift-monitoring -ojsonpath={.spec.host}) +$ curl -k -H "Authorization: Bearer $TOKEN" "https://$ROUTE/api/v1/query?query=up" +# Access Thanos Querier endpoints from within the cluster. +$ curl -k -H "Authorization: Bearer $TOKEN" "https://thanos-querier.openshift-monitoring:9091/api/v1/query?query=up" +---- + * Port 9092 provides access to the `/api/v1/query`, `/api/v1/query_range/`, `/api/v1/labels`, `/api/v1/label/*/values`, and `/api/v1/series` endpoints restricted to a given project. Granting access requires binding a user to the `view` cluster role in the project. ++ +The following example exercises permissions granted by the `view` cluster role. The binding commands must be run by a user with the necessary privileges. ++ +[source,terminal] +---- +# Create a test namespace and a service account. +$ oc create namespace test-thanos-querier-tenancy-view +$ oc create serviceaccount thanos-client --namespace=test-thanos-querier-tenancy-view +# Bind the role to the service account. +# The binding in this example is applied to a service account but can also be applied to any user. +$ oc create rolebinding test-thanos-querier-tenancy-view \ + --namespace=test-thanos-querier-tenancy-view \ + --clusterrole=view \ + --serviceaccount=test-thanos-querier-tenancy-view:thanos-client +# Generate a token to access the endpoints. +$ TOKEN=$(oc create token thanos-client --namespace=test-thanos-querier-tenancy-view) +# Access Thanos Querier endpoints from within the cluster. The port is not exposed externally by default. +$ curl -k -f -H "Authorization: Bearer $TOKEN" "https://thanos-querier.openshift-monitoring:9092/api/v1/query?query=up&namespace=test-thanos-querier-tenancy-view" +---- + * Port 9093 provides access to the `/api/v1/alerts`, and `/api/v1/rules` endpoints restricted to a given project. Granting access requires binding a user to the `monitoring-rules-edit` cluster role or `monitoring-edit` cluster role or `monitoring-rules-view` cluster role in the project. ++ +The following example exercises permissions granted by the `monitoring-rules-edit` cluster role. The binding commands must be run by a user with the necessary privileges. ++ +[source,terminal] +---- +# Create a test namespace and a service account. +$ oc create namespace test-thanos-querier-tenancy-rules-monitoring-rules-edit +$ oc create serviceaccount thanos-client --namespace=test-thanos-querier-tenancy-rules-monitoring-rules-edit +# Bind the role to the service account. +# The binding in this example is applied to a service account but can also be applied to any user. +$ oc create rolebinding test-thanos-querier-tenancy-rules-monitoring-rules-edit \ + --namespace=test-thanos-querier-tenancy-rules-monitoring-rules-edit \ + --clusterrole=monitoring-rules-edit \ + --serviceaccount=test-thanos-querier-tenancy-rules-monitoring-rules-edit:thanos-client +# Generate a token to access the endpoints. +$ TOKEN=$(oc create token thanos-client --namespace=test-thanos-querier-tenancy-rules-monitoring-rules-edit) +# Access Thanos Querier endpoints from within the cluster. The port is not exposed externally by default. +$ curl -k -f -H "Authorization: Bearer $TOKEN" "https://thanos-querier.openshift-monitoring:9093/api/v1/rules?namespace=test-thanos-querier-tenancy-rules-monitoring-rules-edit" +$ curl -k -f -H "Authorization: Bearer $TOKEN" "https://thanos-querier.openshift-monitoring:9093/api/v1/alerts?namespace=test-thanos-querier-tenancy-rules-monitoring-rules-edit" +---- ++ +The following example exercises permissions granted by the `monitoring-edit` cluster role. The binding commands must be run by a user with the necessary privileges. ++ +[source,terminal] +---- +# Create a test namespace and a service account. +$ oc create namespace test-thanos-querier-tenancy-rules-monitoring-edit +$ oc create serviceaccount thanos-client --namespace=test-thanos-querier-tenancy-rules-monitoring-edit +# Bind the role to the service account. +# The binding in this example is applied to a service account but can also be applied to any user. +$ oc create rolebinding test-thanos-querier-tenancy-rules-monitoring-edit \ + --namespace=test-thanos-querier-tenancy-rules-monitoring-edit \ + --clusterrole=monitoring-edit \ + --serviceaccount=test-thanos-querier-tenancy-rules-monitoring-edit:thanos-client +# Generate a token to access the endpoints. +$ TOKEN=$(oc create token thanos-client --namespace=test-thanos-querier-tenancy-rules-monitoring-edit) +# Access Thanos Querier endpoints from within the cluster. The port is not exposed externally by default. +$ curl -k -f -H "Authorization: Bearer $TOKEN" "https://thanos-querier.openshift-monitoring:9093/api/v1/rules?namespace=test-thanos-querier-tenancy-rules-monitoring-edit" +$ curl -k -f -H "Authorization: Bearer $TOKEN" "https://thanos-querier.openshift-monitoring:9093/api/v1/alerts?namespace=test-thanos-querier-tenancy-rules-monitoring-edit" +---- ++ +The following example exercises permissions granted by the `monitoring-rules-view` cluster role. The binding commands must be run by a user with the necessary privileges. ++ +[source,terminal] +---- +# Create a test namespace and a service account. +$ oc create namespace test-thanos-querier-tenancy-rules-monitoring-rules-view +$ oc create serviceaccount thanos-client --namespace=test-thanos-querier-tenancy-rules-monitoring-rules-view +# Bind the role to the service account. +# The binding in this example is applied to a service account but can also be applied to any user. +$ oc create rolebinding test-thanos-querier-tenancy-rules-monitoring-rules-view \ + --namespace=test-thanos-querier-tenancy-rules-monitoring-rules-view \ + --clusterrole=monitoring-rules-view \ + --serviceaccount=test-thanos-querier-tenancy-rules-monitoring-rules-view:thanos-client +# Generate a token to access the endpoints. +$ TOKEN=$(oc create token thanos-client --namespace=test-thanos-querier-tenancy-rules-monitoring-rules-view) +# Access Thanos Querier endpoints from within the cluster. The port is not exposed externally by default. +$ curl -k -f -H "Authorization: Bearer $TOKEN" "https://thanos-querier.openshift-monitoring:9093/api/v1/rules?namespace=test-thanos-querier-tenancy-rules-monitoring-rules-view" +$ curl -k -f -H "Authorization: Bearer $TOKEN" "https://thanos-querier.openshift-monitoring:9093/api/v1/alerts?namespace=test-thanos-querier-tenancy-rules-monitoring-rules-view" +---- + * Port 9094 provides access to the `/metrics` endpoint only. This port is for internal use, and no other usage is guaranteed. === openshift-user-workload-monitoring/thanos-ruler diff --git a/Documentation/resources.md b/Documentation/resources.md index 68c25fd1dc..1ffc2bce91 100644 --- a/Documentation/resources.md +++ b/Documentation/resources.md @@ -56,43 +56,140 @@ Expose the user-defined Alertmanager web server within the cluster on the follow Expose the Alertmanager web server within the cluster on the following ports: * Port 9094 provides access to all the Alertmanager endpoints. Granting access requires binding a user to the `monitoring-alertmanager-view` role (for read-only operations) or `monitoring-alertmanager-edit` role in the `openshift-monitoring` project. ``` -# monitoring-alertmanager-view grants read permissions. -$ oc project openshift-monitoring -$ oc create serviceaccount am-ro-client -$ oc adm policy add-role-to-user monitoring-alertmanager-view \ - --role-namespace=openshift-monitoring --rolebinding-name=am-ro-client \ - --serviceaccount=am-ro-client -$ TOKEN=$(oc create token am-ro-client) -$ ROUTE=$(oc get route alertmanager-main -n openshift-monitoring -ojsonpath={.spec.host}) -$ curl -H "Authorization: Bearer $TOKEN" -k --fail-with-body "https://$ROUTE/api/v2/alerts?filter=alertname=Watchdog" -``` -``` -# monitoring-alertmanager-edit grants edit permissions. -$ oc project openshift-monitoring -$ oc create serviceaccount am-rw-client -$ oc adm policy add-role-to-user monitoring-alertmanager-edit \ - --role-namespace=openshift-monitoring --rolebinding-name=am-rw-client \ - --serviceaccount=am-rw-client -$ TOKEN=$(oc create token am-rw-client) -$ ROUTE=$(oc get route alertmanager-main -n openshift-monitoring -ojsonpath={.spec.host}) -$ curl -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \ +# The following example exercises permissions granted by the `monitoring-alertmanager-view` role. The binding commands must be run by a user with the necessary privileges. + +# Create a test namespace and a service account. +$ oc create namespace test-alertmanager-web-monitoring-alertmanager-view +$ oc create serviceaccount am-client --namespace=test-alertmanager-web-monitoring-alertmanager-view +# Bind the role to the service account. +# The binding in this example is applied to a service account but can also be applied to any user. +$ oc create rolebinding test-alertmanager-web-monitoring-alertmanager-view \ + --namespace=openshift-monitoring \ + --role=monitoring-alertmanager-view \ + --serviceaccount=test-alertmanager-web-monitoring-alertmanager-view:am-client +# Generate a token to access the endpoints. +$ TOKEN=$(oc create token am-client --namespace=test-alertmanager-web-monitoring-alertmanager-view) +# Access Alertmanager endpoints externally. +$ ROUTE=$(oc get route alertmanager-main --namespace=openshift-monitoring -ojsonpath={.spec.host}) +$ curl -k -H "Authorization: Bearer $TOKEN" "https://$ROUTE/api/v2/alerts?filter=alertname=Watchdog" +# Access Alertmanager endpoints from within the cluster. +$ curl -k -H "Authorization: Bearer $TOKEN" "https://alertmanager-main.openshift-monitoring:9094/api/v2/alerts?filter=alertname=Watchdog" +``` +``` +# The following example exercises permissions granted by the `monitoring-alertmanager-edit` role. The binding commands must be run by a user with the necessary privileges. + +# Create a test namespace and a service account. +$ oc create namespace test-alertmanager-web-monitoring-alertmanager-edit +$ oc create serviceaccount am-client --namespace=test-alertmanager-web-monitoring-alertmanager-edit +# Bind the role to the service account. +# The binding in this example is applied to a service account but can also be applied to any user. +$ oc create rolebinding test-alertmanager-web-monitoring-alertmanager-edit \ + --namespace=openshift-monitoring \ + --role=monitoring-alertmanager-edit \ + --serviceaccount=test-alertmanager-web-monitoring-alertmanager-edit:am-client +# Generate a token to access the endpoints. +$ TOKEN=$(oc create token am-client --namespace=test-alertmanager-web-monitoring-alertmanager-edit) +# Access Alertmanager endpoints externally. +$ ROUTE=$(oc get route alertmanager-main --namespace=openshift-monitoring -ojsonpath={.spec.host}) +$ curl -k -X POST "https://$ROUTE/api/v2/silences" \ + -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \ -d '{ "matchers": [ { "name": "alertname", - "value": "MyTestAlert", + "value": "MyTestAlert1", "isRegex": false } ], "startsAt": "2044-01-01T00:00:00Z", "endsAt": "2044-01-01T00:00:01Z", - "createdBy": "am-rw-client", + "createdBy": "test-alertmanager-web-monitoring-alertmanager-edit/am-client", "comment": "Silence test" - }' \ - -k --fail-with-body "https://$ROUTE/api/v2/silences" + }' +# Access Alertmanager endpoints from within the cluster. +$ curl -k -X POST "https://alertmanager-main.openshift-monitoring:9094/api/v2/silences" \ + -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \ + -d '{ + "matchers": [ + { + "name": "alertname", + "value": "MyTestAlert2", + "isRegex": false + } + ], + "startsAt": "2044-01-01T00:00:00Z", + "endsAt": "2044-01-01T00:00:01Z", + "createdBy": "test-alertmanager-web-monitoring-alertmanager-edit/am-client", + "comment": "Silence test" + }' ``` * Port 9092 provides access to the Alertmanager endpoints restricted to a given project. Granting access requires binding a user to the `monitoring-rules-edit` cluster role or `monitoring-edit` cluster role in the project. +``` +# The following example exercises permissions granted by the `monitoring-rules-edit` cluster role. The binding commands must be run by a user with the necessary privileges. + +# Create a test namespace and a service account. +$ oc create namespace test-alertmanager-tenancy-monitoring-rules-edit +$ oc create serviceaccount am-client --namespace=test-alertmanager-tenancy-monitoring-rules-edit +# Bind the role to the service account. +# The binding in this example is applied to a service account but can also be applied to any user. +$ oc create rolebinding test-alertmanager-tenancy-monitoring-rules-edit \ + --namespace=test-alertmanager-tenancy-monitoring-rules-edit \ + --clusterrole=monitoring-rules-edit \ + --serviceaccount=test-alertmanager-tenancy-monitoring-rules-edit:am-client +# Generate a token to access the endpoints. +$ TOKEN=$(oc create token am-client --namespace=test-alertmanager-tenancy-monitoring-rules-edit) +# Access Alertmanager endpoints from within the cluster. The port is not exposed externally by default. +$ curl -k -f -H "Authorization: Bearer $TOKEN" "https://alertmanager-main.openshift-monitoring:9092/api/v2/alerts?namespace=test-alertmanager-tenancy-monitoring-rules-edit" +$ curl -k -X POST -f "https://alertmanager-main.openshift-monitoring:9092/api/v2/silences?namespace=test-alertmanager-tenancy-monitoring-rules-edit" \ + -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \ + -d '{ + "matchers": [ + { + "name": "alertname", + "value": "MyTestAlert", + "isRegex": false + } + ], + "startsAt": "2044-01-01T00:00:00Z", + "endsAt": "2044-01-01T00:00:01Z", + "createdBy": "test-alertmanager-tenancy-monitoring-rules-edit/am-client", + "comment": "Silence test" + }' +``` +``` +# The following example exercises permissions granted by the `monitoring-edit` cluster role. The binding commands must be run by a user with the necessary privileges. + +# Create a test namespace and a service account. +$ oc create namespace test-alertmanager-tenancy-monitoring-edit +$ oc create serviceaccount am-client --namespace=test-alertmanager-tenancy-monitoring-edit +# Bind the role to the service account. +# The binding in this example is applied to a service account but can also be applied to any user. +$ oc create rolebinding test-alertmanager-tenancy-monitoring-edit \ + --namespace=test-alertmanager-tenancy-monitoring-edit \ + --clusterrole=monitoring-edit \ + --serviceaccount=test-alertmanager-tenancy-monitoring-edit:am-client +# Generate a token to access the endpoints. +$ TOKEN=$(oc create token am-client --namespace=test-alertmanager-tenancy-monitoring-edit) +# Access Alertmanager endpoints from within the cluster. The port is not exposed externally by default. +$ curl -k -f -H "Authorization: Bearer $TOKEN" "https://alertmanager-main.openshift-monitoring:9092/api/v2/alerts?namespace=test-alertmanager-tenancy-monitoring-edit" +$ curl -k -X POST -f "https://alertmanager-main.openshift-monitoring:9092/api/v2/silences?namespace=test-alertmanager-tenancy-monitoring-edit" \ + -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \ + -d '{ + "matchers": [ + { + "name": "alertname", + "value": "MyTestAlert", + "isRegex": false + } + ], + "startsAt": "2044-01-01T00:00:00Z", + "endsAt": "2044-01-01T00:00:01Z", + "createdBy": "test-alertmanager-tenancy-monitoring-edit/am-client", + "comment": "Silence test" + }' +``` + * Port 9097 provides access to the `/metrics` endpoint only. This port is for internal use, and no other usage is guaranteed. ### openshift-monitoring/kube-state-metrics @@ -122,7 +219,48 @@ Expose openshift-state-metrics `/metrics` endpoints within the cluster on the fo ### openshift-monitoring/prometheus-k8s Expose the Prometheus web server within the cluster on the following ports: -* Port 9091 provides access to all the Prometheus endpoints. Granting access requires binding a user to the `cluster-monitoring-view` cluster role. +* Port 9091 provides access to all the Prometheus endpoints. Granting access requires binding a user to the `cluster-monitoring-view` cluster role or `cluster-monitoring-metrics-api` cluster role in the `openshift-monitoring` project. +``` +# The following example exercises permissions granted by the `cluster-monitoring-view` cluster role. The binding commands must be run by a user with the necessary privileges. + +# Create a test namespace and a service account. +$ oc create namespace test-prometheus-web-cluster-monitoring-view +$ oc create serviceaccount prom-client --namespace=test-prometheus-web-cluster-monitoring-view +# Bind the role to the service account. +# The binding in this example is applied to a service account but can also be applied to any user. +$ oc create rolebinding test-prometheus-web-cluster-monitoring-view \ + --namespace=openshift-monitoring \ + --clusterrole=cluster-monitoring-view \ + --serviceaccount=test-prometheus-web-cluster-monitoring-view:prom-client +# Generate a token to access the endpoints. +$ TOKEN=$(oc create token prom-client --namespace=test-prometheus-web-cluster-monitoring-view) +# Access Prometheus endpoints externally. +$ ROUTE=$(oc get route prometheus-k8s --namespace=openshift-monitoring -ojsonpath={.spec.host}) +$ curl -k -H "Authorization: Bearer $TOKEN" "https://$ROUTE/api/v1/query?query=up" +# Access Prometheus endpoints from within the cluster. +$ curl -k -H "Authorization: Bearer $TOKEN" "https://prometheus-k8s.openshift-monitoring:9091/api/v1/query?query=up" +``` +``` +# The following example exercises permissions granted by the `cluster-monitoring-metrics-api` role. The binding commands must be run by a user with the necessary privileges. + +# Create a test namespace and a service account. +$ oc create namespace test-prometheus-web-cluster-monitoring-metrics-api +$ oc create serviceaccount prom-client --namespace=test-prometheus-web-cluster-monitoring-metrics-api +# Bind the role to the service account. +# The binding in this example is applied to a service account but can also be applied to any user. +$ oc create rolebinding test-prometheus-web-cluster-monitoring-metrics-api \ + --namespace=openshift-monitoring \ + --role=cluster-monitoring-metrics-api \ + --serviceaccount=test-prometheus-web-cluster-monitoring-metrics-api:prom-client +# Generate a token to access the endpoints. +$ TOKEN=$(oc create token prom-client --namespace=test-prometheus-web-cluster-monitoring-metrics-api) +# Access Prometheus endpoints externally. +$ ROUTE=$(oc get route prometheus-k8s --namespace=openshift-monitoring -ojsonpath={.spec.host}) +$ curl -k -H "Authorization: Bearer $TOKEN" "https://$ROUTE/api/v1/query?query=up" +# Access Prometheus endpoints from within the cluster. +$ curl -k -H "Authorization: Bearer $TOKEN" "https://prometheus-k8s.openshift-monitoring:9091/api/v1/query?query=up" +``` + * Port 9092 provides access to the `/metrics` and `/federate` endpoints only. This port is for internal use, and no other usage is guaranteed. ### openshift-user-workload-monitoring/prometheus-operator @@ -148,9 +286,123 @@ Expose the `/metrics` endpoint on port 8443. This port is for internal use, and ### openshift-monitoring/thanos-querier Expose the Thanos Querier web server within the cluster on the following ports: -* Port 9091 provides access to all the Thanos Querier endpoints. Granting access requires binding a user to the `cluster-monitoring-view` cluster role. +* Port 9091 provides access to all the Thanos Querier endpoints. Granting access requires binding a user to the `cluster-monitoring-view` cluster role or `cluster-monitoring-metrics-api` cluster role in the `openshift-monitoring` project. +``` +# The following example exercises permissions granted by the `cluster-monitoring-view` cluster role. The binding commands must be run by a user with the necessary privileges. + +# Create a test namespace and a service account. +$ oc create namespace test-thanos-querier-web-cluster-monitoring-view +$ oc create serviceaccount thanos-client --namespace=test-thanos-querier-web-cluster-monitoring-view +# Bind the role to the service account. +# The binding in this example is applied to a service account but can also be applied to any user. +$ oc create rolebinding test-thanos-querier-web-cluster-monitoring-view \ + --namespace=openshift-monitoring \ + --clusterrole=cluster-monitoring-view \ + --serviceaccount=test-thanos-querier-web-cluster-monitoring-view:thanos-client +# Generate a token to access the endpoints. +$ TOKEN=$(oc create token thanos-client --namespace=test-thanos-querier-web-cluster-monitoring-view) +# Access Thanos Querier endpoints externally. +$ ROUTE=$(oc get route thanos-querier --namespace=openshift-monitoring -ojsonpath={.spec.host}) +$ curl -k -H "Authorization: Bearer $TOKEN" "https://$ROUTE/api/v1/query?query=up" +# Access Thanos Querier endpoints from within the cluster. +$ curl -k -H "Authorization: Bearer $TOKEN" "https://thanos-querier.openshift-monitoring:9091/api/v1/query?query=up" +``` +``` +# The following example exercises permissions granted by the `cluster-monitoring-metrics-api` role. The binding commands must be run by a user with the necessary privileges. + +# Create a test namespace and a service account. +$ oc create namespace test-thanos-querier-web-cluster-monitoring-metrics-api +$ oc create serviceaccount thanos-client --namespace=test-thanos-querier-web-cluster-monitoring-metrics-api +# Bind the role to the service account. +# The binding in this example is applied to a service account but can also be applied to any user. +$ oc create rolebinding test-thanos-querier-web-cluster-monitoring-metrics-api \ + --namespace=openshift-monitoring \ + --role=cluster-monitoring-metrics-api \ + --serviceaccount=test-thanos-querier-web-cluster-monitoring-metrics-api:thanos-client +# Generate a token to access the endpoints. +$ TOKEN=$(oc create token thanos-client --namespace=test-thanos-querier-web-cluster-monitoring-metrics-api) +# Access Thanos Querier endpoints externally. +$ ROUTE=$(oc get route thanos-querier --namespace=openshift-monitoring -ojsonpath={.spec.host}) +$ curl -k -H "Authorization: Bearer $TOKEN" "https://$ROUTE/api/v1/query?query=up" +# Access Thanos Querier endpoints from within the cluster. +$ curl -k -H "Authorization: Bearer $TOKEN" "https://thanos-querier.openshift-monitoring:9091/api/v1/query?query=up" +``` + * Port 9092 provides access to the `/api/v1/query`, `/api/v1/query_range/`, `/api/v1/labels`, `/api/v1/label/*/values`, and `/api/v1/series` endpoints restricted to a given project. Granting access requires binding a user to the `view` cluster role in the project. +``` +# The following example exercises permissions granted by the `view` cluster role. The binding commands must be run by a user with the necessary privileges. + +# Create a test namespace and a service account. +$ oc create namespace test-thanos-querier-tenancy-view +$ oc create serviceaccount thanos-client --namespace=test-thanos-querier-tenancy-view +# Bind the role to the service account. +# The binding in this example is applied to a service account but can also be applied to any user. +$ oc create rolebinding test-thanos-querier-tenancy-view \ + --namespace=test-thanos-querier-tenancy-view \ + --clusterrole=view \ + --serviceaccount=test-thanos-querier-tenancy-view:thanos-client +# Generate a token to access the endpoints. +$ TOKEN=$(oc create token thanos-client --namespace=test-thanos-querier-tenancy-view) +# Access Thanos Querier endpoints from within the cluster. The port is not exposed externally by default. +$ curl -k -f -H "Authorization: Bearer $TOKEN" "https://thanos-querier.openshift-monitoring:9092/api/v1/query?query=up&namespace=test-thanos-querier-tenancy-view" +``` + * Port 9093 provides access to the `/api/v1/alerts`, and `/api/v1/rules` endpoints restricted to a given project. Granting access requires binding a user to the `monitoring-rules-edit` cluster role or `monitoring-edit` cluster role or `monitoring-rules-view` cluster role in the project. +``` +# The following example exercises permissions granted by the `monitoring-rules-edit` cluster role. The binding commands must be run by a user with the necessary privileges. + +# Create a test namespace and a service account. +$ oc create namespace test-thanos-querier-tenancy-rules-monitoring-rules-edit +$ oc create serviceaccount thanos-client --namespace=test-thanos-querier-tenancy-rules-monitoring-rules-edit +# Bind the role to the service account. +# The binding in this example is applied to a service account but can also be applied to any user. +$ oc create rolebinding test-thanos-querier-tenancy-rules-monitoring-rules-edit \ + --namespace=test-thanos-querier-tenancy-rules-monitoring-rules-edit \ + --clusterrole=monitoring-rules-edit \ + --serviceaccount=test-thanos-querier-tenancy-rules-monitoring-rules-edit:thanos-client +# Generate a token to access the endpoints. +$ TOKEN=$(oc create token thanos-client --namespace=test-thanos-querier-tenancy-rules-monitoring-rules-edit) +# Access Thanos Querier endpoints from within the cluster. The port is not exposed externally by default. +$ curl -k -f -H "Authorization: Bearer $TOKEN" "https://thanos-querier.openshift-monitoring:9093/api/v1/rules?namespace=test-thanos-querier-tenancy-rules-monitoring-rules-edit" +$ curl -k -f -H "Authorization: Bearer $TOKEN" "https://thanos-querier.openshift-monitoring:9093/api/v1/alerts?namespace=test-thanos-querier-tenancy-rules-monitoring-rules-edit" +``` +``` +# The following example exercises permissions granted by the `monitoring-edit` cluster role. The binding commands must be run by a user with the necessary privileges. + +# Create a test namespace and a service account. +$ oc create namespace test-thanos-querier-tenancy-rules-monitoring-edit +$ oc create serviceaccount thanos-client --namespace=test-thanos-querier-tenancy-rules-monitoring-edit +# Bind the role to the service account. +# The binding in this example is applied to a service account but can also be applied to any user. +$ oc create rolebinding test-thanos-querier-tenancy-rules-monitoring-edit \ + --namespace=test-thanos-querier-tenancy-rules-monitoring-edit \ + --clusterrole=monitoring-edit \ + --serviceaccount=test-thanos-querier-tenancy-rules-monitoring-edit:thanos-client +# Generate a token to access the endpoints. +$ TOKEN=$(oc create token thanos-client --namespace=test-thanos-querier-tenancy-rules-monitoring-edit) +# Access Thanos Querier endpoints from within the cluster. The port is not exposed externally by default. +$ curl -k -f -H "Authorization: Bearer $TOKEN" "https://thanos-querier.openshift-monitoring:9093/api/v1/rules?namespace=test-thanos-querier-tenancy-rules-monitoring-edit" +$ curl -k -f -H "Authorization: Bearer $TOKEN" "https://thanos-querier.openshift-monitoring:9093/api/v1/alerts?namespace=test-thanos-querier-tenancy-rules-monitoring-edit" +``` +``` +# The following example exercises permissions granted by the `monitoring-rules-view` cluster role. The binding commands must be run by a user with the necessary privileges. + +# Create a test namespace and a service account. +$ oc create namespace test-thanos-querier-tenancy-rules-monitoring-rules-view +$ oc create serviceaccount thanos-client --namespace=test-thanos-querier-tenancy-rules-monitoring-rules-view +# Bind the role to the service account. +# The binding in this example is applied to a service account but can also be applied to any user. +$ oc create rolebinding test-thanos-querier-tenancy-rules-monitoring-rules-view \ + --namespace=test-thanos-querier-tenancy-rules-monitoring-rules-view \ + --clusterrole=monitoring-rules-view \ + --serviceaccount=test-thanos-querier-tenancy-rules-monitoring-rules-view:thanos-client +# Generate a token to access the endpoints. +$ TOKEN=$(oc create token thanos-client --namespace=test-thanos-querier-tenancy-rules-monitoring-rules-view) +# Access Thanos Querier endpoints from within the cluster. The port is not exposed externally by default. +$ curl -k -f -H "Authorization: Bearer $TOKEN" "https://thanos-querier.openshift-monitoring:9093/api/v1/rules?namespace=test-thanos-querier-tenancy-rules-monitoring-rules-view" +$ curl -k -f -H "Authorization: Bearer $TOKEN" "https://thanos-querier.openshift-monitoring:9093/api/v1/alerts?namespace=test-thanos-querier-tenancy-rules-monitoring-rules-view" +``` + * Port 9094 provides access to the `/metrics` endpoint only. This port is for internal use, and no other usage is guaranteed. ### openshift-user-workload-monitoring/thanos-ruler diff --git a/assets/alertmanager/service.yaml b/assets/alertmanager/service.yaml index 557dbb1dab..9fdfc8c6bb 100644 --- a/assets/alertmanager/service.yaml +++ b/assets/alertmanager/service.yaml @@ -7,6 +7,7 @@ metadata: * Port 9094 provides access to all the Alertmanager endpoints. Granting access requires binding a user to the `monitoring-alertmanager-view` role (for read-only operations) or `monitoring-alertmanager-edit` role in the `openshift-monitoring` project. xx_omitted_before_deploy__test_file_name:openshift-monitoring_alertmanager-main_service_port_9094.yaml * Port 9092 provides access to the Alertmanager endpoints restricted to a given project. Granting access requires binding a user to the `monitoring-rules-edit` cluster role or `monitoring-edit` cluster role in the project. + xx_omitted_before_deploy__test_file_name:openshift-monitoring_alertmanager-main_service_port_9092.yaml * Port 9097 provides access to the `/metrics` endpoint only. This port is for internal use, and no other usage is guaranteed. service.beta.openshift.io/serving-cert-secret-name: alertmanager-main-tls labels: diff --git a/assets/prometheus-k8s/service.yaml b/assets/prometheus-k8s/service.yaml index f0654f1c64..b6b69dcb78 100644 --- a/assets/prometheus-k8s/service.yaml +++ b/assets/prometheus-k8s/service.yaml @@ -4,7 +4,8 @@ metadata: annotations: openshift.io/description: |- Expose the Prometheus web server within the cluster on the following ports: - * Port 9091 provides access to all the Prometheus endpoints. Granting access requires binding a user to the `cluster-monitoring-view` cluster role. + * Port 9091 provides access to all the Prometheus endpoints. Granting access requires binding a user to the `cluster-monitoring-view` cluster role or `cluster-monitoring-metrics-api` cluster role in the `openshift-monitoring` project. + xx_omitted_before_deploy__test_file_name:openshift-monitoring_prometheus-k8s_service_port_9091.yaml * Port 9092 provides access to the `/metrics` and `/federate` endpoints only. This port is for internal use, and no other usage is guaranteed. service.beta.openshift.io/serving-cert-secret-name: prometheus-k8s-tls labels: diff --git a/assets/thanos-querier/service.yaml b/assets/thanos-querier/service.yaml index 1485cd2de4..e6f7f41609 100644 --- a/assets/thanos-querier/service.yaml +++ b/assets/thanos-querier/service.yaml @@ -4,9 +4,12 @@ metadata: annotations: openshift.io/description: |- Expose the Thanos Querier web server within the cluster on the following ports: - * Port 9091 provides access to all the Thanos Querier endpoints. Granting access requires binding a user to the `cluster-monitoring-view` cluster role. + * Port 9091 provides access to all the Thanos Querier endpoints. Granting access requires binding a user to the `cluster-monitoring-view` cluster role or `cluster-monitoring-metrics-api` cluster role in the `openshift-monitoring` project. + xx_omitted_before_deploy__test_file_name:openshift-monitoring_thanos-querier_service_port_9091.yaml * Port 9092 provides access to the `/api/v1/query`, `/api/v1/query_range/`, `/api/v1/labels`, `/api/v1/label/*/values`, and `/api/v1/series` endpoints restricted to a given project. Granting access requires binding a user to the `view` cluster role in the project. + xx_omitted_before_deploy__test_file_name:openshift-monitoring_thanos-querier_service_port_9092.yaml * Port 9093 provides access to the `/api/v1/alerts`, and `/api/v1/rules` endpoints restricted to a given project. Granting access requires binding a user to the `monitoring-rules-edit` cluster role or `monitoring-edit` cluster role or `monitoring-rules-view` cluster role in the project. + xx_omitted_before_deploy__test_file_name:openshift-monitoring_thanos-querier_service_port_9093.yaml * Port 9094 provides access to the `/metrics` endpoint only. This port is for internal use, and no other usage is guaranteed. service.beta.openshift.io/serving-cert-secret-name: thanos-querier-tls labels: diff --git a/go.mod b/go.mod index 248a585fd2..a484a09c31 100644 --- a/go.mod +++ b/go.mod @@ -10,7 +10,6 @@ require ( github.com/go-openapi/strfmt v0.23.0 github.com/google/uuid v1.6.0 github.com/imdario/mergo v0.3.16 - github.com/mattn/go-shellwords v1.0.12 github.com/onsi/ginkgo/v2 v2.22.0 github.com/onsi/gomega v1.36.1 github.com/openshift-eng/openshift-tests-extension v0.0.0-20250702172817-97309544869d diff --git a/go.sum b/go.sum index bab43da43b..83ff4bead8 100644 --- a/go.sum +++ b/go.sum @@ -267,8 +267,6 @@ github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxec github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-shellwords v1.0.12 h1:M2zGm7EW6UQJvDeQxo4T51eKPurbeFbe8WtebGE2xrk= -github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= github.com/miekg/dns v1.1.65 h1:0+tIPHzUW0GCge7IiK3guGP57VAw7hoPDfApjkMD1Fc= github.com/miekg/dns v1.1.65/go.mod h1:Dzw9769uoKVaLuODMDZz9M6ynFU6Em65csPuoi8G0ck= github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible h1:aKW/4cBs+yK6gpqU3K/oIwk9Q/XICqd3zOX/UFuvqmk= diff --git a/hack/docgen/managed_resources.go b/hack/docgen/managed_resources.go index 8c11e8bdf8..adebd1835f 100644 --- a/hack/docgen/managed_resources.go +++ b/hack/docgen/managed_resources.go @@ -248,10 +248,7 @@ func substitutePlaceholdersInDescription(desc, format string) (string, error) { } else { content = suite.StringMarkdown() } - // TODO: remove once unnecessary - if content != "" { - lines = append(lines, content) - } + lines = append(lines, content) } if err := scanner.Err(); err != nil { return "", err diff --git a/jsonnet/components/alertmanager.libsonnet b/jsonnet/components/alertmanager.libsonnet index 896623b9fa..991b1ae5f8 100644 --- a/jsonnet/components/alertmanager.libsonnet +++ b/jsonnet/components/alertmanager.libsonnet @@ -71,6 +71,7 @@ function(params) * Port %d provides access to all the Alertmanager endpoints. %s %s * Port %d provides access to the Alertmanager endpoints restricted to a given project. %s + %s * Port %d provides access to the `/metrics` endpoint only. This port is for internal use, and no other usage is guaranteed. ||| % [ $.service.spec.ports[0].port, @@ -78,6 +79,7 @@ function(params) testFilePlaceholder('openshift-monitoring', 'alertmanager-main', $.service.spec.ports[0].port), $.service.spec.ports[1].port, requiredClusterRoles(['monitoring-rules-edit', 'monitoring-edit'], false, ''), + testFilePlaceholder('openshift-monitoring', 'alertmanager-main', $.service.spec.ports[1].port), $.service.spec.ports[2].port, ], ), diff --git a/jsonnet/components/prometheus.libsonnet b/jsonnet/components/prometheus.libsonnet index 4a81ff4440..5f728acd0a 100644 --- a/jsonnet/components/prometheus.libsonnet +++ b/jsonnet/components/prometheus.libsonnet @@ -5,6 +5,7 @@ local generateSecret = import '../utils/generate-secret.libsonnet'; local prometheus = import 'github.com/prometheus-operator/kube-prometheus/jsonnet/kube-prometheus/components/prometheus.libsonnet'; local withDescription = (import '../utils/add-annotations.libsonnet').withDescription; local requiredClusterRoles = (import '../utils/add-annotations.libsonnet').requiredClusterRoles; +local testFilePlaceholder = (import '../utils/add-annotations.libsonnet').testFilePlaceholder; function(params) local cfg = params; @@ -103,10 +104,12 @@ function(params) ||| Expose the Prometheus web server within the cluster on the following ports: * Port %d provides access to all the Prometheus endpoints. %s + %s * Port %d provides access to the `/metrics` and `/federate` endpoints only. This port is for internal use, and no other usage is guaranteed. ||| % [ $.service.spec.ports[0].port, - requiredClusterRoles(['cluster-monitoring-view'], true), + requiredClusterRoles(['cluster-monitoring-view', 'cluster-monitoring-metrics-api'], false, 'openshift-monitoring'), + testFilePlaceholder('openshift-monitoring', 'prometheus-k8s', $.service.spec.ports[0].port), $.service.spec.ports[1].port, ], ), diff --git a/jsonnet/components/thanos-querier.libsonnet b/jsonnet/components/thanos-querier.libsonnet index 0f86af86f3..15e1020772 100644 --- a/jsonnet/components/thanos-querier.libsonnet +++ b/jsonnet/components/thanos-querier.libsonnet @@ -1,6 +1,7 @@ local generateSecret = import '../utils/generate-secret.libsonnet'; local querier = import 'github.com/thanos-io/kube-thanos/jsonnet/kube-thanos/kube-thanos-query.libsonnet'; local withDescription = (import '../utils/add-annotations.libsonnet').withDescription; +local testFilePlaceholder = (import '../utils/add-annotations.libsonnet').testFilePlaceholder; local requiredRoles = (import '../utils/add-annotations.libsonnet').requiredRoles; local requiredClusterRoles = (import '../utils/add-annotations.libsonnet').requiredClusterRoles; @@ -199,16 +200,22 @@ function(params) ||| Expose the Thanos Querier web server within the cluster on the following ports: * Port %d provides access to all the Thanos Querier endpoints. %s + %s * Port %d provides access to the `/api/v1/query`, `/api/v1/query_range/`, `/api/v1/labels`, `/api/v1/label/*/values`, and `/api/v1/series` endpoints restricted to a given project. %s + %s * Port %d provides access to the `/api/v1/alerts`, and `/api/v1/rules` endpoints restricted to a given project. %s + %s * Port %d provides access to the `/metrics` endpoint only. This port is for internal use, and no other usage is guaranteed. ||| % [ $.service.spec.ports[0].port, - requiredClusterRoles(['cluster-monitoring-view'], true), + requiredClusterRoles(['cluster-monitoring-view', 'cluster-monitoring-metrics-api'], false, 'openshift-monitoring'), + testFilePlaceholder('openshift-monitoring', 'thanos-querier', $.service.spec.ports[0].port), $.service.spec.ports[1].port, requiredClusterRoles(['view'], false, ''), + testFilePlaceholder('openshift-monitoring', 'thanos-querier', $.service.spec.ports[1].port), $.service.spec.ports[2].port, requiredClusterRoles(['monitoring-rules-edit', 'monitoring-edit', 'monitoring-rules-view'], false, ''), + testFilePlaceholder('openshift-monitoring', 'thanos-querier', $.service.spec.ports[2].port), $.service.spec.ports[3].port, ], ), diff --git a/jsonnet/utils/add-annotations.libsonnet b/jsonnet/utils/add-annotations.libsonnet index 799a511db7..88c2320e2c 100644 --- a/jsonnet/utils/add-annotations.libsonnet +++ b/jsonnet/utils/add-annotations.libsonnet @@ -88,7 +88,7 @@ if clusterRoleBinding then s + '.' else if namespace != '' then - s + ' in the `%s` project.' + s + ' in the `%s` project.' % namespace else s + ' in the project.', diff --git a/test/e2e/doc_examples_test.go b/test/e2e/doc_examples_test.go index 471531daee..a05d76a6fd 100644 --- a/test/e2e/doc_examples_test.go +++ b/test/e2e/doc_examples_test.go @@ -15,63 +15,143 @@ package e2e import ( + "context" + "fmt" + "hash/fnv" "os" "path/filepath" + "strconv" "testing" + "time" + "github.com/openshift/cluster-monitoring-operator/test/e2e/framework" "github.com/openshift/cluster-monitoring-operator/test/e2e/test_command" "github.com/stretchr/testify/require" "gopkg.in/yaml.v3" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) +const ( + testNamespace = "test-doc-examples-in-cluster" + serviceAccount = "tester" + clusterRoleBinding = "tester" +) + +func toPodName(testName string) string { + h := fnv.New64() + h.Write([]byte(testName)) + return "test-" + strconv.FormatUint(h.Sum64(), 32) +} + +func setupEnv(t *testing.T) { + cleanupNS, err := f.CreateNamespace(testNamespace) + require.NoError(t, err) + t.Cleanup(func() { + require.NoError(t, cleanupNS()) + }) + + cleanupSA, err := f.CreateServiceAccount(testNamespace, serviceAccount) + require.NoError(t, err) + t.Cleanup(func() { + require.NoError(t, cleanupSA()) + }) + + cleanupBinding, err := f.CreateClusterRoleBinding(testNamespace, clusterRoleBinding, "cluster-admin") + require.NoError(t, err) + t.Cleanup(func() { + require.NoError(t, cleanupBinding()) + }) +} + func TestDocExamples(t *testing.T) { filesDir := "test_command/scripts/" tempDir := t.TempDir() kubeConfigPath := f.KubeConfigPath - entries, err := os.ReadDir(filesDir) + scripts, err := os.ReadDir(filesDir) require.NoError(t, err) // In case there is a wiring issue. - require.Greater(t, len(entries), 0) - - for _, entry := range entries { - file, err := os.Open(filepath.Join(filesDir, entry.Name())) - require.NoError(t, err) - defer file.Close() - - var suite test_command.Suite - decoder := yaml.NewDecoder(file) - decoder.KnownFields(true) - err = decoder.Decode(&suite) - require.NoError(t, err) - - for _, test := range suite.Tests { - // TODO: run in // - t.Run(entry.Name(), func(t *testing.T) { - // Set up cleaners - t.Cleanup(func() { - for _, c := range test.TearDown { - c.Run(t, tempDir, kubeConfigPath) + require.Greater(t, len(scripts), 3) + setupEnv(t) + + for _, script := range scripts { + t.Run(script.Name(), func(t *testing.T) { + t.Parallel() + file, err := os.Open(filepath.Join(filesDir, script.Name())) + require.NoError(t, err) + defer file.Close() + + var suite test_command.Suite + decoder := yaml.NewDecoder(file) + decoder.KnownFields(true) + require.NoError(t, decoder.Decode(&suite)) + + for i, test := range suite.Tests { + // Run the script inside a Pod as some of the endpoints are not exposed by default. + t.Run(fmt.Sprintf("test-%d", i), func(t *testing.T) { + t.Parallel() + t.Cleanup(func() { + test_command.RunScript(t, test.TearDown, tempDir, kubeConfigPath) + }) + + ctx := context.Background() + podName := toPodName(t.Name()) + containerName := "test" + pod := &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: podName, + Namespace: testNamespace, + }, + Spec: corev1.PodSpec{ + ServiceAccountName: serviceAccount, + RestartPolicy: corev1.RestartPolicyNever, + Containers: []corev1.Container{ + { + Name: containerName, + Image: "registry.redhat.io/openshift4/ose-cli:latest", + ImagePullPolicy: corev1.PullIfNotPresent, + Command: []string{"bash", "-c", test.Script}, + SecurityContext: &corev1.SecurityContext{ + Capabilities: &corev1.Capabilities{ + Drop: []corev1.Capability{"ALL"}, + }, + SeccompProfile: &corev1.SeccompProfile{ + Type: corev1.SeccompProfileTypeRuntimeDefault, + }, + }, + }, + }, + }, } - }) - // Setup - envVars := map[string]string{} - for _, setup := range test.SetUp { - require.NoError(t, setup.Run(t, tempDir, kubeConfigPath)) - if setup.EnvVarValue() == "" { - continue + pod, err := f.KubeClient.CoreV1().Pods(testNamespace).Create(ctx, pod, metav1.CreateOptions{}) + require.NoError(t, err) + t.Cleanup(func() { + err := f.KubeClient.CoreV1().Pods(testNamespace).Delete(context.Background(), podName, metav1.DeleteOptions{}) + require.NoError(t, err) + }) + + err = framework.Poll(time.Second, time.Minute, func() error { + pod, err = f.KubeClient.CoreV1().Pods(testNamespace).Get(ctx, podName, metav1.GetOptions{}) + if err != nil { + return err + } + if pod.Status.Phase != corev1.PodSucceeded && pod.Status.Phase != corev1.PodFailed { + return fmt.Errorf("waiting for pod") + } + return nil + }) + require.NoError(t, err) + + if pod.Status.Phase != corev1.PodSucceeded { + l, err := f.GetLogs(testNamespace, podName, containerName) + require.NoError(t, err) + t.Log(l) + require.Fail(t, "pod failed to execute script") } - // Check duplicated env vars. - require.NotContains(t, envVars, setup.EnvVar) - envVars[setup.EnvVar] = setup.EnvVarValue() - } - - // Run the checks - for _, g := range test.Checks { - require.NoError(t, g.Run(t, tempDir, kubeConfigPath, envVars)) - } - }) - } + }) + } + }) } } diff --git a/test/e2e/test_command/scripts/openshift-monitoring_alertmanager-main_service_port_9092.yaml b/test/e2e/test_command/scripts/openshift-monitoring_alertmanager-main_service_port_9092.yaml new file mode 100644 index 0000000000..7b9309be52 --- /dev/null +++ b/test/e2e/test_command/scripts/openshift-monitoring_alertmanager-main_service_port_9092.yaml @@ -0,0 +1,67 @@ +tests: + - script: | + ## The following example exercises permissions granted by the `monitoring-rules-edit` cluster role. + ## The binding commands must be run by a user with the necessary privileges. + # Create a test namespace and a service account. + oc create namespace test-alertmanager-tenancy-monitoring-rules-edit + oc create serviceaccount am-client --namespace=test-alertmanager-tenancy-monitoring-rules-edit + # Bind the role to the service account. + # The binding in this example is applied to a service account but can also be applied to any user. + oc create rolebinding test-alertmanager-tenancy-monitoring-rules-edit \ + --namespace=test-alertmanager-tenancy-monitoring-rules-edit \ + --clusterrole=monitoring-rules-edit \ + --serviceaccount=test-alertmanager-tenancy-monitoring-rules-edit:am-client + # Generate a token to access the endpoints. + TOKEN=$(oc create token am-client --namespace=test-alertmanager-tenancy-monitoring-rules-edit) + # Access Alertmanager endpoints from within the cluster. The port is not exposed externally by default. + curl -k -f -H "Authorization: Bearer $TOKEN" "https://alertmanager-main.openshift-monitoring:9092/api/v2/alerts?namespace=test-alertmanager-tenancy-monitoring-rules-edit" + curl -k -X POST -f "https://alertmanager-main.openshift-monitoring:9092/api/v2/silences?namespace=test-alertmanager-tenancy-monitoring-rules-edit" \ + -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \ + -d '{ + "matchers": [ + { + "name": "alertname", + "value": "MyTestAlert", + "isRegex": false + } + ], + "startsAt": "2044-01-01T00:00:00Z", + "endsAt": "2044-01-01T00:00:01Z", + "createdBy": "test-alertmanager-tenancy-monitoring-rules-edit/am-client", + "comment": "Silence test" + }' + tearDown: | + oc delete namespace test-alertmanager-tenancy-monitoring-rules-edit --wait=false + - script: | + ## The following example exercises permissions granted by the `monitoring-edit` cluster role. + ## The binding commands must be run by a user with the necessary privileges. + # Create a test namespace and a service account. + oc create namespace test-alertmanager-tenancy-monitoring-edit + oc create serviceaccount am-client --namespace=test-alertmanager-tenancy-monitoring-edit + # Bind the role to the service account. + # The binding in this example is applied to a service account but can also be applied to any user. + oc create rolebinding test-alertmanager-tenancy-monitoring-edit \ + --namespace=test-alertmanager-tenancy-monitoring-edit \ + --clusterrole=monitoring-edit \ + --serviceaccount=test-alertmanager-tenancy-monitoring-edit:am-client + # Generate a token to access the endpoints. + TOKEN=$(oc create token am-client --namespace=test-alertmanager-tenancy-monitoring-edit) + # Access Alertmanager endpoints from within the cluster. The port is not exposed externally by default. + curl -k -f -H "Authorization: Bearer $TOKEN" "https://alertmanager-main.openshift-monitoring:9092/api/v2/alerts?namespace=test-alertmanager-tenancy-monitoring-edit" + curl -k -X POST -f "https://alertmanager-main.openshift-monitoring:9092/api/v2/silences?namespace=test-alertmanager-tenancy-monitoring-edit" \ + -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \ + -d '{ + "matchers": [ + { + "name": "alertname", + "value": "MyTestAlert", + "isRegex": false + } + ], + "startsAt": "2044-01-01T00:00:00Z", + "endsAt": "2044-01-01T00:00:01Z", + "createdBy": "test-alertmanager-tenancy-monitoring-edit/am-client", + "comment": "Silence test" + }' + tearDown: | + oc delete namespace test-alertmanager-tenancy-monitoring-edit --wait=false diff --git a/test/e2e/test_command/scripts/openshift-monitoring_alertmanager-main_service_port_9094.yaml b/test/e2e/test_command/scripts/openshift-monitoring_alertmanager-main_service_port_9094.yaml index 11159a6206..2c728312fc 100644 --- a/test/e2e/test_command/scripts/openshift-monitoring_alertmanager-main_service_port_9094.yaml +++ b/test/e2e/test_command/scripts/openshift-monitoring_alertmanager-main_service_port_9094.yaml @@ -1,62 +1,73 @@ tests: -- header: >- - # monitoring-alertmanager-view grants read permissions. - setUp: - - run: "oc project openshift-monitoring" - - run: "oc create serviceaccount am-ro-client" - - run: >- - oc adm policy add-role-to-user monitoring-alertmanager-view \ - --role-namespace=openshift-monitoring --rolebinding-name=am-ro-client \ - --serviceaccount=am-ro-client - - run: "oc create token am-ro-client" - toEnvVar: TOKEN - # TODO: use Route's status. - - run: "oc get route alertmanager-main -n openshift-monitoring -ojsonpath={.spec.host}" - toEnvVar: ROUTE - checks: - - run: > - curl -H "Authorization: Bearer $TOKEN" -k --fail-with-body "https://$ROUTE/api/v2/alerts?filter=alertname=Watchdog" - tearDown: - - run: >- - oc adm policy remove-role-from-user monitoring-alertmanager-view \ - --role-namespace=openshift-monitoring --rolebinding-name=am-ro-client \ - --serviceaccount=am-ro-client - - run: "oc delete serviceaccount am-ro-client" - - run: "oc project default" -- header: >- - # monitoring-alertmanager-edit grants edit permissions. - setUp: - - run: "oc project openshift-monitoring" - - run: "oc create serviceaccount am-rw-client" - - run: >- - oc adm policy add-role-to-user monitoring-alertmanager-edit \ - --role-namespace=openshift-monitoring --rolebinding-name=am-rw-client \ - --serviceaccount=am-rw-client - - run: "oc create token am-rw-client" - toEnvVar: TOKEN - - run: "oc get route alertmanager-main -n openshift-monitoring -ojsonpath={.spec.host}" - toEnvVar: ROUTE - checks: - - run: > - curl -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \ - -d '{ - "matchers": [ - { - "name": "alertname", - "value": "MyTestAlert", - "isRegex": false - } - ], - "startsAt": "2044-01-01T00:00:00Z", - "endsAt": "2044-01-01T00:00:01Z", - "createdBy": "am-rw-client", - "comment": "Silence test" - }' \ - -k --fail-with-body "https://$ROUTE/api/v2/silences" - tearDown: - - run: >- - oc adm policy remove-role-from-user monitoring-alertmanager-edit \ - --role-namespace=openshift-monitoring --rolebinding-name=am-rw-client \ - --serviceaccount=am-rw-client - - run: "oc delete serviceaccount am-rw-client" - - run: "oc project default" + - script: | + ## The following example exercises permissions granted by the `monitoring-alertmanager-view` role. + ## The binding commands must be run by a user with the necessary privileges. + # Create a test namespace and a service account. + oc create namespace test-alertmanager-web-monitoring-alertmanager-view + oc create serviceaccount am-client --namespace=test-alertmanager-web-monitoring-alertmanager-view + # Bind the role to the service account. + # The binding in this example is applied to a service account but can also be applied to any user. + oc create rolebinding test-alertmanager-web-monitoring-alertmanager-view \ + --namespace=openshift-monitoring \ + --role=monitoring-alertmanager-view \ + --serviceaccount=test-alertmanager-web-monitoring-alertmanager-view:am-client + # Generate a token to access the endpoints. + TOKEN=$(oc create token am-client --namespace=test-alertmanager-web-monitoring-alertmanager-view) + # Access Alertmanager endpoints externally. + ROUTE=$(oc get route alertmanager-main --namespace=openshift-monitoring -ojsonpath={.spec.host}) + curl -k -H "Authorization: Bearer $TOKEN" "https://$ROUTE/api/v2/alerts?filter=alertname=Watchdog" + # Access Alertmanager endpoints from within the cluster. + curl -k -H "Authorization: Bearer $TOKEN" "https://alertmanager-main.openshift-monitoring:9094/api/v2/alerts?filter=alertname=Watchdog" + tearDown: | + oc delete rolebinding test-alertmanager-web-monitoring-alertmanager-view --namespace=openshift-monitoring + oc delete namespace test-alertmanager-web-monitoring-alertmanager-view --wait=false + - script: | + ## The following example exercises permissions granted by the `monitoring-alertmanager-edit` role. + ## The binding commands must be run by a user with the necessary privileges. + # Create a test namespace and a service account. + oc create namespace test-alertmanager-web-monitoring-alertmanager-edit + oc create serviceaccount am-client --namespace=test-alertmanager-web-monitoring-alertmanager-edit + # Bind the role to the service account. + # The binding in this example is applied to a service account but can also be applied to any user. + oc create rolebinding test-alertmanager-web-monitoring-alertmanager-edit \ + --namespace=openshift-monitoring \ + --role=monitoring-alertmanager-edit \ + --serviceaccount=test-alertmanager-web-monitoring-alertmanager-edit:am-client + # Generate a token to access the endpoints. + TOKEN=$(oc create token am-client --namespace=test-alertmanager-web-monitoring-alertmanager-edit) + # Access Alertmanager endpoints externally. + ROUTE=$(oc get route alertmanager-main --namespace=openshift-monitoring -ojsonpath={.spec.host}) + curl -k -X POST "https://$ROUTE/api/v2/silences" \ + -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \ + -d '{ + "matchers": [ + { + "name": "alertname", + "value": "MyTestAlert1", + "isRegex": false + } + ], + "startsAt": "2044-01-01T00:00:00Z", + "endsAt": "2044-01-01T00:00:01Z", + "createdBy": "test-alertmanager-web-monitoring-alertmanager-edit/am-client", + "comment": "Silence test" + }' + # Access Alertmanager endpoints from within the cluster. + curl -k -X POST "https://alertmanager-main.openshift-monitoring:9094/api/v2/silences" \ + -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \ + -d '{ + "matchers": [ + { + "name": "alertname", + "value": "MyTestAlert2", + "isRegex": false + } + ], + "startsAt": "2044-01-01T00:00:00Z", + "endsAt": "2044-01-01T00:00:01Z", + "createdBy": "test-alertmanager-web-monitoring-alertmanager-edit/am-client", + "comment": "Silence test" + }' + tearDown: | + oc delete rolebinding test-alertmanager-web-monitoring-alertmanager-edit --namespace=openshift-monitoring + oc delete namespace test-alertmanager-web-monitoring-alertmanager-edit --wait=false diff --git a/test/e2e/test_command/scripts/openshift-monitoring_prometheus-k8s_service_port_9091.yaml b/test/e2e/test_command/scripts/openshift-monitoring_prometheus-k8s_service_port_9091.yaml new file mode 100644 index 0000000000..3d4939fc23 --- /dev/null +++ b/test/e2e/test_command/scripts/openshift-monitoring_prometheus-k8s_service_port_9091.yaml @@ -0,0 +1,45 @@ +tests: + - script: | + ## The following example exercises permissions granted by the `cluster-monitoring-view` cluster role. + ## The binding commands must be run by a user with the necessary privileges. + # Create a test namespace and a service account. + oc create namespace test-prometheus-web-cluster-monitoring-view + oc create serviceaccount prom-client --namespace=test-prometheus-web-cluster-monitoring-view + # Bind the role to the service account. + # The binding in this example is applied to a service account but can also be applied to any user. + oc create rolebinding test-prometheus-web-cluster-monitoring-view \ + --namespace=openshift-monitoring \ + --clusterrole=cluster-monitoring-view \ + --serviceaccount=test-prometheus-web-cluster-monitoring-view:prom-client + # Generate a token to access the endpoints. + TOKEN=$(oc create token prom-client --namespace=test-prometheus-web-cluster-monitoring-view) + # Access Prometheus endpoints externally. + ROUTE=$(oc get route prometheus-k8s --namespace=openshift-monitoring -ojsonpath={.spec.host}) + curl -k -H "Authorization: Bearer $TOKEN" "https://$ROUTE/api/v1/query?query=up" + # Access Prometheus endpoints from within the cluster. + curl -k -H "Authorization: Bearer $TOKEN" "https://prometheus-k8s.openshift-monitoring:9091/api/v1/query?query=up" + tearDown: | + oc delete rolebinding test-prometheus-web-cluster-monitoring-view --namespace=openshift-monitoring + oc delete namespace test-prometheus-web-cluster-monitoring-view --wait=false + - script: | + ## The following example exercises permissions granted by the `cluster-monitoring-metrics-api` role. + ## The binding commands must be run by a user with the necessary privileges. + # Create a test namespace and a service account. + oc create namespace test-prometheus-web-cluster-monitoring-metrics-api + oc create serviceaccount prom-client --namespace=test-prometheus-web-cluster-monitoring-metrics-api + # Bind the role to the service account. + # The binding in this example is applied to a service account but can also be applied to any user. + oc create rolebinding test-prometheus-web-cluster-monitoring-metrics-api \ + --namespace=openshift-monitoring \ + --role=cluster-monitoring-metrics-api \ + --serviceaccount=test-prometheus-web-cluster-monitoring-metrics-api:prom-client + # Generate a token to access the endpoints. + TOKEN=$(oc create token prom-client --namespace=test-prometheus-web-cluster-monitoring-metrics-api) + # Access Prometheus endpoints externally. + ROUTE=$(oc get route prometheus-k8s --namespace=openshift-monitoring -ojsonpath={.spec.host}) + curl -k -H "Authorization: Bearer $TOKEN" "https://$ROUTE/api/v1/query?query=up" + # Access Prometheus endpoints from within the cluster. + curl -k -H "Authorization: Bearer $TOKEN" "https://prometheus-k8s.openshift-monitoring:9091/api/v1/query?query=up" + tearDown: | + oc delete rolebinding test-prometheus-web-cluster-monitoring-metrics-api --namespace=openshift-monitoring + oc delete namespace test-prometheus-web-cluster-monitoring-metrics-api --wait=false diff --git a/test/e2e/test_command/scripts/openshift-monitoring_thanos-querier_service_port_9091.yaml b/test/e2e/test_command/scripts/openshift-monitoring_thanos-querier_service_port_9091.yaml new file mode 100644 index 0000000000..bf87a17b3d --- /dev/null +++ b/test/e2e/test_command/scripts/openshift-monitoring_thanos-querier_service_port_9091.yaml @@ -0,0 +1,45 @@ +tests: + - script: | + ## The following example exercises permissions granted by the `cluster-monitoring-view` cluster role. + ## The binding commands must be run by a user with the necessary privileges. + # Create a test namespace and a service account. + oc create namespace test-thanos-querier-web-cluster-monitoring-view + oc create serviceaccount thanos-client --namespace=test-thanos-querier-web-cluster-monitoring-view + # Bind the role to the service account. + # The binding in this example is applied to a service account but can also be applied to any user. + oc create rolebinding test-thanos-querier-web-cluster-monitoring-view \ + --namespace=openshift-monitoring \ + --clusterrole=cluster-monitoring-view \ + --serviceaccount=test-thanos-querier-web-cluster-monitoring-view:thanos-client + # Generate a token to access the endpoints. + TOKEN=$(oc create token thanos-client --namespace=test-thanos-querier-web-cluster-monitoring-view) + # Access Thanos Querier endpoints externally. + ROUTE=$(oc get route thanos-querier --namespace=openshift-monitoring -ojsonpath={.spec.host}) + curl -k -H "Authorization: Bearer $TOKEN" "https://$ROUTE/api/v1/query?query=up" + # Access Thanos Querier endpoints from within the cluster. + curl -k -H "Authorization: Bearer $TOKEN" "https://thanos-querier.openshift-monitoring:9091/api/v1/query?query=up" + tearDown: | + oc delete rolebinding test-thanos-querier-web-cluster-monitoring-view --namespace=openshift-monitoring + oc delete namespace test-thanos-querier-web-cluster-monitoring-view --wait=false + - script: | + ## The following example exercises permissions granted by the `cluster-monitoring-metrics-api` role. + ## The binding commands must be run by a user with the necessary privileges. + # Create a test namespace and a service account. + oc create namespace test-thanos-querier-web-cluster-monitoring-metrics-api + oc create serviceaccount thanos-client --namespace=test-thanos-querier-web-cluster-monitoring-metrics-api + # Bind the role to the service account. + # The binding in this example is applied to a service account but can also be applied to any user. + oc create rolebinding test-thanos-querier-web-cluster-monitoring-metrics-api \ + --namespace=openshift-monitoring \ + --role=cluster-monitoring-metrics-api \ + --serviceaccount=test-thanos-querier-web-cluster-monitoring-metrics-api:thanos-client + # Generate a token to access the endpoints. + TOKEN=$(oc create token thanos-client --namespace=test-thanos-querier-web-cluster-monitoring-metrics-api) + # Access Thanos Querier endpoints externally. + ROUTE=$(oc get route thanos-querier --namespace=openshift-monitoring -ojsonpath={.spec.host}) + curl -k -H "Authorization: Bearer $TOKEN" "https://$ROUTE/api/v1/query?query=up" + # Access Thanos Querier endpoints from within the cluster. + curl -k -H "Authorization: Bearer $TOKEN" "https://thanos-querier.openshift-monitoring:9091/api/v1/query?query=up" + tearDown: | + oc delete rolebinding test-thanos-querier-web-cluster-monitoring-metrics-api --namespace=openshift-monitoring + oc delete namespace test-thanos-querier-web-cluster-monitoring-metrics-api --wait=false diff --git a/test/e2e/test_command/scripts/openshift-monitoring_thanos-querier_service_port_9092.yaml b/test/e2e/test_command/scripts/openshift-monitoring_thanos-querier_service_port_9092.yaml new file mode 100644 index 0000000000..c388437ecc --- /dev/null +++ b/test/e2e/test_command/scripts/openshift-monitoring_thanos-querier_service_port_9092.yaml @@ -0,0 +1,19 @@ +tests: + - script: | + ## The following example exercises permissions granted by the `view` cluster role. + ## The binding commands must be run by a user with the necessary privileges. + # Create a test namespace and a service account. + oc create namespace test-thanos-querier-tenancy-view + oc create serviceaccount thanos-client --namespace=test-thanos-querier-tenancy-view + # Bind the role to the service account. + # The binding in this example is applied to a service account but can also be applied to any user. + oc create rolebinding test-thanos-querier-tenancy-view \ + --namespace=test-thanos-querier-tenancy-view \ + --clusterrole=view \ + --serviceaccount=test-thanos-querier-tenancy-view:thanos-client + # Generate a token to access the endpoints. + TOKEN=$(oc create token thanos-client --namespace=test-thanos-querier-tenancy-view) + # Access Thanos Querier endpoints from within the cluster. The port is not exposed externally by default. + curl -k -f -H "Authorization: Bearer $TOKEN" "https://thanos-querier.openshift-monitoring:9092/api/v1/query?query=up&namespace=test-thanos-querier-tenancy-view" + tearDown: | + oc delete namespace test-thanos-querier-tenancy-view --wait=false diff --git a/test/e2e/test_command/scripts/openshift-monitoring_thanos-querier_service_port_9093.yaml b/test/e2e/test_command/scripts/openshift-monitoring_thanos-querier_service_port_9093.yaml new file mode 100644 index 0000000000..119d077283 --- /dev/null +++ b/test/e2e/test_command/scripts/openshift-monitoring_thanos-querier_service_port_9093.yaml @@ -0,0 +1,58 @@ +tests: + - script: | + ## The following example exercises permissions granted by the `monitoring-rules-edit` cluster role. + ## The binding commands must be run by a user with the necessary privileges. + # Create a test namespace and a service account. + oc create namespace test-thanos-querier-tenancy-rules-monitoring-rules-edit + oc create serviceaccount thanos-client --namespace=test-thanos-querier-tenancy-rules-monitoring-rules-edit + # Bind the role to the service account. + # The binding in this example is applied to a service account but can also be applied to any user. + oc create rolebinding test-thanos-querier-tenancy-rules-monitoring-rules-edit \ + --namespace=test-thanos-querier-tenancy-rules-monitoring-rules-edit \ + --clusterrole=monitoring-rules-edit \ + --serviceaccount=test-thanos-querier-tenancy-rules-monitoring-rules-edit:thanos-client + # Generate a token to access the endpoints. + TOKEN=$(oc create token thanos-client --namespace=test-thanos-querier-tenancy-rules-monitoring-rules-edit) + # Access Thanos Querier endpoints from within the cluster. The port is not exposed externally by default. + curl -k -f -H "Authorization: Bearer $TOKEN" "https://thanos-querier.openshift-monitoring:9093/api/v1/rules?namespace=test-thanos-querier-tenancy-rules-monitoring-rules-edit" + curl -k -f -H "Authorization: Bearer $TOKEN" "https://thanos-querier.openshift-monitoring:9093/api/v1/alerts?namespace=test-thanos-querier-tenancy-rules-monitoring-rules-edit" + tearDown: | + oc delete namespace test-thanos-querier-tenancy-rules-monitoring-rules-edit --wait=false + - script: | + ## The following example exercises permissions granted by the `monitoring-edit` cluster role. + ## The binding commands must be run by a user with the necessary privileges. + # Create a test namespace and a service account. + oc create namespace test-thanos-querier-tenancy-rules-monitoring-edit + oc create serviceaccount thanos-client --namespace=test-thanos-querier-tenancy-rules-monitoring-edit + # Bind the role to the service account. + # The binding in this example is applied to a service account but can also be applied to any user. + oc create rolebinding test-thanos-querier-tenancy-rules-monitoring-edit \ + --namespace=test-thanos-querier-tenancy-rules-monitoring-edit \ + --clusterrole=monitoring-edit \ + --serviceaccount=test-thanos-querier-tenancy-rules-monitoring-edit:thanos-client + # Generate a token to access the endpoints. + TOKEN=$(oc create token thanos-client --namespace=test-thanos-querier-tenancy-rules-monitoring-edit) + # Access Thanos Querier endpoints from within the cluster. The port is not exposed externally by default. + curl -k -f -H "Authorization: Bearer $TOKEN" "https://thanos-querier.openshift-monitoring:9093/api/v1/rules?namespace=test-thanos-querier-tenancy-rules-monitoring-edit" + curl -k -f -H "Authorization: Bearer $TOKEN" "https://thanos-querier.openshift-monitoring:9093/api/v1/alerts?namespace=test-thanos-querier-tenancy-rules-monitoring-edit" + tearDown: | + oc delete namespace test-thanos-querier-tenancy-rules-monitoring-edit --wait=false + - script: | + ## The following example exercises permissions granted by the `monitoring-rules-view` cluster role. + ## The binding commands must be run by a user with the necessary privileges. + # Create a test namespace and a service account. + oc create namespace test-thanos-querier-tenancy-rules-monitoring-rules-view + oc create serviceaccount thanos-client --namespace=test-thanos-querier-tenancy-rules-monitoring-rules-view + # Bind the role to the service account. + # The binding in this example is applied to a service account but can also be applied to any user. + oc create rolebinding test-thanos-querier-tenancy-rules-monitoring-rules-view \ + --namespace=test-thanos-querier-tenancy-rules-monitoring-rules-view \ + --clusterrole=monitoring-rules-view \ + --serviceaccount=test-thanos-querier-tenancy-rules-monitoring-rules-view:thanos-client + # Generate a token to access the endpoints. + TOKEN=$(oc create token thanos-client --namespace=test-thanos-querier-tenancy-rules-monitoring-rules-view) + # Access Thanos Querier endpoints from within the cluster. The port is not exposed externally by default. + curl -k -f -H "Authorization: Bearer $TOKEN" "https://thanos-querier.openshift-monitoring:9093/api/v1/rules?namespace=test-thanos-querier-tenancy-rules-monitoring-rules-view" + curl -k -f -H "Authorization: Bearer $TOKEN" "https://thanos-querier.openshift-monitoring:9093/api/v1/alerts?namespace=test-thanos-querier-tenancy-rules-monitoring-rules-view" + tearDown: | + oc delete namespace test-thanos-querier-tenancy-rules-monitoring-rules-view --wait=false diff --git a/test/e2e/test_command/test_command.go b/test/e2e/test_command/test_command.go index d17c748354..40a1d2f96c 100644 --- a/test/e2e/test_command/test_command.go +++ b/test/e2e/test_command/test_command.go @@ -15,142 +15,119 @@ package test_command import ( + "bufio" "bytes" "context" "fmt" "os" "os/exec" + "strings" "testing" "time" - "strings" - - "github.com/mattn/go-shellwords" "github.com/stretchr/testify/require" ) -var commandTimeout time.Duration = 5 * time.Second - -type SetUpTearDownCommand struct { - // This isn't run in a shell. - Command string `yaml:"run"` - EnvVar string `yaml:"toEnvVar"` - // the Commands' stdout - envVarValue string -} - -type CheckCommand struct { - // This isn't run in a shell. - Command string `yaml:"run"` -} +const commandTimeout time.Duration = 5 * time.Second type Test struct { - Header string `yaml:"header"` - // Run by a user having the needed permissions. - // Env vars defined in SetUp, can only be used in Checks - SetUp []SetUpTearDownCommand `yaml:"setUp"` - // - Checks []CheckCommand `yaml:"checks"` - - TearDown []SetUpTearDownCommand `yaml:"tearDown"` + Script string `yaml:"script"` + // Only for the test + TearDown string `yaml:"tearDown"` } type Suite struct { Tests []Test `yaml:"tests"` } -func (stc *SetUpTearDownCommand) String() string { - if stc.EnvVar != "" { - return fmt.Sprintf("$ %s=$(%s)", stc.EnvVar, stc.Command) +func (test *Test) parse() (description string, commands []string) { + var descLines []string + scanner := bufio.NewScanner(strings.NewReader(test.Script)) + for scanner.Scan() { + line := scanner.Text() + if after, ok := strings.CutPrefix(line, "## "); ok { + descLines = append(descLines, after) + } else if strings.TrimSpace(line) != "" { + commands = append(commands, line) + } } - return fmt.Sprintf("$ %s", stc.Command) + if err := scanner.Err(); err != nil { + panic(err) + } + description = strings.Join(descLines, " ") + return } -func (stc *SetUpTearDownCommand) EnvVarValue() string { - return stc.envVarValue +func formatCommands(commands []string) string { + var sb strings.Builder + for _, line := range commands { + // Preserve comments and indented multiline lines. + if strings.HasPrefix(line, "#") || strings.HasPrefix(line, " ") { + sb.WriteString(line) + } else { + sb.WriteString("$ " + line) + } + sb.WriteString("\n") + } + return strings.TrimSuffix(sb.String(), "\n") } -func (cc *CheckCommand) String() string { - return fmt.Sprintf("$ %s", cc.Command) +type formatter interface { + formatTest(description string, commands string) string } -func (test *Test) String() string { +type markdownFormatter struct{} + +func (f markdownFormatter) formatTest(description, commands string) string { var sb strings.Builder + sb.WriteString("```\n") + sb.WriteString("# ") + sb.WriteString(description) + sb.WriteString("\n\n") + sb.WriteString(commands) sb.WriteString("\n") - sb.WriteString(test.Header) - for _, s := range test.SetUp { - sb.WriteString("\n") - sb.WriteString(s.String()) - } - for _, c := range test.Checks { - sb.WriteString("\n") - sb.WriteString(c.String()) - } + sb.WriteString("```") return sb.String() } -func (suite *Suite) intoCodeBlocks(delimiter string) string { +type asciidocFormatter struct{} + +func (f asciidocFormatter) formatTest(description, commands string) string { var sb strings.Builder - for _, t := range suite.Tests { - sb.WriteString(delimiter) - sb.WriteString(t.String()) - sb.WriteString(delimiter) - sb.WriteString("\n") - } + sb.WriteString("+\n") + sb.WriteString(description) + sb.WriteString("\n+\n") + sb.WriteString("[source,terminal]\n----\n") + sb.WriteString(commands) + sb.WriteString("\n----") return sb.String() } +func (suite *Suite) format(f formatter) string { + tests := make([]string, len(suite.Tests)) + for i, t := range suite.Tests { + description, commands := t.parse() + tests[i] = f.formatTest(description, formatCommands(commands)) + } + return strings.Join(tests, "\n") + "\n" +} + func (suite *Suite) StringMarkdown() string { - return suite.intoCodeBlocks("```") + return suite.format(markdownFormatter{}) } func (suite *Suite) StringAscii() string { - // Not ready to be part of the doc yet. - return "" - // return suite.intoCodeBlocks("----") + return suite.format(asciidocFormatter{}) } -func (stc *SetUpTearDownCommand) Run(t *testing.T, wDir, kubeConfigPath string) error { +func RunScript(t *testing.T, script, wDir, kubeConfigPath string) { t.Helper() ctx, cancel := context.WithTimeout(context.Background(), commandTimeout) defer cancel() - args, err := shellwords.Parse(stc.Command) - require.NoError(t, err) - - cmd := exec.CommandContext(ctx, args[0], args[1:]...) + cmd := exec.CommandContext(ctx, "bash", "-c", script) cmd.Stderr = bytes.NewBuffer(nil) cmd.Dir = wDir cmd.Env = append(os.Environ(), fmt.Sprintf("KUBECONFIG=%s", kubeConfigPath)) - - if stc.EnvVar != "" { - out, err := cmd.Output() - require.NoError(t, err, "getting stdout failed: %v: command stderr %v", err, cmd.Stderr) - stc.envVarValue = string(out) - return nil - } - - require.NoError(t, cmd.Run(), "running %s failed: command stderr: %v", stc.Command, cmd.Stderr) - return nil -} - -func (cc *CheckCommand) Run(t *testing.T, wDir, kubeConfigPath string, envVars map[string]string) error { - t.Helper() - ctx, cancel := context.WithTimeout(context.Background(), commandTimeout) - defer cancel() - - parser := shellwords.NewParser() - // To avoid running a shell. - parser.ParseEnv = true - envVars["KUBECONFIG"] = kubeConfigPath - parser.Getenv = func(s string) string { return envVars[s] } - args, err := parser.Parse(cc.Command) - require.NoError(t, err) - - cmd := exec.CommandContext(ctx, args[0], args[1:]...) - cmd.Stderr = bytes.NewBuffer(nil) - cmd.Dir = wDir - - require.NoError(t, cmd.Run(), "running %s failed: command stderr: %v", cc.Command, cmd.Stderr) - return nil + require.NoError(t, cmd.Run(), "running %s failed: command stderr: %v", script, cmd.Stderr) } diff --git a/vendor/github.com/mattn/go-shellwords/.travis.yml b/vendor/github.com/mattn/go-shellwords/.travis.yml deleted file mode 100644 index ebd5edd898..0000000000 --- a/vendor/github.com/mattn/go-shellwords/.travis.yml +++ /dev/null @@ -1,16 +0,0 @@ -arch: - - amd64 - - ppc64le -language: go -sudo: false -go: - - tip - -before_install: - - go get -t -v ./... - -script: - - ./go.test.sh - -after_success: - - bash <(curl -s https://codecov.io/bash) diff --git a/vendor/github.com/mattn/go-shellwords/LICENSE b/vendor/github.com/mattn/go-shellwords/LICENSE deleted file mode 100644 index 740fa93132..0000000000 --- a/vendor/github.com/mattn/go-shellwords/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017 Yasuhiro Matsumoto - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/github.com/mattn/go-shellwords/README.md b/vendor/github.com/mattn/go-shellwords/README.md deleted file mode 100644 index bdd531918c..0000000000 --- a/vendor/github.com/mattn/go-shellwords/README.md +++ /dev/null @@ -1,55 +0,0 @@ -# go-shellwords - -[![codecov](https://codecov.io/gh/mattn/go-shellwords/branch/master/graph/badge.svg)](https://codecov.io/gh/mattn/go-shellwords) -[![Build Status](https://travis-ci.org/mattn/go-shellwords.svg?branch=master)](https://travis-ci.org/mattn/go-shellwords) -[![PkgGoDev](https://pkg.go.dev/badge/github.com/mattn/go-shellwords)](https://pkg.go.dev/github.com/mattn/go-shellwords) -[![ci](https://github.com/mattn/go-shellwords/ci/badge.svg)](https://github.com/mattn/go-shellwords/actions) - -Parse line as shell words. - -## Usage - -```go -args, err := shellwords.Parse("./foo --bar=baz") -// args should be ["./foo", "--bar=baz"] -``` - -```go -envs, args, err := shellwords.ParseWithEnvs("FOO=foo BAR=baz ./foo --bar=baz") -// envs should be ["FOO=foo", "BAR=baz"] -// args should be ["./foo", "--bar=baz"] -``` - -```go -os.Setenv("FOO", "bar") -p := shellwords.NewParser() -p.ParseEnv = true -args, err := p.Parse("./foo $FOO") -// args should be ["./foo", "bar"] -``` - -```go -p := shellwords.NewParser() -p.ParseBacktick = true -args, err := p.Parse("./foo `echo $SHELL`") -// args should be ["./foo", "/bin/bash"] -``` - -```go -shellwords.ParseBacktick = true -p := shellwords.NewParser() -args, err := p.Parse("./foo `echo $SHELL`") -// args should be ["./foo", "/bin/bash"] -``` - -# Thanks - -This is based on cpan module [Parse::CommandLine](https://metacpan.org/pod/Parse::CommandLine). - -# License - -under the MIT License: http://mattn.mit-license.org/2017 - -# Author - -Yasuhiro Matsumoto (a.k.a mattn) diff --git a/vendor/github.com/mattn/go-shellwords/go.test.sh b/vendor/github.com/mattn/go-shellwords/go.test.sh deleted file mode 100644 index a7deaca96a..0000000000 --- a/vendor/github.com/mattn/go-shellwords/go.test.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env bash - -set -e -echo "" > coverage.txt - -for d in $(go list ./... | grep -v vendor); do - go test -coverprofile=profile.out -covermode=atomic "$d" - if [ -f profile.out ]; then - cat profile.out >> coverage.txt - rm profile.out - fi -done diff --git a/vendor/github.com/mattn/go-shellwords/shellwords.go b/vendor/github.com/mattn/go-shellwords/shellwords.go deleted file mode 100644 index 1b42a00170..0000000000 --- a/vendor/github.com/mattn/go-shellwords/shellwords.go +++ /dev/null @@ -1,317 +0,0 @@ -package shellwords - -import ( - "bytes" - "errors" - "os" - "strings" - "unicode" -) - -var ( - ParseEnv bool = false - ParseBacktick bool = false -) - -func isSpace(r rune) bool { - switch r { - case ' ', '\t', '\r', '\n': - return true - } - return false -} - -func replaceEnv(getenv func(string) string, s string) string { - if getenv == nil { - getenv = os.Getenv - } - - var buf bytes.Buffer - rs := []rune(s) - for i := 0; i < len(rs); i++ { - r := rs[i] - if r == '\\' { - i++ - if i == len(rs) { - break - } - buf.WriteRune(rs[i]) - continue - } else if r == '$' { - i++ - if i == len(rs) { - buf.WriteRune(r) - break - } - if rs[i] == 0x7b { - i++ - p := i - for ; i < len(rs); i++ { - r = rs[i] - if r == '\\' { - i++ - if i == len(rs) { - return s - } - continue - } - if r == 0x7d || (!unicode.IsLetter(r) && r != '_' && !unicode.IsDigit(r)) { - break - } - } - if r != 0x7d { - return s - } - if i > p { - buf.WriteString(getenv(s[p:i])) - } - } else { - p := i - for ; i < len(rs); i++ { - r := rs[i] - if r == '\\' { - i++ - if i == len(rs) { - return s - } - continue - } - if !unicode.IsLetter(r) && r != '_' && !unicode.IsDigit(r) { - break - } - } - if i > p { - buf.WriteString(getenv(s[p:i])) - i-- - } else { - buf.WriteString(s[p:]) - } - } - } else { - buf.WriteRune(r) - } - } - return buf.String() -} - -type Parser struct { - ParseEnv bool - ParseBacktick bool - Position int - Dir string - - // If ParseEnv is true, use this for getenv. - // If nil, use os.Getenv. - Getenv func(string) string -} - -func NewParser() *Parser { - return &Parser{ - ParseEnv: ParseEnv, - ParseBacktick: ParseBacktick, - Position: 0, - Dir: "", - } -} - -type argType int - -const ( - argNo argType = iota - argSingle - argQuoted -) - -func (p *Parser) Parse(line string) ([]string, error) { - args := []string{} - buf := "" - var escaped, doubleQuoted, singleQuoted, backQuote, dollarQuote bool - backtick := "" - - pos := -1 - got := argNo - - i := -1 -loop: - for _, r := range line { - i++ - if escaped { - buf += string(r) - escaped = false - got = argSingle - continue - } - - if r == '\\' { - if singleQuoted { - buf += string(r) - } else { - escaped = true - } - continue - } - - if isSpace(r) { - if singleQuoted || doubleQuoted || backQuote || dollarQuote { - buf += string(r) - backtick += string(r) - } else if got != argNo { - if p.ParseEnv { - if got == argSingle { - parser := &Parser{ParseEnv: false, ParseBacktick: false, Position: 0, Dir: p.Dir} - strs, err := parser.Parse(replaceEnv(p.Getenv, buf)) - if err != nil { - return nil, err - } - args = append(args, strs...) - } else { - args = append(args, replaceEnv(p.Getenv, buf)) - } - } else { - args = append(args, buf) - } - buf = "" - got = argNo - } - continue - } - - switch r { - case '`': - if !singleQuoted && !doubleQuoted && !dollarQuote { - if p.ParseBacktick { - if backQuote { - out, err := shellRun(backtick, p.Dir) - if err != nil { - return nil, err - } - buf = buf[:len(buf)-len(backtick)] + out - } - backtick = "" - backQuote = !backQuote - continue - } - backtick = "" - backQuote = !backQuote - } - case ')': - if !singleQuoted && !doubleQuoted && !backQuote { - if p.ParseBacktick { - if dollarQuote { - out, err := shellRun(backtick, p.Dir) - if err != nil { - return nil, err - } - buf = buf[:len(buf)-len(backtick)-2] + out - } - backtick = "" - dollarQuote = !dollarQuote - continue - } - backtick = "" - dollarQuote = !dollarQuote - } - case '(': - if !singleQuoted && !doubleQuoted && !backQuote { - if !dollarQuote && strings.HasSuffix(buf, "$") { - dollarQuote = true - buf += "(" - continue - } else { - return nil, errors.New("invalid command line string") - } - } - case '"': - if !singleQuoted && !dollarQuote { - if doubleQuoted { - got = argQuoted - } - doubleQuoted = !doubleQuoted - continue - } - case '\'': - if !doubleQuoted && !dollarQuote { - if singleQuoted { - got = argQuoted - } - singleQuoted = !singleQuoted - continue - } - case ';', '&', '|', '<', '>': - if !(escaped || singleQuoted || doubleQuoted || backQuote || dollarQuote) { - if r == '>' && len(buf) > 0 { - if c := buf[0]; '0' <= c && c <= '9' { - i -= 1 - got = argNo - } - } - pos = i - break loop - } - } - - got = argSingle - buf += string(r) - if backQuote || dollarQuote { - backtick += string(r) - } - } - - if got != argNo { - if p.ParseEnv { - if got == argSingle { - parser := &Parser{ParseEnv: false, ParseBacktick: false, Position: 0, Dir: p.Dir} - strs, err := parser.Parse(replaceEnv(p.Getenv, buf)) - if err != nil { - return nil, err - } - args = append(args, strs...) - } else { - args = append(args, replaceEnv(p.Getenv, buf)) - } - } else { - args = append(args, buf) - } - } - - if escaped || singleQuoted || doubleQuoted || backQuote || dollarQuote { - return nil, errors.New("invalid command line string") - } - - p.Position = pos - - return args, nil -} - -func (p *Parser) ParseWithEnvs(line string) (envs []string, args []string, err error) { - _args, err := p.Parse(line) - if err != nil { - return nil, nil, err - } - envs = []string{} - args = []string{} - parsingEnv := true - for _, arg := range _args { - if parsingEnv && isEnv(arg) { - envs = append(envs, arg) - } else { - if parsingEnv { - parsingEnv = false - } - args = append(args, arg) - } - } - return envs, args, nil -} - -func isEnv(arg string) bool { - return len(strings.Split(arg, "=")) == 2 -} - -func Parse(line string) ([]string, error) { - return NewParser().Parse(line) -} - -func ParseWithEnvs(line string) (envs []string, args []string, err error) { - return NewParser().ParseWithEnvs(line) -} diff --git a/vendor/github.com/mattn/go-shellwords/util_posix.go b/vendor/github.com/mattn/go-shellwords/util_posix.go deleted file mode 100644 index b56a90120a..0000000000 --- a/vendor/github.com/mattn/go-shellwords/util_posix.go +++ /dev/null @@ -1,29 +0,0 @@ -// +build !windows - -package shellwords - -import ( - "fmt" - "os" - "os/exec" - "strings" -) - -func shellRun(line, dir string) (string, error) { - var shell string - if shell = os.Getenv("SHELL"); shell == "" { - shell = "/bin/sh" - } - cmd := exec.Command(shell, "-c", line) - if dir != "" { - cmd.Dir = dir - } - b, err := cmd.Output() - if err != nil { - if eerr, ok := err.(*exec.ExitError); ok { - b = eerr.Stderr - } - return "", fmt.Errorf("%s: %w", string(b), err) - } - return strings.TrimSpace(string(b)), nil -} diff --git a/vendor/github.com/mattn/go-shellwords/util_windows.go b/vendor/github.com/mattn/go-shellwords/util_windows.go deleted file mode 100644 index fd738a7211..0000000000 --- a/vendor/github.com/mattn/go-shellwords/util_windows.go +++ /dev/null @@ -1,29 +0,0 @@ -// +build windows - -package shellwords - -import ( - "fmt" - "os" - "os/exec" - "strings" -) - -func shellRun(line, dir string) (string, error) { - var shell string - if shell = os.Getenv("COMSPEC"); shell == "" { - shell = "cmd" - } - cmd := exec.Command(shell, "/c", line) - if dir != "" { - cmd.Dir = dir - } - b, err := cmd.Output() - if err != nil { - if eerr, ok := err.(*exec.ExitError); ok { - b = eerr.Stderr - } - return "", fmt.Errorf("%s: %w", string(b), err) - } - return strings.TrimSpace(string(b)), nil -} diff --git a/vendor/modules.txt b/vendor/modules.txt index fce439a548..27fe5883dd 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -443,9 +443,6 @@ github.com/kylelemons/godebug/pretty github.com/mailru/easyjson/buffer github.com/mailru/easyjson/jlexer github.com/mailru/easyjson/jwriter -# github.com/mattn/go-shellwords v1.0.12 -## explicit; go 1.13 -github.com/mattn/go-shellwords # github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible ## explicit github.com/mistifyio/go-zfs