From f9a35a66134e6356b596f30e8cc52fdc1b56a297 Mon Sep 17 00:00:00 2001 From: stefanprodan Date: Sun, 12 Apr 2020 18:12:28 +0300 Subject: [PATCH] Move status condition helpers to API --- api/v1alpha1/gitrepository_types.go | 45 ++++++++++ api/v1alpha1/helmrepository_types.go | 46 ++++++++++ controllers/conditions.go | 102 ----------------------- controllers/gitrepository_controller.go | 44 +++++----- controllers/helmrepository_controller.go | 32 ++++--- 5 files changed, 127 insertions(+), 142 deletions(-) delete mode 100644 controllers/conditions.go diff --git a/api/v1alpha1/gitrepository_types.go b/api/v1alpha1/gitrepository_types.go index 44ad82fa..f4e7cab7 100644 --- a/api/v1alpha1/gitrepository_types.go +++ b/api/v1alpha1/gitrepository_types.go @@ -108,3 +108,48 @@ const ( GitOperationSucceedReason string = "GitOperationSucceed" GitOperationFailedReason string = "GitOperationFailed" ) + +func GitRepositoryReady(repository GitRepository, artifact Artifact, url, reason, message string) GitRepository { + repository.Status.Conditions = []SourceCondition{ + { + Type: ReadyCondition, + Status: corev1.ConditionTrue, + LastTransitionTime: metav1.Now(), + Reason: reason, + Message: message, + }, + } + repository.Status.URL = url + + if repository.Status.Artifact != nil { + if repository.Status.Artifact.Path != artifact.Path { + repository.Status.Artifact = &artifact + } + } else { + repository.Status.Artifact = &artifact + } + + return repository +} + +func GitRepositoryNotReady(repository GitRepository, reason, message string) GitRepository { + repository.Status.Conditions = []SourceCondition{ + { + Type: ReadyCondition, + Status: corev1.ConditionFalse, + LastTransitionTime: metav1.Now(), + Reason: reason, + Message: message, + }, + } + return repository +} + +func GitRepositoryReadyMessage(repository GitRepository) string { + for _, condition := range repository.Status.Conditions { + if condition.Type == ReadyCondition { + return condition.Message + } + } + return "" +} diff --git a/api/v1alpha1/helmrepository_types.go b/api/v1alpha1/helmrepository_types.go index 8c239abe..06e87c8b 100644 --- a/api/v1alpha1/helmrepository_types.go +++ b/api/v1alpha1/helmrepository_types.go @@ -17,6 +17,7 @@ limitations under the License. package v1alpha1 import ( + corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -83,3 +84,48 @@ const ( // of the given Helm repository succeeded. IndexationSucceededReason string = "IndexationSucceed" ) + +func HelmRepositoryReady(repository HelmRepository, artifact Artifact, url, reason, message string) HelmRepository { + repository.Status.Conditions = []SourceCondition{ + { + Type: ReadyCondition, + Status: corev1.ConditionTrue, + LastTransitionTime: metav1.Now(), + Reason: reason, + Message: message, + }, + } + repository.Status.URL = url + + if repository.Status.Artifact != nil { + if repository.Status.Artifact.Path != artifact.Path { + repository.Status.Artifact = &artifact + } + } else { + repository.Status.Artifact = &artifact + } + + return repository +} + +func HelmRepositoryNotReady(repository HelmRepository, reason, message string) HelmRepository { + repository.Status.Conditions = []SourceCondition{ + { + Type: ReadyCondition, + Status: corev1.ConditionFalse, + LastTransitionTime: metav1.Now(), + Reason: reason, + Message: message, + }, + } + return repository +} + +func HelmRepositoryReadyMessage(repository HelmRepository) string { + for _, condition := range repository.Status.Conditions { + if condition.Type == ReadyCondition { + return condition.Message + } + } + return "" +} diff --git a/controllers/conditions.go b/controllers/conditions.go deleted file mode 100644 index 13579aa9..00000000 --- a/controllers/conditions.go +++ /dev/null @@ -1,102 +0,0 @@ -/* -Copyright 2020 The Flux CD contributors. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -package controllers - -import ( - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - - sourcev1 "github.com/fluxcd/source-controller/api/v1alpha1" -) - -func ReadyCondition(reason, message string) sourcev1.SourceCondition { - return sourcev1.SourceCondition{ - Type: sourcev1.ReadyCondition, - Status: corev1.ConditionTrue, - LastTransitionTime: metav1.Now(), - Reason: reason, - Message: message, - } -} - -func NotReadyCondition(reason, message string) sourcev1.SourceCondition { - return sourcev1.SourceCondition{ - Type: sourcev1.ReadyCondition, - Status: corev1.ConditionFalse, - LastTransitionTime: metav1.Now(), - Reason: reason, - Message: message, - } -} - -func ReadyGitRepository(repository sourcev1.GitRepository, artifact sourcev1.Artifact, url, reason, message string) sourcev1.GitRepository { - repository.Status.Conditions = []sourcev1.SourceCondition{ReadyCondition(reason, message)} - repository.Status.URL = url - - if repository.Status.Artifact != nil { - if repository.Status.Artifact.Path != artifact.Path { - repository.Status.Artifact = &artifact - } - } else { - repository.Status.Artifact = &artifact - } - - return repository -} - -func NotReadyGitRepository(repository sourcev1.GitRepository, reason, message string) sourcev1.GitRepository { - repository.Status.Conditions = []sourcev1.SourceCondition{NotReadyCondition(reason, message)} - return repository -} - -func GitRepositoryReadyMessage(repository sourcev1.GitRepository) string { - for _, condition := range repository.Status.Conditions { - if condition.Type == sourcev1.ReadyCondition { - return condition.Message - } - } - return "" -} - -func ReadyHelmRepository(repository sourcev1.HelmRepository, artifact sourcev1.Artifact, url, reason, message string) sourcev1.HelmRepository { - repository.Status.Conditions = []sourcev1.SourceCondition{ReadyCondition(reason, message)} - repository.Status.URL = url - - if repository.Status.Artifact != nil { - if repository.Status.Artifact.Path != artifact.Path { - repository.Status.Artifact = &artifact - } - } else { - repository.Status.Artifact = &artifact - } - - return repository -} - -func NotReadyHelmRepository(repository sourcev1.HelmRepository, reason, message string) sourcev1.HelmRepository { - repository.Status.Conditions = []sourcev1.SourceCondition{NotReadyCondition(reason, message)} - return repository -} - -func HelmRepositoryReadyMessage(repository sourcev1.HelmRepository) string { - for _, condition := range repository.Status.Conditions { - if condition.Type == sourcev1.ReadyCondition { - return condition.Message - } - } - return "" -} diff --git a/controllers/gitrepository_controller.go b/controllers/gitrepository_controller.go index 21084c56..de225032 100644 --- a/controllers/gitrepository_controller.go +++ b/controllers/gitrepository_controller.go @@ -67,15 +67,13 @@ func (r *GitRepositoryReconciler) Reconcile(req ctrl.Request) (ctrl.Result, erro return ctrl.Result{}, client.IgnoreNotFound(err) } - result := ctrl.Result{RequeueAfter: repo.Spec.Interval.Duration} - // set initial status if reset, status := r.shouldResetStatus(repo); reset { log.Info("Initializing repository") repo.Status = status if err := r.Status().Update(ctx, &repo); err != nil { log.Error(err, "unable to update GitRepository status") - return result, err + return ctrl.Result{Requeue: true}, err } } @@ -91,13 +89,13 @@ func (r *GitRepositoryReconciler) Reconcile(req ctrl.Request) (ctrl.Result, erro // update status if err := r.Status().Update(ctx, &syncedRepo); err != nil { log.Error(err, "unable to update GitRepository status") - return result, err + return ctrl.Result{Requeue: true}, err } - log.Info("Repository sync succeeded", "msg", GitRepositoryReadyMessage(syncedRepo)) + log.Info("Repository sync succeeded", "msg", sourcev1.GitRepositoryReadyMessage(syncedRepo)) // requeue repository - return result, nil + return ctrl.Result{RequeueAfter: repo.Spec.Interval.Duration}, nil } func (r *GitRepositoryReconciler) SetupWithManager(mgr ctrl.Manager) error { @@ -151,21 +149,21 @@ func (r *GitRepositoryReconciler) sync(repository sourcev1.GitRepository) (sourc tmpSSH, err := ioutil.TempDir("", repository.Name) if err != nil { err = fmt.Errorf("tmp dir error: %w", err) - return NotReadyGitRepository(repository, sourcev1.StorageOperationFailedReason, err.Error()), err + return sourcev1.GitRepositoryNotReady(repository, sourcev1.StorageOperationFailedReason, err.Error()), err } defer os.RemoveAll(tmpSSH) auth, err := r.auth(repository, tmpSSH) if err != nil { err = fmt.Errorf("auth error: %w", err) - return NotReadyGitRepository(repository, sourcev1.StorageOperationFailedReason, err.Error()), err + return sourcev1.GitRepositoryNotReady(repository, sourcev1.StorageOperationFailedReason, err.Error()), err } // create tmp dir for the Git clone tmpGit, err := ioutil.TempDir("", repository.Name) if err != nil { err = fmt.Errorf("tmp dir error: %w", err) - return NotReadyGitRepository(repository, sourcev1.StorageOperationFailedReason, err.Error()), err + return sourcev1.GitRepositoryNotReady(repository, sourcev1.StorageOperationFailedReason, err.Error()), err } defer os.RemoveAll(tmpGit) @@ -184,7 +182,7 @@ func (r *GitRepositoryReconciler) sync(repository sourcev1.GitRepository) (sourc }) if err != nil { err = fmt.Errorf("git clone error: %w", err) - return NotReadyGitRepository(repository, sourcev1.GitOperationFailedReason, err.Error()), err + return sourcev1.GitRepositoryNotReady(repository, sourcev1.GitOperationFailedReason, err.Error()), err } // checkout commit or tag @@ -193,7 +191,7 @@ func (r *GitRepositoryReconciler) sync(repository sourcev1.GitRepository) (sourc w, err := repo.Worktree() if err != nil { err = fmt.Errorf("git worktree error: %w", err) - return NotReadyGitRepository(repository, sourcev1.GitOperationFailedReason, err.Error()), err + return sourcev1.GitRepositoryNotReady(repository, sourcev1.GitOperationFailedReason, err.Error()), err } err = w.Checkout(&git.CheckoutOptions{ @@ -202,19 +200,19 @@ func (r *GitRepositoryReconciler) sync(repository sourcev1.GitRepository) (sourc }) if err != nil { err = fmt.Errorf("git checkout %s for %s error: %w", commit, branch, err) - return NotReadyGitRepository(repository, sourcev1.GitOperationFailedReason, err.Error()), err + return sourcev1.GitRepositoryNotReady(repository, sourcev1.GitOperationFailedReason, err.Error()), err } } else if exp := repository.Spec.Reference.SemVer; exp != "" { rng, err := semver.ParseRange(exp) if err != nil { err = fmt.Errorf("semver parse range error: %w", err) - return NotReadyGitRepository(repository, sourcev1.GitOperationFailedReason, err.Error()), err + return sourcev1.GitRepositoryNotReady(repository, sourcev1.GitOperationFailedReason, err.Error()), err } repoTags, err := repo.Tags() if err != nil { err = fmt.Errorf("git list tags error: %w", err) - return NotReadyGitRepository(repository, sourcev1.GitOperationFailedReason, err.Error()), err + return sourcev1.GitRepositoryNotReady(repository, sourcev1.GitOperationFailedReason, err.Error()), err } tags := make(map[string]string) @@ -243,7 +241,7 @@ func (r *GitRepositoryReconciler) sync(repository sourcev1.GitRepository) (sourc w, err := repo.Worktree() if err != nil { err = fmt.Errorf("git worktree error: %w", err) - return NotReadyGitRepository(repository, sourcev1.GitOperationFailedReason, err.Error()), err + return sourcev1.GitRepositoryNotReady(repository, sourcev1.GitOperationFailedReason, err.Error()), err } err = w.Checkout(&git.CheckoutOptions{ @@ -251,11 +249,11 @@ func (r *GitRepositoryReconciler) sync(repository sourcev1.GitRepository) (sourc }) if err != nil { err = fmt.Errorf("git checkout error: %w", err) - return NotReadyGitRepository(repository, sourcev1.GitOperationFailedReason, err.Error()), err + return sourcev1.GitRepositoryNotReady(repository, sourcev1.GitOperationFailedReason, err.Error()), err } } else { err = fmt.Errorf("no match found for semver: %s", repository.Spec.Reference.SemVer) - return NotReadyGitRepository(repository, sourcev1.GitOperationFailedReason, err.Error()), err + return sourcev1.GitRepositoryNotReady(repository, sourcev1.GitOperationFailedReason, err.Error()), err } } } @@ -264,7 +262,7 @@ func (r *GitRepositoryReconciler) sync(repository sourcev1.GitRepository) (sourc ref, err := repo.Head() if err != nil { err = fmt.Errorf("git resolve HEAD error: %w", err) - return NotReadyGitRepository(repository, sourcev1.GitOperationFailedReason, err.Error()), err + return sourcev1.GitRepositoryNotReady(repository, sourcev1.GitOperationFailedReason, err.Error()), err } if revision == "" { @@ -278,14 +276,14 @@ func (r *GitRepositoryReconciler) sync(repository sourcev1.GitRepository) (sourc err = r.Storage.MkdirAll(artifact) if err != nil { err = fmt.Errorf("mkdir dir error: %w", err) - return NotReadyGitRepository(repository, sourcev1.StorageOperationFailedReason, err.Error()), err + return sourcev1.GitRepositoryNotReady(repository, sourcev1.StorageOperationFailedReason, err.Error()), err } // acquire lock unlock, err := r.Storage.Lock(artifact) if err != nil { err = fmt.Errorf("unable to acquire lock: %w", err) - return NotReadyGitRepository(repository, sourcev1.StorageOperationFailedReason, err.Error()), err + return sourcev1.GitRepositoryNotReady(repository, sourcev1.StorageOperationFailedReason, err.Error()), err } defer unlock() @@ -293,18 +291,18 @@ func (r *GitRepositoryReconciler) sync(repository sourcev1.GitRepository) (sourc err = r.Storage.Archive(artifact, tmpGit, "") if err != nil { err = fmt.Errorf("storage archive error: %w", err) - return NotReadyGitRepository(repository, sourcev1.StorageOperationFailedReason, err.Error()), err + return sourcev1.GitRepositoryNotReady(repository, sourcev1.StorageOperationFailedReason, err.Error()), err } // update latest symlink url, err := r.Storage.Symlink(artifact, "latest.tar.gz") if err != nil { err = fmt.Errorf("storage lock error: %w", err) - return NotReadyGitRepository(repository, sourcev1.StorageOperationFailedReason, err.Error()), err + return sourcev1.GitRepositoryNotReady(repository, sourcev1.StorageOperationFailedReason, err.Error()), err } message := fmt.Sprintf("Artifact is available at: %s", artifact.Path) - return ReadyGitRepository(repository, artifact, url, sourcev1.GitOperationSucceedReason, message), nil + return sourcev1.GitRepositoryReady(repository, artifact, url, sourcev1.GitOperationSucceedReason, message), nil } func (r *GitRepositoryReconciler) shouldResetStatus(repository sourcev1.GitRepository) (bool, sourcev1.GitRepositoryStatus) { diff --git a/controllers/helmrepository_controller.go b/controllers/helmrepository_controller.go index 6954e4cf..5b52d81b 100644 --- a/controllers/helmrepository_controller.go +++ b/controllers/helmrepository_controller.go @@ -63,15 +63,13 @@ func (r *HelmRepositoryReconciler) Reconcile(req ctrl.Request) (ctrl.Result, err return ctrl.Result{}, client.IgnoreNotFound(err) } - result := ctrl.Result{RequeueAfter: repository.Spec.Interval.Duration} - // set initial status if reset, status := r.shouldResetStatus(repository); reset { log.Info("Initializing repository") repository.Status = status if err := r.Status().Update(ctx, &repository); err != nil { log.Error(err, "unable to update HelmRepository status") - return result, err + return ctrl.Result{Requeue: true}, err } } @@ -87,13 +85,13 @@ func (r *HelmRepositoryReconciler) Reconcile(req ctrl.Request) (ctrl.Result, err // update status if err := r.Status().Update(ctx, &syncedRepo); err != nil { log.Error(err, "unable to update HelmRepository status") - return result, err + return ctrl.Result{Requeue: true}, err } - log.Info("Repository sync succeeded", "msg", HelmRepositoryReadyMessage(syncedRepo)) + log.Info("Repository sync succeeded", "msg", sourcev1.HelmRepositoryReadyMessage(syncedRepo)) // requeue repository - return result, nil + return ctrl.Result{RequeueAfter: repository.Spec.Interval.Duration}, nil } func (r *HelmRepositoryReconciler) SetupWithManager(mgr ctrl.Manager) error { @@ -120,12 +118,12 @@ func (r *HelmRepositoryReconciler) SetupWithManager(mgr ctrl.Manager) error { func (r *HelmRepositoryReconciler) sync(repository sourcev1.HelmRepository) (sourcev1.HelmRepository, error) { u, err := url.Parse(repository.Spec.URL) if err != nil { - return NotReadyHelmRepository(repository, sourcev1.URLInvalidReason, err.Error()), err + return sourcev1.HelmRepositoryNotReady(repository, sourcev1.URLInvalidReason, err.Error()), err } c, err := r.Getters.ByScheme(u.Scheme) if err != nil { - return NotReadyHelmRepository(repository, sourcev1.URLInvalidReason, err.Error()), err + return sourcev1.HelmRepositoryNotReady(repository, sourcev1.URLInvalidReason, err.Error()), err } u.RawPath = path.Join(u.RawPath, "index.yaml") @@ -135,22 +133,22 @@ func (r *HelmRepositoryReconciler) sync(repository sourcev1.HelmRepository) (sou // TODO(hidde): add authentication config res, err := c.Get(indexURL, getter.WithURL(repository.Spec.URL)) if err != nil { - return NotReadyHelmRepository(repository, sourcev1.IndexationFailedReason, err.Error()), err + return sourcev1.HelmRepositoryNotReady(repository, sourcev1.IndexationFailedReason, err.Error()), err } data, err := ioutil.ReadAll(res) if err != nil { - return NotReadyHelmRepository(repository, sourcev1.IndexationFailedReason, err.Error()), err + return sourcev1.HelmRepositoryNotReady(repository, sourcev1.IndexationFailedReason, err.Error()), err } i := &repo.IndexFile{} if err := yaml.Unmarshal(data, i); err != nil { - return NotReadyHelmRepository(repository, sourcev1.IndexationFailedReason, err.Error()), err + return sourcev1.HelmRepositoryNotReady(repository, sourcev1.IndexationFailedReason, err.Error()), err } index, err := yaml.Marshal(i) if err != nil { - return NotReadyHelmRepository(repository, sourcev1.IndexationFailedReason, err.Error()), err + return sourcev1.HelmRepositoryNotReady(repository, sourcev1.IndexationFailedReason, err.Error()), err } sum := r.Storage.Checksum(index) @@ -161,14 +159,14 @@ func (r *HelmRepositoryReconciler) sync(repository sourcev1.HelmRepository) (sou err = r.Storage.MkdirAll(artifact) if err != nil { err = fmt.Errorf("unable to create repository index directory: %w", err) - return NotReadyHelmRepository(repository, sourcev1.StorageOperationFailedReason, err.Error()), err + return sourcev1.HelmRepositoryNotReady(repository, sourcev1.StorageOperationFailedReason, err.Error()), err } // acquire lock unlock, err := r.Storage.Lock(artifact) if err != nil { err = fmt.Errorf("unable to acquire lock: %w", err) - return NotReadyHelmRepository(repository, sourcev1.StorageOperationFailedReason, err.Error()), err + return sourcev1.HelmRepositoryNotReady(repository, sourcev1.StorageOperationFailedReason, err.Error()), err } defer unlock() @@ -176,18 +174,18 @@ func (r *HelmRepositoryReconciler) sync(repository sourcev1.HelmRepository) (sou err = r.Storage.WriteFile(artifact, index) if err != nil { err = fmt.Errorf("unable to write repository index file: %w", err) - return NotReadyHelmRepository(repository, sourcev1.StorageOperationFailedReason, err.Error()), err + return sourcev1.HelmRepositoryNotReady(repository, sourcev1.StorageOperationFailedReason, err.Error()), err } // update index symlink indexUrl, err := r.Storage.Symlink(artifact, "index.yaml") if err != nil { err = fmt.Errorf("storage error %w", err) - return NotReadyHelmRepository(repository, sourcev1.StorageOperationFailedReason, err.Error()), err + return sourcev1.HelmRepositoryNotReady(repository, sourcev1.StorageOperationFailedReason, err.Error()), err } message := fmt.Sprintf("Index is available at %s", artifact.Path) - return ReadyHelmRepository(repository, artifact, indexUrl, sourcev1.IndexationSucceededReason, message), nil + return sourcev1.HelmRepositoryReady(repository, artifact, indexUrl, sourcev1.IndexationSucceededReason, message), nil } func (r *HelmRepositoryReconciler) shouldResetStatus(repository sourcev1.HelmRepository) (bool, sourcev1.HelmRepositoryStatus) {