Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

THREESCALE-11633 fix application controller nil pointer #1065

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
37 changes: 33 additions & 4 deletions controllers/capabilities/application_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,16 @@ func (r *ApplicationReconciler) Reconcile(ctx context.Context, req ctrl.Request)
err = r.Client().Get(r.Context(), projectMeta, accountResource)
if err != nil {
if apierrors.IsNotFound(err) {
// If the application CR is marked for deletion and the dev account associated doesn't exist, remove the application CR since there is nothing else to do with application.
if application.GetDeletionTimestamp() != nil && controllerutil.ContainsFinalizer(application, applicationFinalizer) {
controllerutil.RemoveFinalizer(application, applicationFinalizer)
err = r.UpdateResource(application)
if err != nil {
return ctrl.Result{}, err
}

return ctrl.Result{}, nil
}
reqLogger.Error(err, "error developer account not found ")
statusReconciler := NewApplicationStatusReconciler(r.BaseReconciler, application, nil, "", err)
statusResult, statusUpdateErr := statusReconciler.Reconcile()
Expand All @@ -97,13 +107,14 @@ func (r *ApplicationReconciler) Reconcile(ctx context.Context, req ctrl.Request)
return ctrl.Result{}, fmt.Errorf("Failed to reconcile application: %v. Failed to update application status: %w", err, statusUpdateErr)
}

return ctrl.Result{}, fmt.Errorf("Failed to update applicatino status: %w", statusUpdateErr)
return ctrl.Result{}, fmt.Errorf("Failed to update application status: %w", statusUpdateErr)
}
if statusResult.Requeue {
return statusResult, nil
}
}
}

// get providerAccountRef from account
providerAccount, err := controllerhelper.LookupProviderAccount(r.Client(), accountResource.Namespace, accountResource.Spec.ProviderAccountRef, r.Logger())
if err != nil {
Expand Down Expand Up @@ -138,7 +149,11 @@ func (r *ApplicationReconciler) Reconcile(ctx context.Context, req ctrl.Request)
return ctrl.Result{}, nil
}

metadataUpdated := r.reconcileMetadata(application)
metadataUpdated, err := r.reconcileMetadata(application, accountResource)
if err != nil {
r.EventRecorder().Eventf(application, corev1.EventTypeWarning, "Failed to update ownerReferences in application", "%v", err)
return ctrl.Result{}, err
}
if metadataUpdated {
err = r.UpdateResource(application)
if err != nil {
Expand Down Expand Up @@ -187,7 +202,7 @@ func (r *ApplicationReconciler) Reconcile(ctx context.Context, req ctrl.Request)
return ctrl.Result{}, nil
}

func (r *ApplicationReconciler) reconcileMetadata(application *capabilitiesv1beta1.Application) bool {
func (r *ApplicationReconciler) reconcileMetadata(application *capabilitiesv1beta1.Application, developerAccount *capabilitiesv1beta1.DeveloperAccount) (bool, error) {
changed := false

// If the application.Status.ID is found and the annotation is not found - create
Expand All @@ -209,7 +224,16 @@ func (r *ApplicationReconciler) reconcileMetadata(application *capabilitiesv1bet
changed = true
}

return changed
// Add ownerRef of associated account CR, this is done because application CR can't exist without associated dev account. Therefore, if dev account is removed, the application CR should also be removed
if !r.HasOwnerReference(developerAccount, application) {
updated, err := r.EnsureOwnerReference(developerAccount, application)
if err != nil {
return false, err
}
changed = changed || updated
}

return changed, nil
}

func (r *ApplicationReconciler) applicationReconciler(applicationResource *capabilitiesv1beta1.Application, req ctrl.Request, threescaleAPIClient *threescaleapi.ThreeScaleClient, providerAccountAdminURLStr string, accountResource *capabilitiesv1beta1.DeveloperAccount) (*ApplicationStatusReconciler, error) {
Expand Down Expand Up @@ -268,6 +292,11 @@ func (r *ApplicationReconciler) removeApplicationFrom3scale(application *capabil
return nil
}

if account.Status.ID == nil {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will this throw a nil pointer if account.Status is nil?

Suggested change
if account.Status.ID == nil {
if account.Status != nil && account.Status.ID == nil {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, following the verification steps you will get to try it out as we are adding the account CRs back on to the cluster but without the status.

logger.Info("could not remove application because ID is missing in the status of developer account")
return fmt.Errorf("could not remove application because ID is missing in the satus of developer account %s", account.Name)
}

err = threescaleAPIClient.DeleteApplication(*account.Status.ID, *application.Status.ID)
if err != nil && !threescaleapi.IsNotFound(err) {
return err
Expand Down
10 changes: 10 additions & 0 deletions pkg/reconcilers/base_reconciler.go
Original file line number Diff line number Diff line change
Expand Up @@ -275,3 +275,13 @@ func resourceExists(dc discovery.DiscoveryInterface, groupVersion, kind string)

return false, nil
}

// HasOwnerReference checks if the given owner is already present in the object's OwnerReferences.
func (b *BaseReconciler) HasOwnerReference(owner, obj common.KubernetesObject) bool {
for _, ref := range obj.GetOwnerReferences() {
if ref.UID == owner.GetUID() {
return true
}
}
return false
}