Skip to content

Commit c06c27d

Browse files
committed
Reconcile logic and sys tests for topic permission
- issue: #191
1 parent 186d57c commit c06c27d

File tree

13 files changed

+1071
-267
lines changed

13 files changed

+1071
-267
lines changed

controllers/common.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ const (
2323
FederationControllerName = "federation-controller"
2424
ShovelControllerName = "shovel-controller"
2525
SuperStreamControllerName = "super-stream-controller"
26+
TopicPermissionControllerName = "topic-permission-controller"
2627
)
2728

2829
// names for environment variables

controllers/permission_controller.go

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
"context"
55
"errors"
66
"fmt"
7-
87
"github.com/rabbitmq/messaging-topology-operator/rabbitmqclient"
98
k8sApiErrors "k8s.io/apimachinery/pkg/api/errors"
109
"k8s.io/apimachinery/pkg/types"
@@ -33,7 +32,7 @@ func (r *PermissionReconciler) DeclareFunc(ctx context.Context, client rabbitmqc
3332
username := permission.Spec.User
3433
if permission.Spec.UserReference != nil {
3534
var err error
36-
if user, err = r.getUserFromReference(ctx, permission); err != nil {
35+
if user, err = getUsernameFromUser(ctx, r.Client, permission.Namespace, permission.Spec.UserReference.Name); err != nil {
3736
return err
3837
} else if user != nil {
3938
// User exist
@@ -56,26 +55,24 @@ func (r *PermissionReconciler) DeclareFunc(ctx context.Context, client rabbitmqc
5655
return validateResponse(client.UpdatePermissionsIn(permission.Spec.Vhost, username, internal.GeneratePermissions(permission)))
5756
}
5857

59-
func (r *PermissionReconciler) getUserFromReference(ctx context.Context, permission *topology.Permission) (*topology.User, error) {
58+
func getUsernameFromUser(ctx context.Context, client client.Client, namespace, name string) (*topology.User, error) {
6059
logger := ctrl.LoggerFrom(ctx)
6160

62-
// get User from provided user reference
6361
failureMsg := "failed to get User"
6462
user := &topology.User{}
65-
err := r.Get(ctx, types.NamespacedName{Name: permission.Spec.UserReference.Name, Namespace: permission.Namespace}, user)
66-
63+
err := client.Get(ctx, types.NamespacedName{Name: name, Namespace: namespace}, user)
6764
if err != nil && k8sApiErrors.IsNotFound(err) {
6865
logger.Error(fmt.Errorf("user doesn't exist"), failureMsg)
6966
return nil, nil
7067
} else if err != nil {
71-
logger.Error(err, failureMsg, "userReference", permission.Spec.UserReference.Name)
68+
logger.Error(err, failureMsg, "userReference", name)
7269
return nil, err
7370
}
7471

7572
// get username from User status
7673
if user.Status.Username == "" {
7774
err := fmt.Errorf("this User does not have an username set in its status")
78-
logger.Error(err, failureMsg, "userReference", permission.Spec.UserReference.Name)
75+
logger.Error(err, failureMsg, "userReference", name)
7976
return nil, err
8077
}
8178
return user, nil
@@ -87,7 +84,7 @@ func (r *PermissionReconciler) DeleteFunc(ctx context.Context, client rabbitmqcl
8784

8885
username := permission.Spec.User
8986
if permission.Spec.UserReference != nil {
90-
if user, err := r.getUserFromReference(ctx, permission); err != nil {
87+
if user, err := getUsernameFromUser(ctx, r.Client, permission.Namespace, permission.Spec.UserReference.Name); err != nil {
9188
return err
9289
} else if user != nil {
9390
// User exist

controllers/suite_test.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,11 @@ import (
1414
"crypto/x509"
1515
"go/build"
1616
"path/filepath"
17-
"sigs.k8s.io/controller-runtime/pkg/envtest/komega"
1817
"testing"
1918
"time"
2019

20+
"sigs.k8s.io/controller-runtime/pkg/envtest/komega"
21+
2122
"github.com/rabbitmq/messaging-topology-operator/rabbitmqclient"
2223
"github.com/rabbitmq/messaging-topology-operator/rabbitmqclient/rabbitmqclientfakes"
2324

@@ -193,6 +194,14 @@ var _ = BeforeSuite(func() {
193194
RabbitmqClientFactory: fakeRabbitMQClientFactory,
194195
ReconcileFunc: &controllers.ShovelReconciler{Client: mgr.GetClient()},
195196
},
197+
{
198+
Client: mgr.GetClient(),
199+
Type: &topology.TopicPermission{},
200+
Scheme: mgr.GetScheme(),
201+
Recorder: fakeRecorder,
202+
RabbitmqClientFactory: fakeRabbitMQClientFactory,
203+
ReconcileFunc: &controllers.TopicPermissionReconciler{Client: mgr.GetClient(), Scheme: mgr.GetScheme()},
204+
},
196205
}
197206

198207
for _, controller := range topologyReconcilers {
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
package controllers
2+
3+
import (
4+
"context"
5+
"errors"
6+
"fmt"
7+
topology "github.com/rabbitmq/messaging-topology-operator/api/v1beta1"
8+
"github.com/rabbitmq/messaging-topology-operator/internal"
9+
"github.com/rabbitmq/messaging-topology-operator/rabbitmqclient"
10+
"k8s.io/apimachinery/pkg/runtime"
11+
ctrl "sigs.k8s.io/controller-runtime"
12+
"sigs.k8s.io/controller-runtime/pkg/client"
13+
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
14+
)
15+
16+
//+kubebuilder:rbac:groups=rabbitmq.com,resources=topicpermissions,verbs=get;list;watch;create;update;patch;delete
17+
//+kubebuilder:rbac:groups=rabbitmq.com,resources=topicpermissions/status,verbs=get;update;patch
18+
//+kubebuilder:rbac:groups=rabbitmq.com,resources=topicpermissions/finalizers,verbs=update
19+
20+
type TopicPermissionReconciler struct {
21+
client.Client
22+
Scheme *runtime.Scheme
23+
}
24+
25+
func (r *TopicPermissionReconciler) DeclareFunc(ctx context.Context, client rabbitmqclient.Client, obj topology.TopologyResource) error {
26+
permission := obj.(*topology.TopicPermission)
27+
user := &topology.User{}
28+
username := permission.Spec.User
29+
if permission.Spec.UserReference != nil {
30+
var err error
31+
if user, err = getUsernameFromUser(ctx, r.Client, permission.Namespace, permission.Spec.UserReference.Name); err != nil {
32+
return err
33+
} else if user != nil {
34+
// User exist
35+
username = user.Status.Username
36+
}
37+
}
38+
if username == "" {
39+
return fmt.Errorf("failed create Permission, missing User")
40+
}
41+
42+
// user != nil, not working because user has always a name set
43+
if user.Name != "" {
44+
if err := controllerutil.SetControllerReference(user, permission, r.Scheme); err != nil {
45+
return fmt.Errorf("failed set controller reference: %v", err)
46+
}
47+
if err := r.Client.Update(ctx, permission); err != nil {
48+
return fmt.Errorf("failed to Update object with controller reference: %w", err)
49+
}
50+
}
51+
return validateResponse(client.UpdateTopicPermissionsIn(permission.Spec.Vhost, username, internal.GenerateTopicPermissions(permission)))
52+
}
53+
54+
func (r *TopicPermissionReconciler) DeleteFunc(ctx context.Context, client rabbitmqclient.Client, obj topology.TopologyResource) error {
55+
logger := ctrl.LoggerFrom(ctx)
56+
permission := obj.(*topology.TopicPermission)
57+
58+
username := permission.Spec.User
59+
if permission.Spec.UserReference != nil {
60+
if user, err := getUsernameFromUser(ctx, r.Client, permission.Namespace, permission.Spec.UserReference.Name); err != nil {
61+
return err
62+
} else if user != nil {
63+
// User exist
64+
username = user.Status.Username
65+
}
66+
}
67+
68+
if username == "" {
69+
logger.Info("user already removed; no need to delete topic permission")
70+
} else if err := r.clearTopicPermission(ctx, client, permission, username); err != nil {
71+
return err
72+
}
73+
return removeFinalizer(ctx, r.Client, permission)
74+
}
75+
76+
func (r *TopicPermissionReconciler) clearTopicPermission(ctx context.Context, client rabbitmqclient.Client, permission *topology.TopicPermission, user string) error {
77+
logger := ctrl.LoggerFrom(ctx)
78+
err := validateResponseForDeletion(client.DeleteTopicPermissionsIn(permission.Spec.Vhost, user, permission.Spec.Permissions.Exchange))
79+
if errors.Is(err, NotFound) {
80+
logger.Info("cannot find user or vhost in rabbitmq server; no need to delete permission", "user", user, "vhost", permission.Spec.Vhost)
81+
return nil
82+
}
83+
return err
84+
}

0 commit comments

Comments
 (0)