mirror of https://github.com/rancher/gitjob.git
88 lines
2.4 KiB
Go
88 lines
2.4 KiB
Go
package poll
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"strings"
|
|
|
|
v1 "github.com/rancher/gitjob/pkg/apis/gitjob.cattle.io/v1"
|
|
|
|
"github.com/go-logr/logr"
|
|
"k8s.io/apimachinery/pkg/api/errors"
|
|
"k8s.io/apimachinery/pkg/types"
|
|
ctrl "sigs.k8s.io/controller-runtime"
|
|
"sigs.k8s.io/controller-runtime/pkg/client"
|
|
)
|
|
|
|
type Watcher interface {
|
|
StartBackgroundSync(ctx context.Context)
|
|
Finish()
|
|
Restart(ctx context.Context)
|
|
UpdateGitJob(gitJob v1.GitJob)
|
|
GetSyncInterval() int
|
|
}
|
|
|
|
// Handler handles all the watches for the git repositories. These watches are pulling the latest commit every syncPeriod.
|
|
type Handler struct {
|
|
client client.Client
|
|
watches map[string]Watcher
|
|
createWatch func(gitJob v1.GitJob, client client.Client) Watcher // this func creates a watch. It's a struct field, so it can be replaced for a mock in unit tests.
|
|
log logr.Logger
|
|
}
|
|
|
|
func NewHandler(client client.Client) *Handler {
|
|
return &Handler{
|
|
client: client,
|
|
watches: make(map[string]Watcher),
|
|
createWatch: NewWatch,
|
|
log: ctrl.Log.WithName("git-latest-commit-poll-handler"),
|
|
}
|
|
}
|
|
|
|
// AddOrModifyGitRepoWatch adds a new watch for the gitjob if no watch was already present.
|
|
// It updates the existing watch for this gitjob if present.
|
|
func (h *Handler) AddOrModifyGitRepoWatch(ctx context.Context, gitJob v1.GitJob) {
|
|
key := getKey(gitJob)
|
|
watch, found := h.watches[key]
|
|
if !found {
|
|
h.watches[key] = h.createWatch(gitJob, h.client)
|
|
h.watches[key].StartBackgroundSync(ctx)
|
|
} else {
|
|
oldSyncInterval := watch.GetSyncInterval()
|
|
watch.UpdateGitJob(gitJob)
|
|
if oldSyncInterval != gitJob.Spec.SyncInterval {
|
|
watch.Restart(ctx)
|
|
}
|
|
}
|
|
}
|
|
|
|
// CleanUpWatches removes all watches whose gitjob is not present in the cluster.
|
|
func (h *Handler) CleanUpWatches(ctx context.Context) {
|
|
var gitJob v1.GitJob
|
|
for key, watch := range h.watches {
|
|
namespacedName, err := getTypeNamespaceFromKey(key)
|
|
if err != nil {
|
|
h.log.Error(err, "can't get namespacedName", key)
|
|
}
|
|
if err = h.client.Get(ctx, namespacedName, &gitJob); errors.IsNotFound(err) {
|
|
watch.Finish()
|
|
delete(h.watches, key)
|
|
}
|
|
}
|
|
}
|
|
|
|
func getTypeNamespaceFromKey(key string) (types.NamespacedName, error) {
|
|
split := strings.Split(key, "-")
|
|
if len(split) < 2 {
|
|
return types.NamespacedName{}, fmt.Errorf("invalid key")
|
|
}
|
|
return types.NamespacedName{
|
|
Namespace: split[1],
|
|
Name: split[0],
|
|
}, nil
|
|
}
|
|
|
|
func getKey(gitJob v1.GitJob) string {
|
|
return gitJob.Name + "-" + gitJob.Namespace
|
|
}
|