Skip to content
Merged
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
1 change: 1 addition & 0 deletions backend/pkg/app/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,7 @@ func (b *Backend) runBackendControllersUnderLeaderElection(ctx context.Context,
b.options.ClustersServiceClient,
http.DefaultClient,
activeOperationInformer,
backendInformers,
)
operationClusterUpdateController := operationcontrollers.NewOperationClusterUpdateController(
b.options.CosmosDBClient,
Expand Down
26 changes: 26 additions & 0 deletions backend/pkg/controllers/controllerutils/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import (
"github.com/go-logr/logr"

"k8s.io/apimachinery/pkg/api/equality"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
utilsclock "k8s.io/utils/clock"

azcorearm "github.com/Azure/azure-sdk-for-go/sdk/azcore/arm"
Expand Down Expand Up @@ -310,6 +312,30 @@ func SetCondition(conditions *[]api.Condition, toSet api.Condition) {
}
}

func SetMetaV1Condition(conditions *[]metav1.Condition, toSet metav1.Condition) {
existingCondition := meta.FindStatusCondition(*conditions, toSet.Type)
if existingCondition == nil {
toSet.LastTransitionTime = metav1.Time{Time: clock.Now()}
*conditions = append(*conditions, toSet)
return
}

newCondition := existingCondition.DeepCopy()
if newCondition.Status != toSet.Status {
newCondition.LastTransitionTime = metav1.Time{Time: clock.Now()}
}
newCondition.Status = toSet.Status
newCondition.Reason = toSet.Reason
newCondition.Message = toSet.Message

for i := range *conditions {
if (*conditions)[i].Type == toSet.Type {
(*conditions)[i] = *newCondition
return
}
}
}

// GetCondition returns a copy to the condition with the given type from the list of conditions.
// It returns a pointer for a clear indication of "not found", it doesn't return a reference intended for mutation
// of the original list.
Expand Down
29 changes: 15 additions & 14 deletions backend/pkg/controllers/maestro_readonly_bundle_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (

"k8s.io/apimachinery/pkg/api/equality"
k8serrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
Expand Down Expand Up @@ -158,8 +159,8 @@ func buildObjectsFromUnstructuredObj(unstructuredObj *unstructured.Unstructured)
return objs, nil
}

func buildDegradedCondition(conditionStatus api.ConditionStatus, conditionReason string, conditionMessage string) api.Condition {
return api.Condition{
func buildDegradedCondition(conditionStatus metav1.ConditionStatus, conditionReason string, conditionMessage string) metav1.Condition {
return metav1.Condition{
Type: "Degraded",
Status: conditionStatus,
Reason: conditionReason,
Expand Down Expand Up @@ -214,15 +215,15 @@ func calculateManagementClusterContentFromMaestroBundle(
return nil, utils.TrackError(fmt.Errorf("failed to get Maestro Bundle: %w", err))
}
if k8serrors.IsNotFound(err) {
degradedCondition := buildDegradedCondition(api.ConditionTrue, "MaestroBundleNotFound", err.Error())
controllerutils.SetCondition(&desired.Status.Conditions, degradedCondition)
degradedCondition := buildDegradedCondition(metav1.ConditionTrue, "MaestroBundleNotFound", err.Error())
meta.SetStatusCondition(&desired.Status.Conditions, degradedCondition)
return desired, nil
}

rawBytes, err := getSingleResourceStatusFeedbackRawJSONFromMaestroBundle(existingMaestroBundle)
if err != nil {
degradedCondition := buildDegradedCondition(api.ConditionTrue, "MaestroBundleStatusFeedbackNotAvailable", err.Error())
controllerutils.SetCondition(&desired.Status.Conditions, degradedCondition)
degradedCondition := buildDegradedCondition(metav1.ConditionTrue, "MaestroBundleStatusFeedbackNotAvailable", err.Error())
meta.SetStatusCondition(&desired.Status.Conditions, degradedCondition)
return desired, nil
}

Expand All @@ -246,16 +247,16 @@ func calculateManagementClusterContentFromMaestroBundle(
if err != nil {
return nil, utils.TrackError(fmt.Errorf("failed to build objects from unstructured object: %w", err))
}
var degradedCondition api.Condition
var degradedCondition metav1.Condition
if !kubeContentMaxSizeExceeded {
// TODO is ListMeta or TypeMeta required at the metav1.List level?
desired.Status.KubeContent = &metav1.List{Items: objs}
degradedCondition = buildDegradedCondition(api.ConditionFalse, "NoErrors", "As expected.")
degradedCondition = buildDegradedCondition(metav1.ConditionFalse, "NoErrors", "As expected.")
} else {
kubeContextMaxSizeExceededConditionMessage = fmt.Sprintf("%s serialized size %.2f MiB exceeds Kube content max size %.2f MiB;", kind, float64(len(rawBytes))/(1024*1024), float64(kubeContentMaxSizeBytes)/(1024*1024))
degradedCondition = buildDegradedCondition(api.ConditionTrue, "KubeContentMaxSizeExceeded", kubeContextMaxSizeExceededConditionMessage)
degradedCondition = buildDegradedCondition(metav1.ConditionTrue, "KubeContentMaxSizeExceeded", kubeContextMaxSizeExceededConditionMessage)
}
controllerutils.SetCondition(&desired.Status.Conditions, degradedCondition)
meta.SetStatusCondition(&desired.Status.Conditions, degradedCondition)

return desired, nil
}
Expand Down Expand Up @@ -309,11 +310,11 @@ func readAndPersistMaestroReadonlyBundleContent(
// 2.3. If it does not, then keep the condition as is
// 3. Assign the merged conditions to the desired status.
tmpExistingStatus := existing.Status.DeepCopy()
mergedConditions := make([]api.Condition, 0, len(desired.Status.Conditions))
mergedConditions := make([]metav1.Condition, 0, len(desired.Status.Conditions))
for _, desiredCondition := range desired.Status.Conditions {
if controllerutils.GetCondition(tmpExistingStatus.Conditions, desiredCondition.Type) != nil {
controllerutils.SetCondition(&tmpExistingStatus.Conditions, desiredCondition)
merged := controllerutils.GetCondition(tmpExistingStatus.Conditions, desiredCondition.Type)
if meta.FindStatusCondition(tmpExistingStatus.Conditions, desiredCondition.Type) != nil {
meta.SetStatusCondition(&tmpExistingStatus.Conditions, desiredCondition)
merged := meta.FindStatusCondition(tmpExistingStatus.Conditions, desiredCondition.Type)
mergedConditions = append(mergedConditions, *merged)
continue
}
Expand Down
22 changes: 11 additions & 11 deletions backend/pkg/controllers/maestro_readonly_bundle_helpers_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
workv1 "open-cluster-management.io/api/work/v1"

k8serrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
Expand All @@ -37,7 +38,6 @@ import (

hsv1beta1 "github.com/openshift/hypershift/api/hypershift/v1beta1"

"github.com/Azure/ARO-HCP/backend/pkg/controllers/controllerutils"
"github.com/Azure/ARO-HCP/backend/pkg/maestro"
"github.com/Azure/ARO-HCP/internal/api"
"github.com/Azure/ARO-HCP/internal/api/arm"
Expand Down Expand Up @@ -82,14 +82,14 @@ func buildTestMaestroBundleWithStatusFeedback(name, namespace, rawJSON string) *
}

func TestMaestroReadonlyBundleHelpers_buildDegradedCondition(t *testing.T) {
cond := buildDegradedCondition(api.ConditionTrue, "MaestroBundleNotFound", "bundle not found")
cond := buildDegradedCondition(metav1.ConditionTrue, "MaestroBundleNotFound", "bundle not found")
assert.Equal(t, "Degraded", cond.Type)
assert.Equal(t, api.ConditionTrue, cond.Status)
assert.Equal(t, metav1.ConditionTrue, cond.Status)
assert.Equal(t, "MaestroBundleNotFound", cond.Reason)
assert.Equal(t, "bundle not found", cond.Message)

condFalse := buildDegradedCondition(api.ConditionFalse, "", "")
assert.Equal(t, api.ConditionFalse, condFalse.Status)
condFalse := buildDegradedCondition(metav1.ConditionFalse, "", "")
assert.Equal(t, metav1.ConditionFalse, condFalse.Status)
assert.Empty(t, condFalse.Reason)
assert.Empty(t, condFalse.Message)
}
Expand Down Expand Up @@ -407,7 +407,7 @@ func TestMaestroReadonlyBundleHelpers_calculateManagementClusterContentFromMaest
require.NoError(t, err)
require.NotNil(t, got)
assert.Equal(t, tt.wantKubeContent, got.Status.KubeContent != nil && len(got.Status.KubeContent.Items) > 0)
hasDegradedTrue := controllerutils.IsConditionTrue(got.Status.Conditions, "Degraded")
hasDegradedTrue := meta.IsStatusConditionTrue(got.Status.Conditions, "Degraded")
assert.Equal(t, tt.wantDegraded, hasDegradedTrue)
}
})
Expand Down Expand Up @@ -607,18 +607,18 @@ func TestMaestroReadonlyBundleHelpers_readAndPersistMaestroReadonlyBundleContent

u := &unstructured.Unstructured{}
require.NoError(t, json.Unmarshal([]byte(validHCJSON), u))
historicLTT := time.Date(2020, 6, 15, 12, 0, 0, 0, time.UTC)
historicLTT := metav1.Time{Time: time.Date(2020, 6, 15, 12, 0, 0, 0, time.UTC)}
existing := &api.ManagementClusterContent{
CosmosMetadata: api.CosmosMetadata{ResourceID: existingRID},
ResourceID: *existingRID,
Status: api.ManagementClusterContentStatus{
KubeContent: &metav1.List{
Items: []runtime.RawExtension{{Object: u}},
},
Conditions: []api.Condition{
Conditions: []metav1.Condition{
{
Type: "Degraded",
Status: api.ConditionFalse,
Status: metav1.ConditionFalse,
Reason: "NoErrors",
Message: "As expected.",
LastTransitionTime: historicLTT,
Expand All @@ -634,9 +634,9 @@ func TestMaestroReadonlyBundleHelpers_readAndPersistMaestroReadonlyBundleContent

got, err := mccCRUD.Get(ctx, string(api.MaestroBundleInternalNameReadonlyHypershiftHostedCluster))
require.NoError(t, err)
degraded := controllerutils.GetCondition(got.Status.Conditions, "Degraded")
degraded := meta.FindStatusCondition(got.Status.Conditions, "Degraded")
require.NotNil(t, degraded)
assert.True(t, degraded.LastTransitionTime.Equal(historicLTT), "expected LastTransitionTime from Cosmos to be preserved, got %v", degraded.LastTransitionTime)
assert.True(t, degraded.LastTransitionTime.Equal(&historicLTT), "expected LastTransitionTime from Cosmos to be preserved, got %v", degraded.LastTransitionTime)
})

}
Loading
Loading