Skip to content

Commit

Permalink
Merge pull request #91 from mittwald/task/readiness-wait
Browse files Browse the repository at this point in the history
Wait for some resources to become ready
  • Loading branch information
elenz97 authored Dec 10, 2021
2 parents 3ee24d8 + 1828aa7 commit 8fd1dfd
Show file tree
Hide file tree
Showing 4 changed files with 138 additions and 12 deletions.
84 changes: 80 additions & 4 deletions controllers/registries/project_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import (
"fmt"
"time"

controllererrors "github.com/mittwald/harbor-operator/controllers/registries/errors"

clienterrors "github.com/mittwald/goharbor-client/v5/apiv2/pkg/errors"
"sigs.k8s.io/controller-runtime/pkg/controller"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
Expand Down Expand Up @@ -53,6 +55,11 @@ type ProjectReconciler struct {
Scheme *runtime.Scheme
}

var (
RegistryNotReadyError string = "RegistryNotReady"
UserNotReadyError string = "UserNotReady"
)

// +kubebuilder:rbac:groups=registries.mittwald.de,resources=projects,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=registries.mittwald.de,resources=projects/status,verbs=get;update;patch

Expand Down Expand Up @@ -93,16 +100,26 @@ func (r *ProjectReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct
Name: project.Spec.ParentInstance.Name,
}, r.Client)
if err != nil {
controllerutil.RemoveFinalizer(project, internal.FinalizerName)

return ctrl.Result{}, err
switch err.Error() {
case controllererrors.ErrInstanceNotInstalledMsg:
reqLogger.Info("waiting till harbor instance is installed")
return ctrl.Result{RequeueAfter: 30 * time.Second}, nil
case controllererrors.ErrInstanceNotFoundMsg:
controllerutil.RemoveFinalizer(project, internal.FinalizerName)
fallthrough
default:
return ctrl.Result{}, err
}
}

// Set OwnerReference to the parent harbor instance
err = ctrl.SetControllerReference(harbor, project, r.Scheme)
if err != nil {
return ctrl.Result{}, err
}
if err := r.Client.Status().Patch(ctx, project, patch); err != nil {
return ctrl.Result{}, err
}

// Build a client to connect to the harbor API
harborClient, err := internal.BuildClient(ctx, r.Client, harbor)
Expand All @@ -113,7 +130,22 @@ func (r *ProjectReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ct
// Check the Harbor API if it's reporting as healthy
err = internal.AssertHealthyHarborInstance(ctx, harborClient)
if err != nil {
return ctrl.Result{RequeueAfter: 10 * time.Second}, err
reqLogger.Info("waiting till harbor instance is healthy")
return ctrl.Result{RequeueAfter: 30 * time.Second}, nil
}

if err := r.assertProxyCacheRequirementsReady(ctx, harborClient, project, reqLogger); err != nil {
if err.Error() == RegistryNotReadyError {
return ctrl.Result{RequeueAfter: 30 * time.Second}, nil
}
return ctrl.Result{}, err
}

if err := r.assertUserRequirementsReady(ctx, project, reqLogger); err != nil {
if err.Error() == UserNotReadyError {
return ctrl.Result{RequeueAfter: 30 * time.Second}, nil
}
return ctrl.Result{}, err
}

switch project.Status.Phase {
Expand Down Expand Up @@ -167,6 +199,50 @@ func (r *ProjectReconciler) SetupWithManager(mgr ctrl.Manager) error {
Complete(r)
}

func (r *ProjectReconciler) assertProxyCacheRequirementsReady(ctx context.Context, harborClient *h.RESTClient, project *v1alpha2.Project, logger logr.Logger) error {
if project.Spec.ProxyCache == nil || project.Spec.ProxyCache.Registry == nil {
return nil
}

regName := project.Spec.ProxyCache.Registry.Name
l := logger.WithValues("registry", regName)
registry := &v1alpha2.Registry{}
if err := r.Client.Get(ctx, client.ObjectKey{Name: regName, Namespace: project.Namespace}, registry); err != nil {
l.Error(err, "could not find proxy-cache registry")
return err
}

_, err := harborClient.GetRegistryByName(ctx, registry.Spec.Name)
if err != nil {
l.Error(err, "waiting till registry is ready")
return errors.New(RegistryNotReadyError)
}

return nil
}

func (r *ProjectReconciler) assertUserRequirementsReady(ctx context.Context, project *v1alpha2.Project, logger logr.Logger) error {
if len(project.Spec.MemberRequests) == 0 {
return nil
}

for _, req := range project.Spec.MemberRequests {
l := logger.WithValues("user", req.User.Name)
user := &v1alpha2.User{}
if err := r.Client.Get(ctx, client.ObjectKey{Name: req.User.Name, Namespace: project.Namespace}, user); err != nil {
l.Error(err, "user not found")
return err
}

if user.Status.Phase != v1alpha2.UserStatusPhaseReady {
l.Info("user not ready")
return errors.New(UserNotReadyError)
}
}

return nil
}

// assertDeletedProject deletes a Harbor project, first ensuring its existence.
func (r *ProjectReconciler) assertDeletedProject(ctx context.Context, log logr.Logger, harborClient *h.RESTClient,
project *v1alpha2.Project) error {
Expand Down
25 changes: 22 additions & 3 deletions controllers/registries/registry_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"context"
"errors"
"fmt"
controllererrors "github.com/mittwald/harbor-operator/controllers/registries/errors"
"net/url"
"reflect"
"time"
Expand Down Expand Up @@ -90,8 +91,25 @@ func (r *RegistryReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c
Name: registry.Spec.ParentInstance.Name,
}, r.Client)
if err != nil {
controllerutil.RemoveFinalizer(registry, internal.FinalizerName)
return ctrl.Result{}, r.Client.Status().Patch(ctx, registry, patch)
switch err.Error() {
case controllererrors.ErrInstanceNotInstalledMsg:
reqLogger.Info("waiting till harbor instance is installed")
return ctrl.Result{RequeueAfter: 30*time.Second}, nil
case controllererrors.ErrInstanceNotFoundMsg:
controllerutil.RemoveFinalizer(registry, internal.FinalizerName)
fallthrough
default:
return ctrl.Result{}, err
}
}

// Set OwnerReference to the parent harbor instance
err = ctrl.SetControllerReference(harbor, registry, r.Scheme)
if err != nil {
return ctrl.Result{}, err
}
if err := r.Client.Status().Patch(ctx, registry, patch); err != nil {
return ctrl.Result{}, err
}

// Build a client to connect to the harbor API
Expand All @@ -103,7 +121,8 @@ func (r *RegistryReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c
// Check the Harbor API if it's reporting as healthy
err = internal.AssertHealthyHarborInstance(ctx, harborClient)
if err != nil {
return ctrl.Result{RequeueAfter: 10 * time.Second}, err
reqLogger.Info("waiting till harbor instance is healthy")
return ctrl.Result{RequeueAfter: 30 * time.Second}, nil
}

switch registry.Status.Phase {
Expand Down
22 changes: 20 additions & 2 deletions controllers/registries/replication_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"context"
"errors"
"fmt"
controllererrors "github.com/mittwald/harbor-operator/controllers/registries/errors"
"reflect"
"time"

Expand Down Expand Up @@ -86,8 +87,24 @@ func (r *ReplicationReconciler) Reconcile(ctx context.Context, req ctrl.Request)
Name: replication.Spec.ParentInstance.Name,
}, r.Client)
if err != nil {
controllerutil.RemoveFinalizer(replication, internal.FinalizerName)
switch err.Error() {
case controllererrors.ErrInstanceNotInstalledMsg:
reqLogger.Info("waiting till harbor instance is installed")
return ctrl.Result{RequeueAfter: 30*time.Second}, nil
case controllererrors.ErrInstanceNotFoundMsg:
controllerutil.RemoveFinalizer(replication, internal.FinalizerName)
fallthrough
default:
return ctrl.Result{}, err
}
}

// Set OwnerReference to the parent harbor instance
err = ctrl.SetControllerReference(harbor, replication, r.Scheme)
if err != nil {
return ctrl.Result{}, err
}
if err := r.Client.Status().Patch(ctx, replication, patch); err != nil {
return ctrl.Result{}, err
}

Expand All @@ -100,7 +117,8 @@ func (r *ReplicationReconciler) Reconcile(ctx context.Context, req ctrl.Request)
// Check the Harbor API if it's reporting as healthy
err = internal.AssertHealthyHarborInstance(ctx, harborClient)
if err != nil {
return ctrl.Result{}, err
reqLogger.Info("waiting till harbor instance is healthy")
return ctrl.Result{RequeueAfter: 30*time.Second}, nil
}

switch replication.Status.Phase {
Expand Down
19 changes: 16 additions & 3 deletions controllers/registries/user_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package registries
import (
"context"
"errors"
controllererrors "github.com/mittwald/harbor-operator/controllers/registries/errors"
"time"

"github.com/mittwald/goharbor-client/v5/apiv2/model"
Expand Down Expand Up @@ -104,15 +105,26 @@ func (r *UserReconciler) Reconcile(ctx context.Context, req ctrl.Request) (res c
Name: user.Spec.ParentInstance.Name,
}, r.Client)
if err != nil {
controllerutil.RemoveFinalizer(user, internal.FinalizerName)
return ctrl.Result{}, r.Client.Patch(ctx, user, patch)
switch err.Error() {
case controllererrors.ErrInstanceNotInstalledMsg:
reqLogger.Info("waiting till harbor instance is installed")
return ctrl.Result{RequeueAfter: 30*time.Second}, nil
case controllererrors.ErrInstanceNotFoundMsg:
controllerutil.RemoveFinalizer(user, internal.FinalizerName)
fallthrough
default:
return ctrl.Result{}, err
}
}

// Set OwnerReference to the parent harbor instance
err = ctrl.SetControllerReference(harbor, user, r.Scheme)
if err != nil {
return ctrl.Result{}, err
}
if err := r.Client.Status().Patch(ctx, user, patch); err != nil {
return ctrl.Result{}, err
}

// Build a client to connect to the harbor API
harborClient, err := internal.BuildClient(ctx, r.Client, harbor)
Expand All @@ -123,7 +135,8 @@ func (r *UserReconciler) Reconcile(ctx context.Context, req ctrl.Request) (res c
// Check the Harbor API if it's reporting as healthy
err = internal.AssertHealthyHarborInstance(ctx, harborClient)
if err != nil {
return ctrl.Result{RequeueAfter: 10 * time.Second}, err
reqLogger.Info("waiting till harbor instance is healthy")
return ctrl.Result{RequeueAfter: 30 * time.Second}, nil
}

// Handle user reconciliation
Expand Down

0 comments on commit 8fd1dfd

Please sign in to comment.