Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for query RBAC #1100

Draft
wants to merge 3 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions .chloggen/query-rbac.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
change_type: enhancement

# The name of the component, or a single word describing the area of concern, (e.g. tempostack, tempomonolithic, github action)
component: tempostack

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: Add support for query RBAC when Gateway/multitenancy is used.

# One or more tracking issues related to the change
issues: [1100]

# (Optional) One or more lines of additional information to render under the primary note.
# These lines will be padded with 2 spaces and then inserted directly into the document.
# Use pipe (|) for multiline entries.
subtext: |
This feature allows users to apply query RBAC in the multitenancy mode.
The RBAC allows filtering span/resource/scope attributes and events based on the namespaces which a user querying the data can access.
For instance, a user can only see attributes from namespaces it can access.

```yaml
spec:
template:
gateway:
enabled: true
rbac:
enabled: true
```
8 changes: 8 additions & 0 deletions api/tempo/v1alpha1/tempostack_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -578,6 +578,14 @@ type TempoGatewaySpec struct {
// +kubebuilder:validation:Optional
// +operator-sdk:csv:customresourcedefinitions:type=spec,displayName="Jaeger gateway Ingress Settings"
Ingress IngressSpec `json:"ingress,omitempty"`

RBAC RBACSpec `json:"rbac,omitempty"`
}

// RBACSpec defines RBAC options.
type RBACSpec struct {
// Enabled defines if the query RBAC should be enabled.
Enabled bool `json:"enabled"`
}

// TempoQueryFrontendSpec extends TempoComponentSpec with frontend specific parameters.
Expand Down
16 changes: 16 additions & 0 deletions api/tempo/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ metadata:
capabilities: Deep Insights
categories: Logging & Tracing,Monitoring
containerImage: ghcr.io/grafana/tempo-operator/tempo-operator:v0.14.2
createdAt: "2024-12-12T05:29:14Z"
createdAt: "2025-01-22T15:42:22Z"
description: Create and manage deployments of Tempo, a high-scale distributed
tracing backend.
operatorframework.io/cluster-monitoring: "true"
Expand Down
10 changes: 10 additions & 0 deletions bundle/community/manifests/tempo.grafana.com_tempostacks.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1424,6 +1424,16 @@ spec:
- ""
type: string
type: object
rbac:
description: RBACSpec defines RBAC options.
properties:
enabled:
description: Enabled defines if the query RBAC should
be enabled.
type: boolean
required:
- enabled
type: object
required:
- enabled
type: object
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ metadata:
capabilities: Deep Insights
categories: Logging & Tracing,Monitoring
containerImage: ghcr.io/grafana/tempo-operator/tempo-operator:v0.14.2
createdAt: "2024-12-12T05:29:13Z"
createdAt: "2025-01-22T15:42:20Z"
description: Create and manage deployments of Tempo, a high-scale distributed
tracing backend.
operatorframework.io/cluster-monitoring: "true"
Expand Down
10 changes: 10 additions & 0 deletions bundle/openshift/manifests/tempo.grafana.com_tempostacks.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1424,6 +1424,16 @@ spec:
- ""
type: string
type: object
rbac:
description: RBACSpec defines RBAC options.
properties:
enabled:
description: Enabled defines if the query RBAC should
be enabled.
type: boolean
required:
- enabled
type: object
required:
- enabled
type: object
Expand Down
10 changes: 10 additions & 0 deletions config/crd/bases/tempo.grafana.com_tempostacks.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1420,6 +1420,16 @@ spec:
- ""
type: string
type: object
rbac:
description: RBACSpec defines RBAC options.
properties:
enabled:
description: Enabled defines if the query RBAC should
be enabled.
type: boolean
required:
- enabled
type: object
required:
- enabled
type: object
Expand Down
2 changes: 2 additions & 0 deletions docs/spec/tempo.grafana.com_tempostacks.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,8 @@ spec: # TempoStackSpec defines the desired st
route: # Route defines the options for the OpenShift route.
termination: "" # Termination defines the termination type. The default is "edge".
type: "" # Type defines the type of Ingress for the Jaeger Query UI. Currently ingress, route and none are supported.
rbac: # RBACSpec defines RBAC options.
enabled: false # Enabled defines if the query RBAC should be enabled.
ingester: # Ingester defines the ingester component spec.
podSecurityContext: # PodSecurityContext defines security context will be applied to all pods of this component.
fsGroup: 0 # A special supplemental group that applies to all containers in a pod. Some volume types allow the Kubelet to change the ownership of that volume to be owned by the pod: 1. The owning GID will be the FSGroup 2. The setgid bit is set (new files created in the volume will be owned by FSGroup) 3. The permission bits are OR'd with rw-rw---- If unset, the Kubelet will not modify the ownership and permissions of any volume. Note that this field cannot be set when spec.os.name is windows.
Expand Down
25 changes: 25 additions & 0 deletions internal/manifests/gateway/gateway.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,10 @@ func BuildGateway(params manifestutils.Params) ([]client.Object, error) {
if err != nil {
return nil, err
}
dep.Spec.Template, err = patchReadRBAC(params, dep.Spec.Template)
if err != nil {
return nil, err
}

dep.Spec.Template, err = patchTracing(params.Tempo, dep.Spec.Template)
if err != nil {
Expand Down Expand Up @@ -357,6 +361,27 @@ func patchTraceReadEndpoint(params manifestutils.Params, pod corev1.PodTemplateS
return pod, nil
}

func patchReadRBAC(params manifestutils.Params, pod corev1.PodTemplateSpec) (corev1.PodTemplateSpec, error) {
if !params.Tempo.Spec.Template.Gateway.RBAC.Enabled {
return pod, nil
}

container := corev1.Container{
Args: []string{"--traces.query-rbac=true"},
}

for i := range pod.Spec.Containers {
if pod.Spec.Containers[i].Name != containerNameTempoGateway {
continue
}
if err := mergo.Merge(&pod.Spec.Containers[i], container, mergo.WithAppendSlice); err != nil {
return corev1.PodTemplateSpec{}, err
}
}

return pod, nil
}

func patchTracing(tempo v1alpha1.TempoStack, pod corev1.PodTemplateSpec) (corev1.PodTemplateSpec, error) {
if tempo.Spec.Observability.Tracing.SamplingFraction == "" {
return pod, nil
Expand Down
122 changes: 122 additions & 0 deletions internal/manifests/gateway/gateway_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,128 @@ func TestPatchTraceReadEndpoint(t *testing.T) {
}
}

func TestPatchReadRBAC(t *testing.T) {
tt := []struct {
name string
inputParams manifestutils.Params
inputPod corev1.PodTemplateSpec
expectPod corev1.PodTemplateSpec
expectErr error
}{
{
name: "with read RBAC",
inputParams: manifestutils.Params{
Tempo: v1alpha1.TempoStack{
ObjectMeta: metav1.ObjectMeta{
Name: "name",
Namespace: "default",
},
Spec: v1alpha1.TempoStackSpec{
Template: v1alpha1.TempoTemplateSpec{
Gateway: v1alpha1.TempoGatewaySpec{
Enabled: true,
RBAC: v1alpha1.RBACSpec{
Enabled: true,
},
},
},
},
},
},
inputPod: corev1.PodTemplateSpec{
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: containerNameTempoGateway,
Args: []string{
"--abc",
},
},
{
Name: "second",
Args: []string{
"--xyz",
},
},
},
},
},
expectPod: corev1.PodTemplateSpec{
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: containerNameTempoGateway,
Args: []string{
"--abc",
"--traces.query-rbac=true",
},
},
{
Name: "second",
Args: []string{
"--xyz",
},
},
},
},
},
},
{
name: "without trace read RBAC",
inputParams: manifestutils.Params{
Tempo: v1alpha1.TempoStack{
ObjectMeta: metav1.ObjectMeta{
Name: "name",
Namespace: "default",
},
Spec: v1alpha1.TempoStackSpec{
Template: v1alpha1.TempoTemplateSpec{
Gateway: v1alpha1.TempoGatewaySpec{
Enabled: true,
RBAC: v1alpha1.RBACSpec{
Enabled: false,
},
},
},
},
},
},
inputPod: corev1.PodTemplateSpec{
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: containerNameTempoGateway,
Args: []string{
"--abc",
},
},
},
},
},
expectPod: corev1.PodTemplateSpec{
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: containerNameTempoGateway,
Args: []string{
"--abc",
},
},
},
},
},
},
}

for _, tc := range tt {
t.Run(tc.name, func(t *testing.T) {
pod, err := patchReadRBAC(tc.inputParams, tc.inputPod)
require.Equal(t, tc.expectErr, err)
assert.Equal(t, tc.expectPod, pod)
})
}
}

func TestTLSParameters(t *testing.T) {
tempo := v1alpha1.TempoStack{
ObjectMeta: metav1.ObjectMeta{
Expand Down
1 change: 1 addition & 0 deletions internal/manifests/gateway/openshift.go
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ func NewOpaContainer(ctrlConfig configv1alpha1.ProjectConfig, tenants v1alpha1.T
var args = []string{
"--log.level=warn",
"--opa.admin-groups=system:cluster-admins,cluster-admin,dedicated-admin",
"--opa.matcher=kubernetes_namespace_name",
fmt.Sprintf("--web.listen=:%d", gatewayOPAHTTPPort),
fmt.Sprintf("--web.internal.listen=:%d", gatewayOPAInternalPort),
fmt.Sprintf("--web.healthchecks.url=http://localhost:%d", gatewayOPAHTTPPort),
Expand Down
1 change: 1 addition & 0 deletions internal/manifests/gateway/openshift_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ func TestPatchOPAContainer(t *testing.T) {
assert.Equal(t, []string{
"--log.level=warn",
"--opa.admin-groups=system:cluster-admins,cluster-admin,dedicated-admin",
"--opa.matcher=kubernetes_namespace_name",
"--web.listen=:8082", "--web.internal.listen=:8083",
"--web.healthchecks.url=http://localhost:8082",
"--opa.package=tempostack",
Expand Down
1 change: 1 addition & 0 deletions internal/manifests/monolithic/statefulset_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -938,6 +938,7 @@ func TestStatefulsetGateway(t *testing.T) {
Args: []string{
"--log.level=warn",
"--opa.admin-groups=system:cluster-admins,cluster-admin,dedicated-admin",
"--opa.matcher=kubernetes_namespace_name",
"--web.listen=:8082",
"--web.internal.listen=:8083",
"--web.healthchecks.url=http://localhost:8082",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ spec:
- args:
- --log.level=warn
- --opa.admin-groups=system:cluster-admins,cluster-admin,dedicated-admin
- --opa.matcher=kubernetes_namespace_name
- --web.listen=:8082
- --web.internal.listen=:8083
- --web.healthchecks.url=http://localhost:8082
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ spec:
- args:
- --log.level=warn
- --opa.admin-groups=system:cluster-admins,cluster-admin,dedicated-admin
- --opa.matcher=kubernetes_namespace_name
- --web.listen=:8082
- --web.internal.listen=:8083
- --web.healthchecks.url=http://localhost:8082
Expand Down
2 changes: 2 additions & 0 deletions tests/e2e-openshift/multitenancy/01-assert.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ spec:
- --web.healthchecks.url=https://localhost:8080
- --tls.client-auth-type=NoClientCert
- --traces.read.endpoint=https://tempo-simplest-query-frontend.chainsaw-multitenancy.svc.cluster.local:16686
- --traces.query-rbac=true
livenessProbe:
failureThreshold: 10
httpGet:
Expand Down Expand Up @@ -235,6 +236,7 @@ spec:
- args:
- --log.level=warn
- --opa.admin-groups=system:cluster-admins,cluster-admin,dedicated-admin
- --opa.matcher=kubernetes_namespace_name
- --web.listen=:8082
- --web.internal.listen=:8083
- --web.healthchecks.url=http://localhost:8082
Expand Down
2 changes: 2 additions & 0 deletions tests/e2e-openshift/multitenancy/01-install-tempo.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ spec:
template:
gateway:
enabled: true
rbac:
enabled: true
queryFrontend:
jaegerQuery:
enabled: true
Expand Down