Skip to content

Commit

Permalink
map kapp conditions to Extension
Browse files Browse the repository at this point in the history
Signed-off-by: Ankita Thomas <ankithom@redhat.com>
  • Loading branch information
ankitathomas committed Mar 11, 2024
1 parent 6865e1d commit 3157a50
Show file tree
Hide file tree
Showing 4 changed files with 385 additions and 30 deletions.
4 changes: 4 additions & 0 deletions api/v1alpha1/clusterextension_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ const (
ReasonResolutionUnknown = "ResolutionUnknown"
ReasonSuccess = "Success"
ReasonDeprecated = "Deprecated"
ReasonDeleteFailed = "DeleteFailed"
ReasonDeleting = "Deleting"
)

func init() {
Expand All @@ -116,6 +118,8 @@ func init() {
ReasonInvalidSpec,
ReasonSuccess,
ReasonDeprecated,
ReasonDeleteFailed,
ReasonDeleting,
)
}

Expand Down
22 changes: 22 additions & 0 deletions internal/controllers/common_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,28 @@ func setInstalledStatusConditionFailed(conditions *[]metav1.Condition, message s
})
}

// setInstalledStatusConditionDeleting sets the installed status condition to unknown for deletes in progress.
func setInstalledStatusConditionDeleting(conditions *[]metav1.Condition, message string, generation int64) {
apimeta.SetStatusCondition(conditions, metav1.Condition{
Type: ocv1alpha1.TypeInstalled,
Status: metav1.ConditionUnknown,
Reason: ocv1alpha1.ReasonDeleting,
Message: message,
ObservedGeneration: generation,
})
}

// setInstalledStatusConditionDeleteFailed sets the installed status condition to unknown for failed deletes.
func setInstalledStatusConditionDeleteFailed(conditions *[]metav1.Condition, message string, generation int64) {
apimeta.SetStatusCondition(conditions, metav1.Condition{
Type: ocv1alpha1.TypeInstalled,
Status: metav1.ConditionUnknown,
Reason: ocv1alpha1.ReasonDeleteFailed,
Message: message,
ObservedGeneration: generation,
})
}

// setDEprecationStatusesUnknown sets the deprecation status conditions to unknown.
func setDeprecationStatusesUnknown(conditions *[]metav1.Condition, message string, generation int64) {
conditionTypes := []string{
Expand Down
83 changes: 53 additions & 30 deletions internal/controllers/extension_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ func (r *ExtensionReconciler) reconcile(ctx context.Context, ext *ocv1alpha1.Ext
return ctrl.Result{}, err
}

mapAppStatusToInstalledCondition(existingTypedApp, ext, bundle.Image)
MapAppStatusToCondition(existingTypedApp, ext, bundle.Image)
SetDeprecationStatusInExtension(ext, bundle)

return ctrl.Result{}, nil
Expand All @@ -231,30 +231,64 @@ func (r *ExtensionReconciler) SetupWithManager(mgr ctrl.Manager) error {
Complete(r)
}

// TODO: follow up with mapping of all the available App statuses: https://github.com/carvel-dev/kapp-controller/blob/855063edee53315811a13ee8d5df1431ba258ede/pkg/apis/kappctrl/v1alpha1/status.go#L28-L35
// mapAppStatusToInstalledCondition currently maps only the installed condition.
func mapAppStatusToInstalledCondition(existingApp *kappctrlv1alpha1.App, ext *ocv1alpha1.Extension, bundleImage string) {
appReady := findStatusCondition(existingApp.Status.GenericStatus.Conditions, kappctrlv1alpha1.ReconcileSucceeded)
if appReady == nil {
ext.Status.InstalledBundleResource = ""
setInstalledStatusConditionUnknown(&ext.Status.Conditions, "install status unknown", ext.Generation)
// mapAppStatusToCondition maps the reconciling/deleting App conditions to the installed/deleting conditions on the Extension.
func MapAppStatusToCondition(existingApp *kappctrlv1alpha1.App, ext *ocv1alpha1.Extension, bundleImage string) {
if ext == nil {
return
}
message := "install status unknown"
ext.Status.InstalledBundleResource = ""

if appReady.Status != corev1.ConditionTrue {
ext.Status.InstalledBundleResource = ""
setInstalledStatusConditionFailed(
&ext.Status.Conditions,
appReady.Message,
ext.GetGeneration(),
)
if existingApp == nil {
setInstalledStatusConditionUnknown(&ext.Status.Conditions, message, ext.Generation)
return
}
message = existingApp.Status.FriendlyDescription
if strings.Contains(message, "Error (see .status.usefulErrorMessage for details)") || len(message) == 0 {
message = existingApp.Status.UsefulErrorMessage
}

orderedAppStatuses := []kappctrlv1alpha1.ConditionType{
kappctrlv1alpha1.DeleteFailed,
kappctrlv1alpha1.Deleting,
kappctrlv1alpha1.ReconcileSucceeded,
kappctrlv1alpha1.ReconcileFailed,
kappctrlv1alpha1.Reconciling,
}
appStatusMapFn := map[kappctrlv1alpha1.ConditionType]func(*[]metav1.Condition, string, int64){
kappctrlv1alpha1.DeleteFailed: setInstalledStatusConditionDeleteFailed,
kappctrlv1alpha1.Deleting: setInstalledStatusConditionDeleting,
kappctrlv1alpha1.ReconcileSucceeded: setInstalledStatusConditionSuccess,
kappctrlv1alpha1.ReconcileFailed: setInstalledStatusConditionFailed,
kappctrlv1alpha1.Reconciling: setInstalledStatusConditionUnknown,
}
for _, cond := range orderedAppStatuses {
if c := findStatusCondition(existingApp.Status.GenericStatus.Conditions, cond); c != nil && c.Status == corev1.ConditionTrue {
if len(message) == 0 {
message = c.Message
}
if c.Type == kappctrlv1alpha1.ReconcileSucceeded {
ext.Status.InstalledBundleResource = bundleImage
}
appStatusMapFn[cond](&ext.Status.Conditions, message, ext.Generation)
return
}
}
if len(message) == 0 {
message = "install status unknown"
}
setInstalledStatusConditionUnknown(&ext.Status.Conditions, message, ext.Generation)
}

// InstalledBundleResource this should be converted into a slice as App allows fetching
// from multiple sources.
ext.Status.InstalledBundleResource = bundleImage
setInstalledStatusConditionSuccess(&ext.Status.Conditions, appReady.Message, ext.Generation)
// findStatusCondition finds the conditionType in conditions.
// TODO: suggest using upstream conditions to Carvel.
func findStatusCondition(conditions []kappctrlv1alpha1.Condition, conditionType kappctrlv1alpha1.ConditionType) *kappctrlv1alpha1.Condition {
for i := range conditions {
if conditions[i].Type == conditionType {
return &conditions[i]
}
}
return nil
}

// setDeprecationStatus will set the appropriate deprecation statuses for a Extension
Expand Down Expand Up @@ -339,17 +373,6 @@ func SetDeprecationStatusInExtension(ext *ocv1alpha1.Extension, bundle *catalogm
}
}

// findStatusCondition finds the conditionType in conditions.
// TODO: suggest using upstream conditions to Carvel.
func findStatusCondition(conditions []kappctrlv1alpha1.Condition, conditionType kappctrlv1alpha1.ConditionType) *kappctrlv1alpha1.Condition {
for i := range conditions {
if conditions[i].Type == conditionType {
return &conditions[i]
}
}
return nil
}

func (r *ExtensionReconciler) ensureApp(ctx context.Context, desiredApp *unstructured.Unstructured) error {
existingApp, err := r.existingAppUnstructured(ctx, desiredApp.GetName(), desiredApp.GetNamespace())
if client.IgnoreNotFound(err) != nil {
Expand Down
Loading

0 comments on commit 3157a50

Please sign in to comment.