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

feat: Add online/offline replica support #4812

Merged
merged 5 commits into from
Dec 11, 2024
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
20 changes: 14 additions & 6 deletions infra/feast-operator/api/v1alpha1/featurestore_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,9 @@ type FeatureStoreServices struct {

// OfflineStore configures the deployed offline store service
type OfflineStore struct {
ServiceConfigs `json:",inline"`
Persistence *OfflineStorePersistence `json:"persistence,omitempty"`
TLS *OfflineTlsConfigs `json:"tls,omitempty"`
StoreServiceConfigs `json:",inline"`
Persistence *OfflineStorePersistence `json:"persistence,omitempty"`
TLS *OfflineTlsConfigs `json:"tls,omitempty"`
// LogLevel sets the logging level for the offline store service
// Allowed values: "debug", "info", "warning", "error", "critical".
// +kubebuilder:validation:Enum=debug;info;warning;error;critical
Expand Down Expand Up @@ -134,9 +134,9 @@ var ValidOfflineStoreDBStorePersistenceTypes = []string{

// OnlineStore configures the deployed online store service
type OnlineStore struct {
ServiceConfigs `json:",inline"`
Persistence *OnlineStorePersistence `json:"persistence,omitempty"`
TLS *TlsConfigs `json:"tls,omitempty"`
StoreServiceConfigs `json:",inline"`
Persistence *OnlineStorePersistence `json:"persistence,omitempty"`
TLS *TlsConfigs `json:"tls,omitempty"`
// LogLevel sets the logging level for the online store service
// Allowed values: "debug", "info", "warning", "error", "critical".
// +kubebuilder:validation:Enum=debug;info;warning;error;critical
Expand Down Expand Up @@ -297,6 +297,14 @@ type DefaultConfigs struct {
Image *string `json:"image,omitempty"`
}

// StoreServiceConfigs k8s deployment settings
type StoreServiceConfigs struct {
// Replicas determines the number of pods for the feast service.
// When Replicas > 1, persistence is recommended.
Replicas *int32 `json:"replicas,omitempty"`
tchughesiv marked this conversation as resolved.
Show resolved Hide resolved
ServiceConfigs `json:",inline"`
}

// OptionalConfigs k8s container settings that are optional
type OptionalConfigs struct {
Env *[]corev1.EnvVar `json:"env,omitempty"`
Expand Down
25 changes: 23 additions & 2 deletions infra/feast-operator/api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,12 @@ spec:
x-kubernetes-validations:
- message: One selection required between file or store.
rule: '[has(self.file), has(self.store)].exists_one(c, c)'
replicas:
description: |-
Replicas determines the number of pods for the feast service.
When Replicas > 1, persistence is recommended.
format: int32
type: integer
resources:
description: ResourceRequirements describes the compute resource
requirements.
Expand Down Expand Up @@ -745,6 +751,12 @@ spec:
x-kubernetes-validations:
- message: One selection required between file or store.
rule: '[has(self.file), has(self.store)].exists_one(c, c)'
replicas:
description: |-
Replicas determines the number of pods for the feast service.
When Replicas > 1, persistence is recommended.
format: int32
type: integer
resources:
description: ResourceRequirements describes the compute resource
requirements.
Expand Down Expand Up @@ -1614,6 +1626,12 @@ spec:
- message: One selection required between file or store.
rule: '[has(self.file), has(self.store)].exists_one(c,
c)'
replicas:
description: |-
Replicas determines the number of pods for the feast service.
When Replicas > 1, persistence is recommended.
format: int32
type: integer
resources:
description: ResourceRequirements describes the compute
resource requirements.
Expand Down Expand Up @@ -1997,6 +2015,12 @@ spec:
- message: One selection required between file or store.
rule: '[has(self.file), has(self.store)].exists_one(c,
c)'
replicas:
description: |-
Replicas determines the number of pods for the feast service.
When Replicas > 1, persistence is recommended.
format: int32
type: integer
resources:
description: ResourceRequirements describes the compute
resource requirements.
Expand Down
24 changes: 24 additions & 0 deletions infra/feast-operator/dist/install.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,12 @@ spec:
x-kubernetes-validations:
- message: One selection required between file or store.
rule: '[has(self.file), has(self.store)].exists_one(c, c)'
replicas:
description: |-
Replicas determines the number of pods for the feast service.
When Replicas > 1, persistence is recommended.
format: int32
type: integer
resources:
description: ResourceRequirements describes the compute resource
requirements.
Expand Down Expand Up @@ -753,6 +759,12 @@ spec:
x-kubernetes-validations:
- message: One selection required between file or store.
rule: '[has(self.file), has(self.store)].exists_one(c, c)'
replicas:
description: |-
Replicas determines the number of pods for the feast service.
When Replicas > 1, persistence is recommended.
format: int32
type: integer
resources:
description: ResourceRequirements describes the compute resource
requirements.
Expand Down Expand Up @@ -1622,6 +1634,12 @@ spec:
- message: One selection required between file or store.
rule: '[has(self.file), has(self.store)].exists_one(c,
c)'
replicas:
description: |-
Replicas determines the number of pods for the feast service.
When Replicas > 1, persistence is recommended.
format: int32
type: integer
resources:
description: ResourceRequirements describes the compute
resource requirements.
Expand Down Expand Up @@ -2005,6 +2023,12 @@ spec:
- message: One selection required between file or store.
rule: '[has(self.file), has(self.store)].exists_one(c,
c)'
replicas:
description: |-
Replicas determines the number of pods for the feast service.
When Replicas > 1, persistence is recommended.
format: int32
type: integer
resources:
description: ResourceRequirements describes the compute
resource requirements.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ var _ = Describe("FeatureStore Controller - db storage services", func() {
Context("When deploying a resource with all db storage services", func() {
const resourceName = "cr-name"
var pullPolicy = corev1.PullAlways
var replicas = int32(1)

ctx := context.Background()

Expand Down Expand Up @@ -205,7 +206,7 @@ var _ = Describe("FeatureStore Controller - db storage services", func() {
By("creating the custom resource for the Kind FeatureStore")
err = k8sClient.Get(ctx, typeNamespacedName, featurestore)
if err != nil && errors.IsNotFound(err) {
resource := createFeatureStoreResource(resourceName, image, pullPolicy, &[]corev1.EnvVar{})
resource := createFeatureStoreResource(resourceName, image, pullPolicy, replicas, &[]corev1.EnvVar{})
resource.Spec.Services.OfflineStore.Persistence = &feastdevv1alpha1.OfflineStorePersistence{
DBPersistence: &feastdevv1alpha1.OfflineStoreDBStorePersistence{
Type: string(offlineType),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ var _ = Describe("FeatureStore Controller-Ephemeral services", func() {
const resourceName = "services-ephemeral"
const offlineType = "duckdb"
var pullPolicy = corev1.PullAlways
var replicas = int32(1)
var testEnvVarName = "testEnvVarName"
var testEnvVarValue = "testEnvVarValue"

Expand All @@ -65,7 +66,7 @@ var _ = Describe("FeatureStore Controller-Ephemeral services", func() {
By("creating the custom resource for the Kind FeatureStore")
err := k8sClient.Get(ctx, typeNamespacedName, featurestore)
if err != nil && errors.IsNotFound(err) {
resource := createFeatureStoreResource(resourceName, image, pullPolicy, &[]corev1.EnvVar{{Name: testEnvVarName, Value: testEnvVarValue},
resource := createFeatureStoreResource(resourceName, image, pullPolicy, replicas, &[]corev1.EnvVar{{Name: testEnvVarName, Value: testEnvVarValue},
{Name: "fieldRefName", ValueFrom: &corev1.EnvVarSource{FieldRef: &corev1.ObjectFieldSelector{APIVersion: "v1", FieldPath: "metadata.namespace"}}}})
resource.Spec.Services.OfflineStore.Persistence = &feastdevv1alpha1.OfflineStorePersistence{
FilePersistence: &feastdevv1alpha1.OfflineStoreFilePersistence{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ var _ = Describe("FeatureStore Controller-Kubernetes authorization", func() {
Context("When deploying a resource with all ephemeral services and Kubernetes authorization", func() {
const resourceName = "kubernetes-authorization"
var pullPolicy = corev1.PullAlways
var replicas = int32(1)

ctx := context.Background()

Expand All @@ -62,7 +63,7 @@ var _ = Describe("FeatureStore Controller-Kubernetes authorization", func() {
By("creating the custom resource for the Kind FeatureStore")
err := k8sClient.Get(ctx, typeNamespacedName, featurestore)
if err != nil && errors.IsNotFound(err) {
resource := createFeatureStoreResource(resourceName, image, pullPolicy, &[]corev1.EnvVar{})
resource := createFeatureStoreResource(resourceName, image, pullPolicy, replicas, &[]corev1.EnvVar{})
resource.Spec.AuthzConfig = &feastdevv1alpha1.AuthzConfig{KubernetesAuthz: &feastdevv1alpha1.KubernetesAuthz{
Roles: roles,
}}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ var _ = Describe("FeatureStore Controller-Ephemeral services", func() {
Context("When deploying a resource with all ephemeral services", func() {
const resourceName = "services-object-store"
var pullPolicy = corev1.PullAlways
var replicas = int32(1)
var testEnvVarName = "testEnvVarName"
var testEnvVarValue = "testEnvVarValue"

Expand All @@ -67,7 +68,7 @@ var _ = Describe("FeatureStore Controller-Ephemeral services", func() {
By("creating the custom resource for the Kind FeatureStore")
err := k8sClient.Get(ctx, typeNamespacedName, featurestore)
if err != nil && errors.IsNotFound(err) {
resource := createFeatureStoreResource(resourceName, image, pullPolicy, &[]corev1.EnvVar{{Name: testEnvVarName, Value: testEnvVarValue},
resource := createFeatureStoreResource(resourceName, image, pullPolicy, replicas, &[]corev1.EnvVar{{Name: testEnvVarName, Value: testEnvVarValue},
{Name: "fieldRefName", ValueFrom: &corev1.EnvVarSource{FieldRef: &corev1.ObjectFieldSelector{APIVersion: "v1", FieldPath: "metadata.namespace"}}}})
resource.Spec.Services.OnlineStore = nil
resource.Spec.Services.OfflineStore = nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ var _ = Describe("FeatureStore Controller-OIDC authorization", func() {
const resourceName = "oidc-authorization"
const oidcSecretName = "oidc-secret"
var pullPolicy = corev1.PullAlways
var replicas = int32(1)

ctx := context.Background()

Expand All @@ -73,7 +74,7 @@ var _ = Describe("FeatureStore Controller-OIDC authorization", func() {
By("creating the custom resource for the Kind FeatureStore")
err = k8sClient.Get(ctx, typeNamespacedName, featurestore)
if err != nil && errors.IsNotFound(err) {
resource := createFeatureStoreResource(resourceName, image, pullPolicy, &[]corev1.EnvVar{})
resource := createFeatureStoreResource(resourceName, image, pullPolicy, replicas, &[]corev1.EnvVar{})
resource.Spec.AuthzConfig = &feastdevv1alpha1.AuthzConfig{OidcAuthz: &feastdevv1alpha1.OidcAuthz{
SecretRef: corev1.LocalObjectReference{
Name: oidcSecretName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ var _ = Describe("FeatureStore Controller-Ephemeral services", func() {
Context("When deploying a resource with all ephemeral services", func() {
const resourceName = "services-pvc"
var pullPolicy = corev1.PullAlways
var replicas = int32(1)
var testEnvVarName = "testEnvVarName"
var testEnvVarValue = "testEnvVarValue"

Expand Down Expand Up @@ -77,7 +78,7 @@ var _ = Describe("FeatureStore Controller-Ephemeral services", func() {
By("creating the custom resource for the Kind FeatureStore")
err := k8sClient.Get(ctx, typeNamespacedName, featurestore)
if err != nil && errors.IsNotFound(err) {
resource := createFeatureStoreResource(resourceName, image, pullPolicy, &[]corev1.EnvVar{{Name: testEnvVarName, Value: testEnvVarValue},
resource := createFeatureStoreResource(resourceName, image, pullPolicy, replicas, &[]corev1.EnvVar{{Name: testEnvVarName, Value: testEnvVarValue},
{Name: "fieldRefName", ValueFrom: &corev1.EnvVarSource{FieldRef: &corev1.ObjectFieldSelector{APIVersion: "v1", FieldPath: "metadata.namespace"}}}})
resource.Spec.Services.OfflineStore.Persistence = &feastdevv1alpha1.OfflineStorePersistence{
FilePersistence: &feastdevv1alpha1.OfflineStoreFilePersistence{
Expand Down
Loading
Loading