@@ -20,32 +20,143 @@ import (
20
20
"context"
21
21
22
22
"github.com/go-logr/logr"
23
+ "k8s.io/apimachinery/pkg/api/errors"
23
24
"k8s.io/apimachinery/pkg/runtime"
24
25
ctrl "sigs.k8s.io/controller-runtime"
25
26
"sigs.k8s.io/controller-runtime/pkg/client"
26
27
27
28
slackv1alpha1 "github.com/stakater/slack-operator/api/v1alpha1"
29
+ slack "github.com/stakater/slack-operator/pkg/slack"
28
30
)
29
31
30
32
// ChannelReconciler reconciles a Channel object
31
33
type ChannelReconciler struct {
32
34
client.Client
33
- Log logr.Logger
34
- Scheme * runtime.Scheme
35
+ Log logr.Logger
36
+ Scheme * runtime.Scheme
37
+ SlackService slack.Service
35
38
}
36
39
37
40
// +kubebuilder:rbac:groups=slack.stakater.com,resources=channels,verbs=get;list;watch;create;update;patch;delete
38
41
// +kubebuilder:rbac:groups=slack.stakater.com,resources=channels/status,verbs=get;update;patch
39
42
43
+ // Reconcile loop for the Channel resource
40
44
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 )
43
47
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
+ }
45
155
46
156
return ctrl.Result {}, nil
47
157
}
48
158
159
+ // SetupWithManager - Controller-Manager binding configuration
49
160
func (r * ChannelReconciler ) SetupWithManager (mgr ctrl.Manager ) error {
50
161
return ctrl .NewControllerManagedBy (mgr ).
51
162
For (& slackv1alpha1.Channel {}).
0 commit comments