Skip to content

Commit f2a4766

Browse files
committed
Add validation in reconciliation workflow
1 parent b04d485 commit f2a4766

File tree

5 files changed

+51
-2
lines changed

5 files changed

+51
-2
lines changed

api/v1alpha1/channel_webhook.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ func (r *Channel) ValidateUpdate(old runtime.Object) error {
5555
if !ok {
5656
return fmt.Errorf("Error casting old runtime object to %T from %T", oldChannel, old)
5757
}
58-
return validateImmutableFields(r, oldChannel)
58+
return ValidateImmutableFields(r, oldChannel)
5959
}
6060

6161
// ValidateDelete implements webhook.Validator so a webhook will be registered for the type
@@ -66,7 +66,7 @@ func (r *Channel) ValidateDelete() error {
6666
}
6767

6868
// TODO: test & write tst
69-
func validateImmutableFields(newChannel *Channel, oldChannel *Channel) error {
69+
func ValidateImmutableFields(newChannel *Channel, oldChannel *Channel) error {
7070
if oldChannel.Spec.Private != newChannel.Spec.Private {
7171
return fmt.Errorf("Field 'isPrivate' is immutable and cannot be changed after Slack Channel has been created")
7272
}

controllers/channel_controller.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,14 @@ func (r *ChannelReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
109109
return r.updateSlackChannel(ctx, channel)
110110
}
111111

112+
existingChannel, err := r.SlackService.GetChannel(channel.Status.ID)
113+
existingChannelCR := r.SlackService.GetChannelCRFromChannel(existingChannel)
114+
115+
err = slackv1alpha1.ValidateImmutableFields(existingChannelCR, channel)
116+
if err != nil {
117+
return reconcilerUtil.ManageError(r.Client, channel, err, true)
118+
}
119+
112120
return r.updateSlackChannel(ctx, channel)
113121
}
114122

controllers/suite_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ var _ = BeforeSuite(func(done Done) {
103103
}, 60)
104104

105105
var _ = AfterSuite(func() {
106+
util.DeleteNamespace(ns)
107+
106108
By("tearing down the test environment")
107109
err := testEnv.Stop()
108110
Expect(err).ToNot(HaveOccurred())

controllers/util/testUtil.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,16 @@ func (t *TestUtil) CreateNamespace(name string) {
104104
}
105105
}
106106

107+
// CreateNamespace creates a namespace in the kubernetes server
108+
func (t *TestUtil) DeleteNamespace(name string) {
109+
namespaceObject := t.CreateNamespaceObject(name)
110+
err := t.k8sClient.Delete(t.ctx, namespaceObject)
111+
112+
if err != nil {
113+
ginkgo.Fail(err.Error())
114+
}
115+
}
116+
107117
// CreateSlackChannelObject creates a slack channel custom resource object
108118
func (t *TestUtil) CreateSlackChannelObject(name string, isPrivate bool, topic string, description string, users []string, namespace string) *slackv1alpha1.Channel {
109119
return &slackv1alpha1.Channel{

pkg/slack/service.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package slack
33
import (
44
"github.com/go-logr/logr"
55
"github.com/slack-go/slack"
6+
7+
slackv1alpha1 "github.com/stakater/slack-operator/api/v1alpha1"
68
)
79

810
// Service interface
@@ -13,6 +15,8 @@ type Service interface {
1315
RenameChannel(string, string) (*slack.Channel, error)
1416
ArchiveChannel(string) error
1517
InviteUsers(string, []string) error
18+
GetChannel(string) (*slack.Channel, error)
19+
GetChannelCRFromChannel(*slack.Channel) *slackv1alpha1.Channel
1620
}
1721

1822
// SlackService structure
@@ -29,6 +33,19 @@ func New(APIToken string, logger logr.Logger) *SlackService {
2933
}
3034
}
3135

36+
// GetChannel gets a channel on slack
37+
func (s *SlackService) GetChannel(channelID string) (*slack.Channel, error) {
38+
log := s.log.WithValues("channelID", channelID)
39+
40+
channel, err := s.api.GetConversationInfo(channelID, false)
41+
if err != nil {
42+
log.Error(err, "Error fetching channel")
43+
return nil, err
44+
}
45+
46+
return channel, err
47+
}
48+
3249
// CreateChannel creates a public or private channel on slack with the given name
3350
func (s *SlackService) CreateChannel(name string, isPrivate bool) (*string, error) {
3451
s.log.Info("Creating Slack Channel", "name", name, "isPrivate", isPrivate)
@@ -158,3 +175,15 @@ func (s *SlackService) InviteUsers(channelID string, userEmails []string) error
158175
}
159176
return nil
160177
}
178+
179+
func (s *SlackService) GetChannelCRFromChannel(existingChannel *slack.Channel) *slackv1alpha1.Channel {
180+
var channel slackv1alpha1.Channel
181+
182+
channel.Spec.Name = existingChannel.Name
183+
channel.Spec.Description = existingChannel.Purpose.Value
184+
channel.Spec.Topic = existingChannel.Topic.Value
185+
channel.Spec.Private = existingChannel.IsPrivate
186+
channel.Spec.Users = existingChannel.Members
187+
188+
return &channel
189+
}

0 commit comments

Comments
 (0)