Skip to content

Commit 47351a3

Browse files
fix(operator): move authorization RBAC to dedicated cluster_scoped
reconciler
1 parent 21cfa33 commit 47351a3

17 files changed

+173
-141
lines changed

operator/internal/controller/loki/dashboards_controller.go renamed to operator/internal/controller/loki/lokistack_cluster_scoped_controller.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,15 +47,15 @@ func (r *DashboardsReconciler) Reconcile(ctx context.Context, req ctrl.Request)
4747
if len(stacks.Items) == 0 {
4848
// Removes all LokiStack dashboard resources on OpenShift clusters when
4949
// the last LokiStack custom resource is deleted.
50-
if err := handlers.DeleteDashboards(ctx, r.Client, r.OperatorNs); err != nil {
50+
if err := handlers.DeleteClusterScopedResources(ctx, r.Client, r.OperatorNs, stacks); err != nil {
5151
return ctrl.Result{}, kverrors.Wrap(err, "failed to delete dashboard resources")
5252
}
5353
return ctrl.Result{}, nil
5454
}
5555

5656
// Creates all LokiStack dashboard resources on OpenShift clusters when
5757
// the first LokiStack custom resource is created.
58-
if err := handlers.CreateDashboards(ctx, r.Log, r.OperatorNs, r.Client, r.Scheme); err != nil {
58+
if err := handlers.CreateClusterScopedResources(ctx, r.Log, r.OperatorNs, r.Client, r.Scheme, stacks); err != nil {
5959
return ctrl.Result{}, kverrors.Wrap(err, "failed to create dashboard resources", "req", req)
6060
}
6161
return ctrl.Result{}, nil

operator/internal/handlers/dashboards_create.go

Lines changed: 0 additions & 52 deletions
This file was deleted.
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
package handlers
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/ViaQ/logerr/v2/kverrors"
8+
"github.com/go-logr/logr"
9+
rbacv1 "k8s.io/api/rbac/v1"
10+
"k8s.io/apimachinery/pkg/runtime"
11+
ctrl "sigs.k8s.io/controller-runtime"
12+
"sigs.k8s.io/controller-runtime/pkg/client" //nolint:typecheck
13+
ctrlutil "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
14+
15+
lokiv1 "github.com/grafana/loki/operator/api/loki/v1"
16+
"github.com/grafana/loki/operator/internal/external/k8s"
17+
"github.com/grafana/loki/operator/internal/manifests"
18+
"github.com/grafana/loki/operator/internal/manifests/openshift"
19+
)
20+
21+
// CreateClusterScopedResources handles the LokiStack cluster scoped create events.
22+
func CreateClusterScopedResources(ctx context.Context, log logr.Logger, operatorNs string, k k8s.Client, s *runtime.Scheme, stacks lokiv1.LokiStackList) error {
23+
// This has to be done here as to not introduce a circular dependency.
24+
gatewaySubjects := make([]rbacv1.Subject, 0, len(stacks.Items))
25+
rulerSubjects := make([]rbacv1.Subject, 0, len(stacks.Items))
26+
for _, stack := range stacks.Items {
27+
gatewaySubjects = append(gatewaySubjects, rbacv1.Subject{
28+
Kind: "ServiceAccount",
29+
Name: manifests.GatewayName(stack.Name),
30+
Namespace: stack.Namespace,
31+
})
32+
rulerSubjects = append(rulerSubjects, rbacv1.Subject{
33+
Kind: "ServiceAccount",
34+
Name: manifests.RulerName(stack.Name),
35+
Namespace: stack.Namespace,
36+
})
37+
}
38+
opts := openshift.NewOptionsClusterScope(operatorNs, stacks, manifests.ClusterScopeLabels(), gatewaySubjects, rulerSubjects)
39+
40+
objs, err := openshift.BuildDashboards(opts)
41+
if err != nil {
42+
return kverrors.Wrap(err, "failed to build dashboard manifests")
43+
}
44+
45+
rbacOBjs, err := openshift.BuildRBAC(opts)
46+
if err != nil {
47+
return kverrors.Wrap(err, "failed to build RBAC manifests")
48+
}
49+
objs = append(objs, rbacOBjs...)
50+
51+
var errCount int32
52+
for _, obj := range objs {
53+
desired := obj.DeepCopyObject().(client.Object)
54+
mutateFn := manifests.MutateFuncFor(obj, desired, nil)
55+
56+
op, err := ctrl.CreateOrUpdate(ctx, k, obj, mutateFn)
57+
if err != nil {
58+
log.Error(err, "failed to configure resource")
59+
errCount++
60+
continue
61+
}
62+
63+
msg := fmt.Sprintf("Resource has been %s", op)
64+
switch op {
65+
case ctrlutil.OperationResultNone:
66+
log.V(1).Info(msg)
67+
default:
68+
log.Info(msg)
69+
}
70+
}
71+
72+
if errCount > 0 {
73+
return kverrors.New("failed to configure lokistack dashboard resources")
74+
}
75+
76+
return nil
77+
}

operator/internal/handlers/dashboards_create_test.go renamed to operator/internal/handlers/lokistack_cluster_scope_resources_create_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ func TestCreateDashboards_ReturnsResourcesInManagedNamespaces(t *testing.T) {
5353

5454
k.StatusStub = func() client.StatusWriter { return sw }
5555

56-
err := CreateDashboards(context.TODO(), logger, "test", k, scheme)
56+
err := CreateClusterScopedResources(context.TODO(), logger, "test", k, scheme, lokiv1.LokiStackList{Items: []lokiv1.LokiStack{stack}})
5757
require.NoError(t, err)
5858

5959
// make sure create was called

operator/internal/handlers/dashboards_delete.go renamed to operator/internal/handlers/lokistack_cluster_scope_resources_delete.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,20 +4,26 @@ import (
44
"context"
55

66
"github.com/ViaQ/logerr/v2/kverrors"
7+
rbacv1 "k8s.io/api/rbac/v1"
78
apierrors "k8s.io/apimachinery/pkg/api/errors"
89
"sigs.k8s.io/controller-runtime/pkg/client"
910

11+
lokiv1 "github.com/grafana/loki/operator/api/loki/v1"
1012
"github.com/grafana/loki/operator/internal/external/k8s"
13+
"github.com/grafana/loki/operator/internal/manifests"
1114
"github.com/grafana/loki/operator/internal/manifests/openshift"
1215
)
1316

14-
// DeleteDashboards removes all cluster-scoped dashboard resources.
15-
func DeleteDashboards(ctx context.Context, k k8s.Client, operatorNs string) error {
16-
objs, err := openshift.BuildDashboards(operatorNs)
17+
// DeleteClusterScopedResources removes all cluster-scoped resources.
18+
func DeleteClusterScopedResources(ctx context.Context, k k8s.Client, operatorNs string, stacks lokiv1.LokiStackList) error {
19+
opts := openshift.NewOptionsClusterScope(operatorNs, stacks, manifests.ClusterScopeLabels(), []rbacv1.Subject{}, []rbacv1.Subject{})
20+
objs, err := openshift.BuildDashboards(opts)
1721
if err != nil {
1822
return kverrors.Wrap(err, "failed to build dashboards manifests")
1923
}
2024

25+
// Delete all re
26+
2127
for _, obj := range objs {
2228
key := client.ObjectKeyFromObject(obj)
2329
if err := k.Delete(ctx, obj, &client.DeleteOptions{}); err != nil {

operator/internal/handlers/dashboards_delete_test.go renamed to operator/internal/handlers/lokistack_cluster_scope_resources_delete_test.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,19 @@ import (
99
"k8s.io/apimachinery/pkg/runtime/schema"
1010
"sigs.k8s.io/controller-runtime/pkg/client"
1111

12+
v1 "github.com/grafana/loki/operator/api/loki/v1"
1213
"github.com/grafana/loki/operator/internal/external/k8s/k8sfakes"
1314
"github.com/grafana/loki/operator/internal/manifests/openshift"
1415
)
1516

1617
func TestDeleteDashboards(t *testing.T) {
17-
objs, err := openshift.BuildDashboards("operator-ns")
18+
opts := openshift.NewOptionsClusterScope("operator-ns", v1.LokiStackList{}, nil, nil, nil)
19+
objs, err := openshift.BuildDashboards(opts)
1820
require.NoError(t, err)
1921

2022
k := &k8sfakes.FakeClient{}
2123

22-
err = DeleteDashboards(context.TODO(), k, "operator-ns")
24+
err = DeleteClusterScopedResources(context.TODO(), k, "operator-ns", v1.LokiStackList{})
2325
require.NoError(t, err)
2426
require.Equal(t, k.DeleteCallCount(), len(objs))
2527
}
@@ -30,6 +32,6 @@ func TestDeleteDashboards_ReturnsNoError_WhenNotFound(t *testing.T) {
3032
return apierrors.NewNotFound(schema.GroupResource{}, "something wasn't found")
3133
}
3234

33-
err := DeleteDashboards(context.TODO(), k, "operator-ns")
35+
err := DeleteClusterScopedResources(context.TODO(), k, "operator-ns", v1.LokiStackList{})
3436
require.NoError(t, err)
3537
}

operator/internal/manifests/gateway_tenants.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,6 @@ func configureGatewayObjsForMode(objs []client.Object, opts Options) []client.Ob
152152
}
153153
}
154154

155-
openShiftObjs := openshift.BuildGatewayTenantModeObjects(opts.OpenShiftOptions)
156-
objs = append(objs, openShiftObjs...)
157155
}
158156

159157
return objs

operator/internal/manifests/gateway_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,7 @@ func TestBuildGateway_HasExtraObjectsForTenantMode(t *testing.T) {
303303
})
304304

305305
require.NoError(t, err)
306-
require.Len(t, objs, 13)
306+
require.Len(t, objs, 11)
307307
}
308308

309309
func TestBuildGateway_WithExtraObjectsForTenantMode_RouteSvcMatches(t *testing.T) {
@@ -987,7 +987,7 @@ func TestBuildGateway_PodDisruptionBudget(t *testing.T) {
987987
}
988988
objs, err := BuildGateway(opts)
989989
require.NoError(t, err)
990-
require.Len(t, objs, 13)
990+
require.Len(t, objs, 11)
991991

992992
pdb := objs[6].(*policyv1.PodDisruptionBudget)
993993
require.NotNil(t, pdb)

operator/internal/manifests/openshift/build.go

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,24 +15,11 @@ func BuildGatewayObjects(opts Options) []client.Object {
1515
}
1616
}
1717

18-
// BuildGatewayTenantModeObjects returns a list of auxiliary openshift/k8s objects
19-
// for lokistack gateway deployments on OpenShift for tenant modes:
20-
// - openshift-logging
21-
// - openshift-network
22-
func BuildGatewayTenantModeObjects(opts Options) []client.Object {
23-
return []client.Object{
24-
BuildGatewayClusterRole(opts),
25-
BuildGatewayClusterRoleBinding(opts),
26-
}
27-
}
28-
2918
// BuildRulerObjects returns a list of auxiliary openshift/k8s objects
3019
// for lokistack ruler deployments on OpenShift.
3120
func BuildRulerObjects(opts Options) []client.Object {
3221
return []client.Object{
3322
BuildAlertManagerCAConfigMap(opts),
3423
BuildRulerServiceAccount(opts),
35-
BuildRulerClusterRole(opts),
36-
BuildRulerClusterRoleBinding(opts),
3724
}
3825
}

operator/internal/manifests/openshift/build_test.go

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,9 @@ import (
66
"time"
77

88
"github.com/stretchr/testify/require"
9-
corev1 "k8s.io/api/core/v1"
109
rbacv1 "k8s.io/api/rbac/v1"
11-
12-
lokiv1 "github.com/grafana/loki/operator/api/loki/v1"
1310
)
1411

15-
func TestBuildGatewayTenantModeObjects_ClusterRoleRefMatches(t *testing.T) {
16-
opts := NewOptions("abc", "ns", "abc", "abc", "abc", 1*time.Minute, map[string]string{}, "abc").
17-
WithTenantsForMode(lokiv1.OpenshiftLogging, "example.com", map[string]TenantData{})
18-
19-
objs := BuildGatewayTenantModeObjects(*opts)
20-
cr := objs[0].(*rbacv1.ClusterRole)
21-
rb := objs[1].(*rbacv1.ClusterRoleBinding)
22-
23-
require.Equal(t, cr.Kind, rb.RoleRef.Kind)
24-
require.Equal(t, cr.Name, rb.RoleRef.Name)
25-
}
26-
2712
func TestBuildGatewayObjects_MonitoringClusterRoleRefMatches(t *testing.T) {
2813
opts := NewOptions("abc", "ns", "abc", "abc", "abc", 1*time.Minute, map[string]string{}, "abc")
2914

@@ -49,18 +34,3 @@ func TestBuildGatewayObjets_RouteWithTimeoutAnnotation(t *testing.T) {
4934
want := fmt.Sprintf("%.fs", routeTimeout.Seconds())
5035
require.Equal(t, want, got)
5136
}
52-
53-
func TestBuildRulerObjects_ClusterRoleRefMatches(t *testing.T) {
54-
opts := NewOptions("abc", "ns", "abc", "abc", "abc", 1*time.Minute, map[string]string{}, "abc")
55-
56-
objs := BuildRulerObjects(*opts)
57-
sa := objs[1].(*corev1.ServiceAccount)
58-
cr := objs[2].(*rbacv1.ClusterRole)
59-
rb := objs[3].(*rbacv1.ClusterRoleBinding)
60-
61-
require.Equal(t, sa.Kind, rb.Subjects[0].Kind)
62-
require.Equal(t, sa.Name, rb.Subjects[0].Name)
63-
require.Equal(t, sa.Namespace, rb.Subjects[0].Namespace)
64-
require.Equal(t, cr.Kind, rb.RoleRef.Kind)
65-
require.Equal(t, cr.Name, rb.RoleRef.Name)
66-
}

0 commit comments

Comments
 (0)