Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion charts/fleet/templates/rbac_gitjob.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ rules:
- watch
- update
- apiGroups:
- ""
- "events.k8s.io"
resources:
- 'events'
verbs:
Expand Down
6 changes: 6 additions & 0 deletions e2e/single-cluster/gitrepo_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,12 @@ var _ = Describe("Monitoring Git repos via HTTP for change", Label("infra-setup"
out, _ := k.Namespace(targetNamespace).Get("deployments")
return out
}, testenv.MediumTimeout, testenv.ShortTimeout).Should(ContainSubstring("newsleep"))

By("checking that events are generated")
Eventually(func() string {
out, _ := k.Get("events", "--field-selector=reason=GotNewCommit")
return out
}).Should(ContainSubstring(commit))
})
})

Expand Down
32 changes: 21 additions & 11 deletions integrationtests/gitjob/controller/controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -438,15 +438,15 @@ var _ = Describe("GitJob controller", func() {
g.Expect(events.Items[0].Reason).To(Equal("GotNewCommit"))
g.Expect(events.Items[0].Message).To(Equal("9ca3a0ad308ed8bffa6602572e2a1343af9c3d2e"))
g.Expect(events.Items[0].Type).To(Equal("Normal"))
g.Expect(events.Items[0].Source.Component).To(Equal("gitjob-controller"))
g.Expect(events.Items[0].ReportingController).To(Equal("gitjob-controller"))
g.Expect(events.Items[1].Reason).To(Equal("Created"))
g.Expect(events.Items[1].Message).To(Equal("GitJob was created"))
g.Expect(events.Items[1].ReportingController).To(Equal("gitjob-controller"))
g.Expect(events.Items[1].Type).To(Equal("Normal"))
g.Expect(events.Items[1].Source.Component).To(Equal("gitjob-controller"))
g.Expect(events.Items[2].Reason).To(Equal("JobDeleted"))
g.Expect(events.Items[2].Message).To(Equal("job deletion triggered because job succeeded"))
g.Expect(events.Items[2].Type).To(Equal("Normal"))
g.Expect(events.Items[2].Source.Component).To(Equal("gitjob-controller"))
g.Expect(events.Items[2].ReportingController).To(Equal("gitjob-controller"))
}).Should(Succeed())

// job should not be present
Expand Down Expand Up @@ -706,30 +706,40 @@ var _ = Describe("GitJob controller", func() {

return string(job.UID) != string(newJob.UID)
}).Should(BeTrue())
// it should log 3 events
// it should log 5 events:
// first one is to log the new commit from the poller
// second one is to inform that the job was created
// third one reports on the job being deleted because of ForceUpdateGeneration
// the fourth and fifth ones represent job re-creation and deletion after successful completion,
// respectively
Eventually(func(g Gomega) {
events, _ := k8sClientSet.CoreV1().Events(gitRepo.Namespace).List(context.TODO(),
metav1.ListOptions{
FieldSelector: "involvedObject.name=force-deletion",
TypeMeta: metav1.TypeMeta{Kind: "GitRepo"},
})
g.Expect(events).ToNot(BeNil())
g.Expect(events.Items).To(HaveLen(3))
g.Expect(events.Items).To(HaveLen(5))

for _, e := range events.Items {
g.Expect(e.ReportingController).To(Equal("gitjob-controller"))
g.Expect(e.Type).To(Equal("Normal"))
}

g.Expect(events.Items[0].Reason).To(Equal("GotNewCommit"))
g.Expect(events.Items[0].Message).To(Equal("9ca3a0ad308ed8bffa6602572e2a1343af9c3d2e"))
g.Expect(events.Items[0].Type).To(Equal("Normal"))
g.Expect(events.Items[0].Source.Component).To(Equal("gitjob-controller"))

g.Expect(events.Items[1].Reason).To(Equal("Created"))
g.Expect(events.Items[1].Message).To(Equal("GitJob was created"))
g.Expect(events.Items[1].Type).To(Equal("Normal"))
g.Expect(events.Items[1].Source.Component).To(Equal("gitjob-controller"))

g.Expect(events.Items[2].Reason).To(Equal("JobDeleted"))
g.Expect(events.Items[2].Message).To(Equal("job deletion triggered because job succeeded"))
g.Expect(events.Items[2].Type).To(Equal("Normal"))
g.Expect(events.Items[2].Source.Component).To(Equal("gitjob-controller"))

g.Expect(events.Items[3].Reason).To(Equal("Created"))
g.Expect(events.Items[3].Message).To(Equal("GitJob was created"))

g.Expect(events.Items[4].Reason).To(Equal("JobDeleted"))
g.Expect(events.Items[4].Message).To(Equal("job deletion triggered because job succeeded"))
}).Should(Succeed())
})

Expand Down
2 changes: 1 addition & 1 deletion integrationtests/gitjob/controller/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ var _ = BeforeSuite(func() {
Scheduler: sched,
GitFetcher: fetcherMock,
Clock: reconciler.RealClock{},
Recorder: mgr.GetEventRecorderFor("gitjob-controller"),
Recorder: mgr.GetEventRecorder("gitjob-controller"),
Workers: 50,
SystemNamespace: "default",
KnownHosts: ssh.KnownHosts{},
Expand Down
2 changes: 1 addition & 1 deletion integrationtests/helmops/controller/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ var _ = BeforeSuite(func() {
err = (&reconciler.HelmOpReconciler{
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
Recorder: mgr.GetEventRecorderFor("helmops-controller"),
Recorder: mgr.GetEventRecorder("helmops-controller"),
Scheduler: sched,
Workers: 50,
}).SetupWithManager(mgr)
Expand Down
2 changes: 1 addition & 1 deletion internal/cmd/controller/gitops/operator.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ func (g *GitOperator) Run(cmd *cobra.Command, args []string) error {
JobNodeSelector: g.ShardNodeSelector,
GitFetcher: &git.Fetch{KnownHosts: kh},
Clock: reconciler.RealClock{},
Recorder: mgr.GetEventRecorderFor(fmt.Sprintf("fleet-gitops%s", shardIDSuffix)),
Recorder: mgr.GetEventRecorder(fmt.Sprintf("fleet-gitops%s", shardIDSuffix)),
SystemNamespace: namespace,
KnownHosts: kh,
WithImagescan: imagescanEnabled,
Expand Down
10 changes: 8 additions & 2 deletions internal/cmd/controller/gitops/reconciler/gitjob.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import (
ssh "github.com/rancher/fleet/internal/ssh"
v1alpha1 "github.com/rancher/fleet/pkg/apis/fleet.cattle.io/v1alpha1"
"github.com/rancher/fleet/pkg/cert"
fleetevent "github.com/rancher/fleet/pkg/event"
"github.com/rancher/fleet/pkg/sharding"

appsv1 "k8s.io/api/apps/v1"
Expand Down Expand Up @@ -70,7 +69,14 @@ func (r *GitJobReconciler) createJobAndResources(ctx context.Context, gitrepo *v
return fmt.Errorf("error creating git job: %w", err)
}

r.Recorder.Event(gitrepo, fleetevent.Normal, "Created", "GitJob was created")
r.Recorder.Eventf(
gitrepo,
nil,
corev1.EventTypeNormal,
"Created",
"CreateGitJob",
"GitJob was created",
)
return nil
}

Expand Down
74 changes: 64 additions & 10 deletions internal/cmd/controller/gitops/reconciler/gitjob_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ import (
"github.com/rancher/fleet/internal/metrics"
v1alpha1 "github.com/rancher/fleet/pkg/apis/fleet.cattle.io/v1alpha1"
"github.com/rancher/fleet/pkg/durations"
fleetevent "github.com/rancher/fleet/pkg/event"
"github.com/rancher/fleet/pkg/sharding"

"github.com/rancher/wrangler/v3/pkg/condition"
Expand All @@ -41,7 +40,7 @@ import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/types"
errutil "k8s.io/apimachinery/pkg/util/errors"
"k8s.io/client-go/tools/record"
"k8s.io/client-go/tools/events"
"k8s.io/client-go/util/retry"
"sigs.k8s.io/cli-utils/pkg/kstatus/status"
ctrl "sigs.k8s.io/controller-runtime"
Expand Down Expand Up @@ -141,7 +140,7 @@ type GitJobReconciler struct {
JobNodeSelector string
GitFetcher GitFetcher
Clock TimeGetter
Recorder record.EventRecorder
Recorder events.EventRecorder
SystemNamespace string
KnownHosts KnownHostsGetter
WithImagescan bool
Expand Down Expand Up @@ -202,7 +201,16 @@ func (r *GitJobReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
// Restrictions / Overrides, gitrepo reconciler is responsible for setting error in status
oldStatus := gitrepo.Status.DeepCopy()
if err := AuthorizeAndAssignDefaults(ctx, r.Client, gitrepo); err != nil {
r.Recorder.Event(gitrepo, fleetevent.Warning, "FailedToApplyRestrictions", err.Error())
r.Recorder.Eventf(
gitrepo,
nil,
corev1.EventTypeWarning,
"FailedToApplyRestrictions",
"ApplyGitRepoRestrictions",
"%v",
err,
)

return ctrl.Result{}, updateErrorStatus(ctx, r.Client, req.NamespacedName, *oldStatus, err)
}

Expand Down Expand Up @@ -306,15 +314,31 @@ func (r *GitJobReconciler) manageGitJob(ctx context.Context, logger logr.Logger,
}, &job)
if err != nil && !apierrors.IsNotFound(err) {
err = fmt.Errorf("error retrieving git job: %w", err)
r.Recorder.Event(gitrepo, fleetevent.Warning, "FailedToGetGitJob", err.Error())
r.Recorder.Eventf(
gitrepo,
nil,
corev1.EventTypeWarning,
"FailedToGetGitJob",
"GetGitJob",
"%v",
err,
)

return ctrl.Result{}, err
}

if apierrors.IsNotFound(err) {
clientSecretChanged, helmSecretChanged, err := r.hasReferencedSecretChanged(ctx, gitrepo)
if err != nil {
r.Recorder.Event(gitrepo, fleetevent.Warning, "FailedValidatingSecret", err.Error())
r.Recorder.Eventf(
gitrepo,
nil,
corev1.EventTypeWarning,
"FailedValidatingSecret",
"ValidateSecret",
"%v",
err,
)
return ctrl.Result{}, fmt.Errorf("error validating external secrets: %w", err)
}

Expand All @@ -333,16 +357,39 @@ func (r *GitJobReconciler) manageGitJob(ctx context.Context, logger logr.Logger,
gitrepo.Status.Commit = commit
}
if err != nil {
r.Recorder.Event(gitrepo, fleetevent.Warning, "Failed", err.Error())
r.Recorder.Eventf(
gitrepo,
nil,
corev1.EventTypeWarning,
"Failed",
"MonitorLatestCommit",
"%v",
err,
)
} else if oldCommit != gitrepo.Status.Commit {
r.Recorder.Event(gitrepo, fleetevent.Normal, "GotNewCommit", gitrepo.Status.Commit)
r.Recorder.Eventf(
gitrepo,
nil,
corev1.EventTypeNormal,
"GotNewCommit",
"GetNewCommit",
gitrepo.Status.Commit,
)
}
}

if r.shouldCreateJob(gitrepo, oldCommit, helmSecretChanged) {
r.updateGenerationValuesIfNeeded(gitrepo)
if err := r.validateExternalSecretExist(ctx, gitrepo); err != nil {
r.Recorder.Event(gitrepo, fleetevent.Warning, "FailedValidatingSecret", err.Error())
r.Recorder.Eventf(
gitrepo,
nil,
corev1.EventTypeWarning,
"FailedValidatingSecret",
"ValidateSecret",
"%v",
err,
)
return ctrl.Result{}, fmt.Errorf("error validating external secrets: %w", err)
}
if err := r.createJobAndResources(ctx, gitrepo, logger); err != nil {
Expand Down Expand Up @@ -581,7 +628,14 @@ func (r *GitJobReconciler) deleteJobIfNeeded(ctx context.Context, gitRepo *v1alp
if err := r.Delete(ctx, job, client.PropagationPolicy(metav1.DeletePropagationBackground)); err != nil && !apierrors.IsNotFound(err) {
return err, false
}
r.Recorder.Event(gitRepo, fleetevent.Normal, "JobDeleted", jobDeletedMessage)
r.Recorder.Eventf(
gitRepo,
nil,
corev1.EventTypeNormal,
"JobDeleted",
"DeleteJob",
jobDeletedMessage,
)
}

// finally if there's a job and any of the secrets related to the gitrepo changed,
Expand Down
47 changes: 37 additions & 10 deletions internal/cmd/controller/gitops/reconciler/gitjob_test.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
//go:generate mockgen --build_flags=--mod=mod -destination=../../../../mocks/client_mock.go -package=mocks -mock_names=Client=MockK8sClient,SubResourceWriter=MockStatusWriter sigs.k8s.io/controller-runtime/pkg/client Client,SubResourceWriter
//go:generate mockgen --build_flags=--mod=mod -destination=../../../../mocks/eventrecorder_mock.go -package=mocks k8s.io/client-go/tools/events EventRecorder

package reconciler

Expand All @@ -22,7 +23,6 @@ import (
"github.com/rancher/wrangler/v3/pkg/genericcondition"
"go.uber.org/mock/gomock"

fleetevent "github.com/rancher/fleet/pkg/event"
appsv1 "k8s.io/api/apps/v1"
batchv1 "k8s.io/api/batch/v1"
corev1 "k8s.io/api/core/v1"
Expand Down Expand Up @@ -85,6 +85,24 @@ func (m gitRepoPointerMatcher) String() string {
return ""
}

// errorMatcher implements a gomock matcher on error message strings.
type errorMatcher struct {
errMsg string
}

func (m errorMatcher) Matches(x interface{}) bool {
err, ok := x.(error)
if !ok {
return false
}

return err.Error() == m.errMsg
}

func (m errorMatcher) String() string {
return fmt.Sprintf("matches error %q", m.errMsg)
}

func TestReconcile_Error_WhenGitrepoRestrictionsAreNotMet(t *testing.T) {
mockCtrl := gomock.NewController(t)
defer mockCtrl.Finish()
Expand Down Expand Up @@ -129,11 +147,14 @@ func TestReconcile_Error_WhenGitrepoRestrictionsAreNotMet(t *testing.T) {
)

recorderMock := mocks.NewMockEventRecorder(mockCtrl)
recorderMock.EXPECT().Event(
recorderMock.EXPECT().Eventf(
&gitRepoMatcher{gitRepo},
fleetevent.Warning,
nil,
corev1.EventTypeWarning,
"FailedToApplyRestrictions",
"empty targetNamespace denied, because allowedTargetNamespaces restriction is present",
"ApplyGitRepoRestrictions",
"%v",
errorMatcher{"empty targetNamespace denied, because allowedTargetNamespaces restriction is present"},
)

r := GitJobReconciler{
Expand Down Expand Up @@ -204,11 +225,14 @@ func TestReconcile_Error_WhenGetGitJobErrors(t *testing.T) {

recorderMock := mocks.NewMockEventRecorder(mockCtrl)

recorderMock.EXPECT().Event(
recorderMock.EXPECT().Eventf(
&gitRepoMatcher{gitRepo},
fleetevent.Warning,
nil,
corev1.EventTypeWarning,
"FailedToGetGitJob",
"error retrieving git job: GITJOB ERROR",
"GetGitJob",
"%v",
errorMatcher{"error retrieving git job: GITJOB ERROR"},
)

r := GitJobReconciler{
Expand Down Expand Up @@ -275,11 +299,14 @@ func TestReconcile_Error_WhenSecretDoesNotExist(t *testing.T) {

recorderMock := mocks.NewMockEventRecorder(mockCtrl)

recorderMock.EXPECT().Event(
recorderMock.EXPECT().Eventf(
&gitRepoMatcher{gitRepo},
fleetevent.Warning,
nil,
corev1.EventTypeWarning,
"FailedValidatingSecret",
"failed to look up HelmSecretNameForPaths, error: SECRET ERROR",
"ValidateSecret",
"%v",
errorMatcher{"failed to look up HelmSecretNameForPaths, error: SECRET ERROR"},
)

statusClient := mocks.NewMockStatusWriter(mockCtrl)
Expand Down
Loading