Skip to content

Commit ef778a4

Browse files
committed
Add reconcile logic for slack channel
1 parent 3423c04 commit ef778a4

File tree

1 file changed

+116
-5
lines changed

1 file changed

+116
-5
lines changed

controllers/channel_controller.go

Lines changed: 116 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,32 +20,143 @@ import (
2020
"context"
2121

2222
"github.com/go-logr/logr"
23+
"k8s.io/apimachinery/pkg/api/errors"
2324
"k8s.io/apimachinery/pkg/runtime"
2425
ctrl "sigs.k8s.io/controller-runtime"
2526
"sigs.k8s.io/controller-runtime/pkg/client"
2627

2728
slackv1alpha1 "github.com/stakater/slack-operator/api/v1alpha1"
29+
slack "github.com/stakater/slack-operator/pkg/slack"
2830
)
2931

3032
// ChannelReconciler reconciles a Channel object
3133
type ChannelReconciler struct {
3234
client.Client
33-
Log logr.Logger
34-
Scheme *runtime.Scheme
35+
Log logr.Logger
36+
Scheme *runtime.Scheme
37+
SlackService slack.Service
3538
}
3639

3740
// +kubebuilder:rbac:groups=slack.stakater.com,resources=channels,verbs=get;list;watch;create;update;patch;delete
3841
// +kubebuilder:rbac:groups=slack.stakater.com,resources=channels/status,verbs=get;update;patch
3942

43+
// Reconcile loop for the Channel resource
4044
func (r *ChannelReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
41-
_ = context.Background()
42-
_ = r.Log.WithValues("channel", req.NamespacedName)
45+
ctx := context.Background()
46+
log := r.Log.WithValues("channel", req.NamespacedName)
4347

44-
// your logic here
48+
channel := &slackv1alpha1.Channel{}
49+
err := r.Get(ctx, req.NamespacedName, channel)
50+
51+
if err != nil {
52+
if errors.IsNotFound(err) {
53+
// Request object not found, could have been deleted after reconcile request.
54+
// Owned objects are automatically garbage collected. For additional cleanup logic use finalizers.
55+
// Return and don't requeue
56+
log.Info("Channel resource not found. Deleting channel")
57+
//TODO: Delete slack channel here
58+
return ctrl.Result{}, nil
59+
}
60+
// Error reading channel, requeue
61+
return ctrl.Result{}, err
62+
}
63+
64+
name := channel.Spec.Name
65+
//TODO: make private immutable in validation
66+
isPrivate := channel.Spec.Private
67+
68+
if channel.Status.ID == "" {
69+
log.Info("Creating new channel", "name", name)
70+
71+
channelID, err := r.SlackService.CreateChannel(name, isPrivate)
72+
73+
if err != nil {
74+
// Set error state and don't requeue
75+
channel.Status.Error = err.Error()
76+
return ctrl.Result{}, nil
77+
}
78+
channel.Status.ID = channelID.Get()
79+
80+
err = r.Status().Update(ctx, channel)
81+
if err != nil {
82+
log.Error(err, "Failed to update Channel status")
83+
return ctrl.Result{}, err
84+
}
85+
return ctrl.Result{}, nil
86+
}
87+
88+
return r.updateSlackChannel(ctx, channel)
89+
}
90+
91+
// TODO: too verbose code for error checking
92+
// TODO: send request only if data is different
93+
func (r *ChannelReconciler) updateSlackChannel(ctx context.Context, channel *slackv1alpha1.Channel) (ctrl.Result, error) {
94+
channelID := slack.NewChannelID(channel.Status.ID)
95+
log := r.Log.WithValues("channelID", channelID.Get())
96+
97+
log.Info("Updating channel details")
98+
99+
name := channel.Spec.Name
100+
users := channel.Spec.Users
101+
topic := channel.Spec.Topic
102+
description := channel.Spec.Description
103+
104+
err := r.SlackService.RenameChannel(channelID, name)
105+
if err != nil {
106+
log.Error(err, "Error renaming channel")
107+
channel.Status.Error = err.Error()
108+
109+
err = r.Status().Update(ctx, channel)
110+
if err != nil {
111+
log.Error(err, "Failed to update Channel status")
112+
return ctrl.Result{}, err
113+
}
114+
return ctrl.Result{}, nil
115+
}
116+
117+
err = r.SlackService.SetTopic(channelID, topic)
118+
if err != nil {
119+
log.Error(err, "Error setting channel topic")
120+
channel.Status.Error = err.Error()
121+
122+
err = r.Status().Update(ctx, channel)
123+
if err != nil {
124+
log.Error(err, "Failed to update Channel status")
125+
return ctrl.Result{}, err
126+
}
127+
return ctrl.Result{}, nil
128+
}
129+
130+
err = r.SlackService.SetDescription(channelID, description)
131+
if err != nil {
132+
log.Error(err, "Error setting channel description")
133+
channel.Status.Error = err.Error()
134+
135+
err = r.Status().Update(ctx, channel)
136+
if err != nil {
137+
log.Error(err, "Failed to update Channel status")
138+
return ctrl.Result{}, err
139+
}
140+
return ctrl.Result{}, nil
141+
}
142+
143+
err = r.SlackService.InviteUsers(channelID, users)
144+
if err != nil {
145+
log.Error(err, "Error inviting users to channel")
146+
channel.Status.Error = err.Error()
147+
148+
err = r.Status().Update(ctx, channel)
149+
if err != nil {
150+
log.Error(err, "Failed to update Channel status")
151+
return ctrl.Result{}, err
152+
}
153+
return ctrl.Result{}, nil
154+
}
45155

46156
return ctrl.Result{}, nil
47157
}
48158

159+
// SetupWithManager - Controller-Manager binding configuration
49160
func (r *ChannelReconciler) SetupWithManager(mgr ctrl.Manager) error {
50161
return ctrl.NewControllerManagedBy(mgr).
51162
For(&slackv1alpha1.Channel{}).

0 commit comments

Comments
 (0)