Skip to content

Commit

Permalink
fix: Changed feast operator to set status of featurestore cr to ready…
Browse files Browse the repository at this point in the history
… based on deployment.status = available (#5020)

Changed featurestore cr ready status to reflect deployment available status

Signed-off-by: Theodor Mihalache <tmihalac@redhat.com>
  • Loading branch information
tmihalac authored Feb 6, 2025
1 parent ea1d02d commit fce0d35
Show file tree
Hide file tree
Showing 12 changed files with 119 additions and 52 deletions.
32 changes: 17 additions & 15 deletions infra/feast-operator/api/v1alpha1/featurestore_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,23 +38,25 @@ const (
AuthorizationReadyType = "Authorization"

// Feast condition reasons:
ReadyReason = "Ready"
FailedReason = "FeatureStoreFailed"
OfflineStoreFailedReason = "OfflineStoreDeploymentFailed"
OnlineStoreFailedReason = "OnlineStoreDeploymentFailed"
RegistryFailedReason = "RegistryDeploymentFailed"
UIFailedReason = "UIDeploymentFailed"
ClientFailedReason = "ClientDeploymentFailed"
KubernetesAuthzFailedReason = "KubernetesAuthorizationDeploymentFailed"
ReadyReason = "Ready"
FailedReason = "FeatureStoreFailed"
DeploymentNotAvailableReason = "DeploymentNotAvailable"
OfflineStoreFailedReason = "OfflineStoreDeploymentFailed"
OnlineStoreFailedReason = "OnlineStoreDeploymentFailed"
RegistryFailedReason = "RegistryDeploymentFailed"
UIFailedReason = "UIDeploymentFailed"
ClientFailedReason = "ClientDeploymentFailed"
KubernetesAuthzFailedReason = "KubernetesAuthorizationDeploymentFailed"

// Feast condition messages:
ReadyMessage = "FeatureStore installation complete"
OfflineStoreReadyMessage = "Offline Store installation complete"
OnlineStoreReadyMessage = "Online Store installation complete"
RegistryReadyMessage = "Registry installation complete"
UIReadyMessage = "UI installation complete"
ClientReadyMessage = "Client installation complete"
KubernetesAuthzReadyMessage = "Kubernetes authorization installation complete"
ReadyMessage = "FeatureStore installation complete"
OfflineStoreReadyMessage = "Offline Store installation complete"
OnlineStoreReadyMessage = "Online Store installation complete"
RegistryReadyMessage = "Registry installation complete"
UIReadyMessage = "UI installation complete"
ClientReadyMessage = "Client installation complete"
KubernetesAuthzReadyMessage = "Kubernetes authorization installation complete"
DeploymentNotAvailableMessage = "Deployment is not available"

// entity_key_serialization_version
SerializationVersion = 3
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,30 @@ func (r *FeatureStoreReconciler) deployFeast(ctx context.Context, cr *feastdevv1
Reason: feastdevv1alpha1.FailedReason,
Message: "Error: " + err.Error(),
}
} else {
deployment, deploymentErr := feast.GetDeployment()
if deploymentErr != nil {
condition = metav1.Condition{
Type: feastdevv1alpha1.ReadyType,
Status: metav1.ConditionUnknown,
Reason: feastdevv1alpha1.DeploymentNotAvailableReason,
Message: feastdevv1alpha1.DeploymentNotAvailableMessage,
}

result = errResult
} else {
isDeployAvailable := services.IsDeploymentAvailable(deployment.Status.Conditions)
if !isDeployAvailable {
condition = metav1.Condition{
Type: feastdevv1alpha1.ReadyType,
Status: metav1.ConditionUnknown,
Reason: feastdevv1alpha1.DeploymentNotAvailableReason,
Message: feastdevv1alpha1.DeploymentNotAvailableMessage,
}

result = errResult
}
}
}

logger.Info(condition.Message)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -398,10 +398,10 @@ var _ = Describe("FeatureStore Controller - db storage services", func() {
Expect(resource.Status.Conditions).NotTo(BeEmpty())
cond := apimeta.FindStatusCondition(resource.Status.Conditions, feastdevv1alpha1.ReadyType)
Expect(cond).ToNot(BeNil())
Expect(cond.Status).To(Equal(metav1.ConditionTrue))
Expect(cond.Reason).To(Equal(feastdevv1alpha1.ReadyReason))
Expect(cond.Status).To(Equal(metav1.ConditionUnknown))
Expect(cond.Reason).To(Equal(feastdevv1alpha1.DeploymentNotAvailableReason))
Expect(cond.Type).To(Equal(feastdevv1alpha1.ReadyType))
Expect(cond.Message).To(Equal(feastdevv1alpha1.ReadyMessage))
Expect(cond.Message).To(Equal(feastdevv1alpha1.DeploymentNotAvailableMessage))

cond = apimeta.FindStatusCondition(resource.Status.Conditions, feastdevv1alpha1.RegistryReadyType)
Expect(cond).ToNot(BeNil())
Expand Down Expand Up @@ -431,7 +431,7 @@ var _ = Describe("FeatureStore Controller - db storage services", func() {
Expect(cond.Type).To(Equal(feastdevv1alpha1.OnlineStoreReadyType))
Expect(cond.Message).To(Equal(feastdevv1alpha1.OnlineStoreReadyMessage))

Expect(resource.Status.Phase).To(Equal(feastdevv1alpha1.ReadyPhase))
Expect(resource.Status.Phase).To(Equal(feastdevv1alpha1.PendingPhase))

// check deployment
deploy := &appsv1.Deployment{}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,10 +164,10 @@ var _ = Describe("FeatureStore Controller-Ephemeral services", func() {
Expect(resource.Status.Conditions).NotTo(BeEmpty())
cond := apimeta.FindStatusCondition(resource.Status.Conditions, feastdevv1alpha1.ReadyType)
Expect(cond).ToNot(BeNil())
Expect(cond.Status).To(Equal(metav1.ConditionTrue))
Expect(cond.Reason).To(Equal(feastdevv1alpha1.ReadyReason))
Expect(cond.Status).To(Equal(metav1.ConditionUnknown))
Expect(cond.Reason).To(Equal(feastdevv1alpha1.DeploymentNotAvailableReason))
Expect(cond.Type).To(Equal(feastdevv1alpha1.ReadyType))
Expect(cond.Message).To(Equal(feastdevv1alpha1.ReadyMessage))
Expect(cond.Message).To(Equal(feastdevv1alpha1.DeploymentNotAvailableMessage))

cond = apimeta.FindStatusCondition(resource.Status.Conditions, feastdevv1alpha1.AuthorizationReadyType)
Expect(cond).To(BeNil())
Expand Down Expand Up @@ -200,7 +200,7 @@ var _ = Describe("FeatureStore Controller-Ephemeral services", func() {
Expect(cond.Type).To(Equal(feastdevv1alpha1.OnlineStoreReadyType))
Expect(cond.Message).To(Equal(feastdevv1alpha1.OnlineStoreReadyMessage))

Expect(resource.Status.Phase).To(Equal(feastdevv1alpha1.ReadyPhase))
Expect(resource.Status.Phase).To(Equal(feastdevv1alpha1.PendingPhase))

// check deployment
deploy := &appsv1.Deployment{}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,10 +150,10 @@ var _ = Describe("FeatureStore Controller-Kubernetes authorization", func() {
Expect(resource.Status.Conditions).NotTo(BeEmpty())
cond := apimeta.FindStatusCondition(resource.Status.Conditions, feastdevv1alpha1.ReadyType)
Expect(cond).ToNot(BeNil())
Expect(cond.Status).To(Equal(metav1.ConditionTrue))
Expect(cond.Reason).To(Equal(feastdevv1alpha1.ReadyReason))
Expect(cond.Status).To(Equal(metav1.ConditionUnknown))
Expect(cond.Reason).To(Equal(feastdevv1alpha1.DeploymentNotAvailableReason))
Expect(cond.Type).To(Equal(feastdevv1alpha1.ReadyType))
Expect(cond.Message).To(Equal(feastdevv1alpha1.ReadyMessage))
Expect(cond.Message).To(Equal(feastdevv1alpha1.DeploymentNotAvailableMessage))

cond = apimeta.FindStatusCondition(resource.Status.Conditions, feastdevv1alpha1.AuthorizationReadyType)
Expect(cond).ToNot(BeNil())
Expand Down Expand Up @@ -190,7 +190,7 @@ var _ = Describe("FeatureStore Controller-Kubernetes authorization", func() {
Expect(cond.Type).To(Equal(feastdevv1alpha1.OnlineStoreReadyType))
Expect(cond.Message).To(Equal(feastdevv1alpha1.OnlineStoreReadyMessage))

Expect(resource.Status.Phase).To(Equal(feastdevv1alpha1.ReadyPhase))
Expect(resource.Status.Phase).To(Equal(feastdevv1alpha1.PendingPhase))

// check deployment
deploy := &appsv1.Deployment{}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,10 @@ var _ = Describe("FeatureStore Controller - Feast service LogLevel", func() {
Expect(resource.Status.Conditions).NotTo(BeEmpty())
cond := apimeta.FindStatusCondition(resource.Status.Conditions, feastdevv1alpha1.ReadyType)
Expect(cond).ToNot(BeNil())
Expect(cond.Status).To(Equal(metav1.ConditionTrue))
Expect(cond.Reason).To(Equal(feastdevv1alpha1.ReadyReason))
Expect(cond.Status).To(Equal(metav1.ConditionUnknown))
Expect(cond.Reason).To(Equal(feastdevv1alpha1.DeploymentNotAvailableReason))
Expect(cond.Type).To(Equal(feastdevv1alpha1.ReadyType))
Expect(cond.Message).To(Equal(feastdevv1alpha1.ReadyMessage))
Expect(cond.Message).To(Equal(feastdevv1alpha1.DeploymentNotAvailableMessage))

cond = apimeta.FindStatusCondition(resource.Status.Conditions, feastdevv1alpha1.RegistryReadyType)
Expect(cond).ToNot(BeNil())
Expand Down Expand Up @@ -161,7 +161,7 @@ var _ = Describe("FeatureStore Controller - Feast service LogLevel", func() {
Expect(cond.Reason).To(Equal(feastdevv1alpha1.ReadyReason))
Expect(cond.Type).To(Equal(feastdevv1alpha1.OnlineStoreReadyType))
Expect(cond.Message).To(Equal(feastdevv1alpha1.OnlineStoreReadyMessage))
Expect(resource.Status.Phase).To(Equal(feastdevv1alpha1.ReadyPhase))
Expect(resource.Status.Phase).To(Equal(feastdevv1alpha1.PendingPhase))

// check deployment
deploy := &appsv1.Deployment{}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,10 +148,10 @@ var _ = Describe("FeatureStore Controller-Ephemeral services", func() {
Expect(resource.Status.Conditions).NotTo(BeEmpty())
cond := apimeta.FindStatusCondition(resource.Status.Conditions, feastdevv1alpha1.ReadyType)
Expect(cond).ToNot(BeNil())
Expect(cond.Status).To(Equal(metav1.ConditionTrue))
Expect(cond.Reason).To(Equal(feastdevv1alpha1.ReadyReason))
Expect(cond.Status).To(Equal(metav1.ConditionUnknown))
Expect(cond.Reason).To(Equal(feastdevv1alpha1.DeploymentNotAvailableReason))
Expect(cond.Type).To(Equal(feastdevv1alpha1.ReadyType))
Expect(cond.Message).To(Equal(feastdevv1alpha1.ReadyMessage))
Expect(cond.Message).To(Equal(feastdevv1alpha1.DeploymentNotAvailableMessage))

cond = apimeta.FindStatusCondition(resource.Status.Conditions, feastdevv1alpha1.AuthorizationReadyType)
Expect(cond).To(BeNil())
Expand All @@ -176,7 +176,7 @@ var _ = Describe("FeatureStore Controller-Ephemeral services", func() {
cond = apimeta.FindStatusCondition(resource.Status.Conditions, feastdevv1alpha1.OnlineStoreReadyType)
Expect(cond).To(BeNil())

Expect(resource.Status.Phase).To(Equal(feastdevv1alpha1.ReadyPhase))
Expect(resource.Status.Phase).To(Equal(feastdevv1alpha1.PendingPhase))

// check deployment
deploy := &appsv1.Deployment{}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,10 +173,10 @@ var _ = Describe("FeatureStore Controller-OIDC authorization", func() {
Expect(resource.Status.Conditions).NotTo(BeEmpty())
cond := apimeta.FindStatusCondition(resource.Status.Conditions, feastdevv1alpha1.ReadyType)
Expect(cond).ToNot(BeNil())
Expect(cond.Status).To(Equal(metav1.ConditionTrue))
Expect(cond.Reason).To(Equal(feastdevv1alpha1.ReadyReason))
Expect(cond.Status).To(Equal(metav1.ConditionUnknown))
Expect(cond.Reason).To(Equal(feastdevv1alpha1.DeploymentNotAvailableReason))
Expect(cond.Type).To(Equal(feastdevv1alpha1.ReadyType))
Expect(cond.Message).To(Equal(feastdevv1alpha1.ReadyMessage))
Expect(cond.Message).To(Equal(feastdevv1alpha1.DeploymentNotAvailableMessage))

cond = apimeta.FindStatusCondition(resource.Status.Conditions, feastdevv1alpha1.AuthorizationReadyType)
Expect(cond).To(BeNil())
Expand Down Expand Up @@ -209,7 +209,7 @@ var _ = Describe("FeatureStore Controller-OIDC authorization", func() {
Expect(cond.Type).To(Equal(feastdevv1alpha1.OnlineStoreReadyType))
Expect(cond.Message).To(Equal(feastdevv1alpha1.OnlineStoreReadyMessage))

Expect(resource.Status.Phase).To(Equal(feastdevv1alpha1.ReadyPhase))
Expect(resource.Status.Phase).To(Equal(feastdevv1alpha1.PendingPhase))

// check deployment
deploy := &appsv1.Deployment{}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -227,10 +227,10 @@ var _ = Describe("FeatureStore Controller-Ephemeral services", func() {
Expect(resource.Status.Conditions).NotTo(BeEmpty())
cond := apimeta.FindStatusCondition(resource.Status.Conditions, feastdevv1alpha1.ReadyType)
Expect(cond).ToNot(BeNil())
Expect(cond.Status).To(Equal(metav1.ConditionTrue))
Expect(cond.Reason).To(Equal(feastdevv1alpha1.ReadyReason))
Expect(cond.Status).To(Equal(metav1.ConditionUnknown))
Expect(cond.Reason).To(Equal(feastdevv1alpha1.DeploymentNotAvailableReason))
Expect(cond.Type).To(Equal(feastdevv1alpha1.ReadyType))
Expect(cond.Message).To(Equal(feastdevv1alpha1.ReadyMessage))
Expect(cond.Message).To(Equal(feastdevv1alpha1.DeploymentNotAvailableMessage))

cond = apimeta.FindStatusCondition(resource.Status.Conditions, feastdevv1alpha1.AuthorizationReadyType)
Expect(cond).To(BeNil())
Expand Down Expand Up @@ -263,7 +263,7 @@ var _ = Describe("FeatureStore Controller-Ephemeral services", func() {
Expect(cond.Type).To(Equal(feastdevv1alpha1.OnlineStoreReadyType))
Expect(cond.Message).To(Equal(feastdevv1alpha1.OnlineStoreReadyMessage))

Expect(resource.Status.Phase).To(Equal(feastdevv1alpha1.ReadyPhase))
Expect(resource.Status.Phase).To(Equal(feastdevv1alpha1.PendingPhase))

ephemeralName := "feast-data"
ephemeralVolume := corev1.Volume{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,31 @@ var _ = Describe("FeatureStore Controller", func() {
FeatureStore: resource,
},
}

deployment, _ := feast.GetDeployment()
deployment.Status = appsv1.DeploymentStatus{
Conditions: []appsv1.DeploymentCondition{
{
Type: appsv1.DeploymentAvailable,
Status: "True", // Mark as available
Reason: "MinimumReplicasAvailable",
},
},
}

// Update the deployment's status
err = controllerReconciler.Status().Update(context.Background(), &deployment)
Expect(err).NotTo(HaveOccurred())

_, err = controllerReconciler.Reconcile(ctx, reconcile.Request{
NamespacedName: typeNamespacedName,
})
Expect(err).NotTo(HaveOccurred())

resource = &feastdevv1alpha1.FeatureStore{}
err = k8sClient.Get(ctx, typeNamespacedName, resource)
Expect(err).NotTo(HaveOccurred())

Expect(resource.Status).NotTo(BeNil())
Expect(resource.Status.FeastVersion).To(Equal(feastversion.FeastVersion))
Expect(resource.Status.ClientConfigMap).To(Equal(feast.GetFeastServiceName(services.ClientFeastType)))
Expand Down Expand Up @@ -501,10 +526,10 @@ var _ = Describe("FeatureStore Controller", func() {
Expect(resource.Status.Conditions).NotTo(BeEmpty())
cond := apimeta.FindStatusCondition(resource.Status.Conditions, feastdevv1alpha1.ReadyType)
Expect(cond).ToNot(BeNil())
Expect(cond.Status).To(Equal(metav1.ConditionTrue))
Expect(cond.Reason).To(Equal(feastdevv1alpha1.ReadyReason))
Expect(cond.Status).To(Equal(metav1.ConditionUnknown))
Expect(cond.Reason).To(Equal(feastdevv1alpha1.DeploymentNotAvailableReason))
Expect(cond.Type).To(Equal(feastdevv1alpha1.ReadyType))
Expect(cond.Message).To(Equal(feastdevv1alpha1.ReadyMessage))
Expect(cond.Message).To(Equal(feastdevv1alpha1.DeploymentNotAvailableMessage))

cond = apimeta.FindStatusCondition(resource.Status.Conditions, feastdevv1alpha1.AuthorizationReadyType)
Expect(cond).To(BeNil())
Expand Down Expand Up @@ -544,7 +569,7 @@ var _ = Describe("FeatureStore Controller", func() {
Expect(cond.Type).To(Equal(feastdevv1alpha1.UIReadyType))
Expect(cond.Message).To(Equal(feastdevv1alpha1.UIReadyMessage))

Expect(resource.Status.Phase).To(Equal(feastdevv1alpha1.ReadyPhase))
Expect(resource.Status.Phase).To(Equal(feastdevv1alpha1.PendingPhase))

deploy := &appsv1.Deployment{}
objMeta := feast.GetObjectMeta()
Expand Down Expand Up @@ -999,7 +1024,6 @@ var _ = Describe("FeatureStore Controller", func() {

Expect(apimeta.FindStatusCondition(resource.Status.Conditions, feastdevv1alpha1.AuthorizationReadyType)).To(BeNil())
Expect(apimeta.FindStatusCondition(resource.Status.Conditions, feastdevv1alpha1.RegistryReadyType)).To(BeNil())
Expect(apimeta.IsStatusConditionTrue(resource.Status.Conditions, feastdevv1alpha1.ReadyType)).To(BeTrue())
Expect(apimeta.IsStatusConditionTrue(resource.Status.Conditions, feastdevv1alpha1.OnlineStoreReadyType)).To(BeTrue())
Expect(apimeta.IsStatusConditionTrue(resource.Status.Conditions, feastdevv1alpha1.OfflineStoreReadyType)).To(BeTrue())
Expect(resource.Status.ServiceHostnames.Registry).ToNot(BeEmpty())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,10 +145,10 @@ var _ = Describe("FeatureStore Controller - Feast service TLS", func() {
Expect(resource.Status.Conditions).NotTo(BeEmpty())
cond := apimeta.FindStatusCondition(resource.Status.Conditions, feastdevv1alpha1.ReadyType)
Expect(cond).ToNot(BeNil())
Expect(cond.Status).To(Equal(metav1.ConditionTrue))
Expect(cond.Reason).To(Equal(feastdevv1alpha1.ReadyReason))
Expect(cond.Status).To(Equal(metav1.ConditionUnknown))
Expect(cond.Reason).To(Equal(feastdevv1alpha1.DeploymentNotAvailableReason))
Expect(cond.Type).To(Equal(feastdevv1alpha1.ReadyType))
Expect(cond.Message).To(Equal(feastdevv1alpha1.ReadyMessage))
Expect(cond.Message).To(Equal(feastdevv1alpha1.DeploymentNotAvailableMessage))

cond = apimeta.FindStatusCondition(resource.Status.Conditions, feastdevv1alpha1.RegistryReadyType)
Expect(cond).ToNot(BeNil())
Expand Down Expand Up @@ -178,7 +178,7 @@ var _ = Describe("FeatureStore Controller - Feast service TLS", func() {
Expect(cond.Type).To(Equal(feastdevv1alpha1.OnlineStoreReadyType))
Expect(cond.Message).To(Equal(feastdevv1alpha1.OnlineStoreReadyMessage))

Expect(resource.Status.Phase).To(Equal(feastdevv1alpha1.ReadyPhase))
Expect(resource.Status.Phase).To(Equal(feastdevv1alpha1.PendingPhase))

// check deployment
deploy := &appsv1.Deployment{}
Expand Down
17 changes: 17 additions & 0 deletions infra/feast-operator/internal/controller/services/services.go
Original file line number Diff line number Diff line change
Expand Up @@ -614,6 +614,13 @@ func (feast *FeastServices) GetFeastServiceName(feastType FeastServiceType) stri
return GetFeastServiceName(feast.Handler.FeatureStore, feastType)
}

func (feast *FeastServices) GetDeployment() (appsv1.Deployment, error) {
deployment := appsv1.Deployment{}
obj := feast.GetObjectMeta()
err := feast.Handler.Get(feast.Handler.Context, client.ObjectKey{Namespace: obj.GetNamespace(), Name: obj.GetName()}, &deployment)
return deployment, err
}

// GetFeastServiceName returns the feast service object name based on service type
func GetFeastServiceName(featureStore *feastdevv1alpha1.FeatureStore, feastType FeastServiceType) string {
return GetFeastName(featureStore) + "-" + string(feastType)
Expand Down Expand Up @@ -917,3 +924,13 @@ func getProbeHandler(feastType FeastServiceType, tls *feastdevv1alpha1.TlsConfig
},
}
}

func IsDeploymentAvailable(conditions []appsv1.DeploymentCondition) bool {
for _, condition := range conditions {
if condition.Type == appsv1.DeploymentAvailable {
return condition.Status == corev1.ConditionTrue
}
}

return false
}

0 comments on commit fce0d35

Please sign in to comment.