github.com/verrazzano/verrazzano@v1.7.0/platform-operator/controllers/module/component-handler/common/vzcomponent_status.go (about) 1 // Copyright (c) 2023, Oracle and/or its affiliates. 2 // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. 3 4 package common 5 6 import ( 7 "context" 8 "fmt" 9 "github.com/verrazzano/verrazzano-modules/pkg/controller/result" 10 "github.com/verrazzano/verrazzano-modules/pkg/controller/spi/handlerspi" 11 vzapi "github.com/verrazzano/verrazzano/platform-operator/apis/verrazzano/v1alpha1" 12 corev1 "k8s.io/api/core/v1" 13 "k8s.io/apimachinery/pkg/api/errors" 14 "k8s.io/apimachinery/pkg/types" 15 "time" 16 ) 17 18 // StatusData contains the data for the component status field 19 type StatusData struct { 20 Vznsn types.NamespacedName 21 CondType vzapi.ConditionType 22 CompName string 23 CompVersion string 24 Msg string 25 Ready bool 26 } 27 28 // UpdateVerrazzanoComponentStatusToDisabled updates the component status to disabled 29 func UpdateVerrazzanoComponentStatusToDisabled(ctx handlerspi.HandlerContext, Vznsn types.NamespacedName, compName string) result.Result { 30 // Always get the latest module from the controller-runtime cache to try and avoid conflict error 31 vzcr := &vzapi.Verrazzano{} 32 if err := ctx.Client.Get(context.TODO(), Vznsn, vzcr); err != nil { 33 ctx.Log.Progress("Failed getting Verrazzano CR, retrying...") 34 return result.NewResultShortRequeueDelay() 35 } 36 if vzcr.Status.Components == nil { 37 vzcr.Status.Components = vzapi.ComponentStatusMap{} 38 } 39 compStatus := &vzapi.ComponentStatusDetails{ 40 Name: compName, 41 State: vzapi.CompStateDisabled, 42 } 43 vzcr.Status.Components[compName] = compStatus 44 45 if err := ctx.Client.Status().Update(context.TODO(), vzcr); err != nil { 46 if !errors.IsConflict(err) { 47 ctx.Log.Progress("Failed to update Verrazzano component status, retrying: %v", err) 48 } 49 return result.NewResultShortRequeueDelay() 50 } 51 return result.NewResult() 52 } 53 54 // UpdateVerrazzanoComponentStatus updates the Verrazzano component status 55 func UpdateVerrazzanoComponentStatus(ctx handlerspi.HandlerContext, sd StatusData) result.Result { 56 // Always get the latest module from the controller-runtime cache to try and avoid conflict error 57 vzcr := &vzapi.Verrazzano{} 58 if err := ctx.Client.Get(context.TODO(), sd.Vznsn, vzcr); err != nil { 59 ctx.Log.Progress("Failed getting Verrazzano CR, retrying...") 60 return result.NewResultShortRequeueDelay() 61 } 62 if vzcr.Status.Components == nil { 63 vzcr.Status.Components = vzapi.ComponentStatusMap{} 64 } 65 compStatus := vzcr.Status.Components[sd.CompName] 66 if compStatus == nil { 67 compStatus = &vzapi.ComponentStatusDetails{ 68 Available: getAvailPtr(vzapi.ComponentUnavailable), 69 LastReconciledGeneration: 0, 70 Name: sd.CompName, 71 State: vzapi.CompStateUninstalled, 72 } 73 vzcr.Status.Components[sd.CompName] = compStatus 74 } 75 if sd.Ready { 76 compStatus.Available = getAvailPtr(vzapi.ComponentAvailable) 77 compStatus.State = vzapi.CompStateReady 78 compStatus.LastReconciledGeneration = vzcr.Generation 79 compStatus.Version = sd.CompVersion 80 } else { 81 compStatus.State = vzapi.CompStateReconciling 82 } 83 84 // Append or replace the condition 85 cond := vzapi.Condition{ 86 Type: sd.CondType, 87 Status: corev1.ConditionTrue, 88 Message: sd.Msg, 89 } 90 addOrReplaceCondition(compStatus, cond) 91 92 if err := ctx.Client.Status().Update(context.TODO(), vzcr); err != nil { 93 if !errors.IsConflict(err) { 94 ctx.Log.Progress("Failed to update Verrazzano component status, retrying: %v", err) 95 } 96 return result.NewResultShortRequeueDelay() 97 } 98 return result.NewResult() 99 } 100 101 // addOrReplaceCondition appends the condition to the list of conditions. 102 // if the condition already exists, then remove it 103 func addOrReplaceCondition(compStatus *vzapi.ComponentStatusDetails, cond vzapi.Condition) { 104 cond.LastTransitionTime = getCurrentTime() 105 106 // Copy conditions that have a different type than the input condition into a new list 107 var newConditions []vzapi.Condition 108 if compStatus.Conditions != nil { 109 for i, existing := range compStatus.Conditions { 110 if existing.Type != cond.Type { 111 newConditions = append(newConditions, compStatus.Conditions[i]) 112 } 113 } 114 } 115 116 // Always put the new condition at the end of the list since the kubectl status display and 117 // some upgrade stuff depends on the most recent condition being the last one 118 compStatus.Conditions = append(newConditions, cond) 119 } 120 121 func getCurrentTime() string { 122 t := time.Now().UTC() 123 return fmt.Sprintf("%d-%02d-%02dT%02d:%02d:%02dZ", 124 t.Year(), t.Month(), t.Day(), t.Hour(), t.Minute(), t.Second()) 125 } 126 127 func getAvailPtr(avail vzapi.ComponentAvailability) *vzapi.ComponentAvailability { 128 return &avail 129 }