Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
Signed-off-by: Daniele Martinoli <[email protected]>
  • Loading branch information
dmartinol committed Nov 28, 2024
1 parent ef0b54e commit 6e8c611
Show file tree
Hide file tree
Showing 16 changed files with 406 additions and 53 deletions.
8 changes: 8 additions & 0 deletions infra/feast-operator/api/v1alpha1/featurestore_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -268,8 +268,10 @@ type OptionalConfigs struct {
}

// AuthzConfig defines the authorization settings for the deployed Feast services.
// +kubebuilder:validation:XValidation:rule="[has(self.kubernetes), has(self.oidc)].exists_one(c, c)",message="One selection required between kubernetes or oidc."
type AuthzConfig struct {
KubernetesAuthz *KubernetesAuthz `json:"kubernetes,omitempty"`
OidcAuthz *OidcAuthz `json:"oidc,omitempty"`
}

// KubernetesAuthz provides a way to define the authorization settings using Kubernetes RBAC resources.
Expand All @@ -284,6 +286,12 @@ type KubernetesAuthz struct {
Roles []string `json:"roles,omitempty"`
}

// OidcAuthz defines the authorization settings for deployments using an Open ID Connect identity provider.
// https://auth0.com/docs/authenticate/protocols/openid-connect-protocol
type OidcAuthz struct {
SecretRef corev1.LocalObjectReference `json:"secretRef"`
}

// FeatureStoreStatus defines the observed state of FeatureStore
type FeatureStoreStatus struct {
// Shows the currently applied feast configuration, including any pertinent defaults
Expand Down
21 changes: 21 additions & 0 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.

49 changes: 49 additions & 0 deletions infra/feast-operator/config/crd/bases/feast.dev_featurestores.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,31 @@ spec:
type: string
type: array
type: object
oidc:
description: |-
OidcAuthz defines the authorization settings for deployments using an Open ID Connect identity provider.
https://auth0.com/docs/authenticate/protocols/openid-connect-protocol
properties:
secretRef:
description: |-
LocalObjectReference contains enough information to let you locate the
referenced object inside the same namespace.
properties:
name:
description: |-
Name of the referent.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
TODO: Add other useful fields. apiVersion, kind, uid?
type: string
type: object
x-kubernetes-map-type: atomic
required:
- secretRef
type: object
type: object
x-kubernetes-validations:
- message: One selection required between kubernetes or oidc.
rule: '[has(self.kubernetes), has(self.oidc)].exists_one(c, c)'
feastProject:
description: FeastProject is the Feast project id. This can be any
alphanumeric string with underscores, but it cannot start with an
Expand Down Expand Up @@ -1091,7 +1115,32 @@ spec:
type: string
type: array
type: object
oidc:
description: |-
OidcAuthz defines the authorization settings for deployments using an Open ID Connect identity provider.
https://auth0.com/docs/authenticate/protocols/openid-connect-protocol
properties:
secretRef:
description: |-
LocalObjectReference contains enough information to let you locate the
referenced object inside the same namespace.
properties:
name:
description: |-
Name of the referent.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
TODO: Add other useful fields. apiVersion, kind, uid?
type: string
type: object
x-kubernetes-map-type: atomic
required:
- secretRef
type: object
type: object
x-kubernetes-validations:
- message: One selection required between kubernetes or oidc.
rule: '[has(self.kubernetes), has(self.oidc)].exists_one(c,
c)'
feastProject:
description: FeastProject is the Feast project id. This can be
any alphanumeric string with underscores, but it cannot start
Expand Down
49 changes: 49 additions & 0 deletions infra/feast-operator/dist/install.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,31 @@ spec:
type: string
type: array
type: object
oidc:
description: |-
OidcAuthz defines the authorization settings for deployments using an Open ID Connect identity provider.
https://auth0.com/docs/authenticate/protocols/openid-connect-protocol
properties:
secretRef:
description: |-
LocalObjectReference contains enough information to let you locate the
referenced object inside the same namespace.
properties:
name:
description: |-
Name of the referent.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
TODO: Add other useful fields. apiVersion, kind, uid?
type: string
type: object
x-kubernetes-map-type: atomic
required:
- secretRef
type: object
type: object
x-kubernetes-validations:
- message: One selection required between kubernetes or oidc.
rule: '[has(self.kubernetes), has(self.oidc)].exists_one(c, c)'
feastProject:
description: FeastProject is the Feast project id. This can be any
alphanumeric string with underscores, but it cannot start with an
Expand Down Expand Up @@ -1099,7 +1123,32 @@ spec:
type: string
type: array
type: object
oidc:
description: |-
OidcAuthz defines the authorization settings for deployments using an Open ID Connect identity provider.
https://auth0.com/docs/authenticate/protocols/openid-connect-protocol
properties:
secretRef:
description: |-
LocalObjectReference contains enough information to let you locate the
referenced object inside the same namespace.
properties:
name:
description: |-
Name of the referent.
More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
TODO: Add other useful fields. apiVersion, kind, uid?
type: string
type: object
x-kubernetes-map-type: atomic
required:
- secretRef
type: object
type: object
x-kubernetes-validations:
- message: One selection required between kubernetes or oidc.
rule: '[has(self.kubernetes), has(self.oidc)].exists_one(c,
c)'
feastProject:
description: FeastProject is the Feast project id. This can be
any alphanumeric string with underscores, but it cannot start
Expand Down
20 changes: 8 additions & 12 deletions infra/feast-operator/internal/controller/authz/authz.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,12 @@ import (
// Deploy the feast authorization
func (authz *FeastAuthorization) Deploy() error {
authzConfig := authz.Handler.FeatureStore.Status.Applied.AuthzConfig
if authzConfig != nil {
if authzConfig.KubernetesAuthz != nil {
if err := authz.deployKubernetesAuth(authzConfig.KubernetesAuthz); err != nil {
return err
}
} else {
authz.removeOrphanedRoles()
_ = authz.Handler.DeleteOwnedFeastObj(authz.initFeastRole())
_ = authz.Handler.DeleteOwnedFeastObj(authz.initFeastRoleBinding())
}
if authzConfig != nil && authzConfig.KubernetesAuthz != nil {
return authz.deployKubernetesAuth(authzConfig.KubernetesAuthz)
}
authz.removeOrphanedRoles()
_ = authz.Handler.DeleteOwnedFeastObj(authz.initFeastRole())
_ = authz.Handler.DeleteOwnedFeastObj(authz.initFeastRoleBinding())
return nil
}

Expand All @@ -51,6 +46,7 @@ func (authz *FeastAuthorization) deployKubernetesAuth(kubernetesAuth *feastdevv1
}

func (authz *FeastAuthorization) removeOrphanedRoles() {
authzConfig := authz.Handler.FeatureStore.Status.Applied.AuthzConfig
roleList := &rbacv1.RoleList{}
err := authz.Handler.Client.List(context.TODO(), roleList, &client.ListOptions{
Namespace: authz.Handler.FeatureStore.Namespace,
Expand All @@ -61,8 +57,8 @@ func (authz *FeastAuthorization) removeOrphanedRoles() {
}

desiredRoles := []string{}
if authz.Handler.FeatureStore.Status.Applied.AuthzConfig.KubernetesAuthz != nil {
desiredRoles = authz.Handler.FeatureStore.Status.Applied.AuthzConfig.KubernetesAuthz.Roles
if authzConfig != nil && authzConfig.KubernetesAuthz != nil {
desiredRoles = authzConfig.KubernetesAuthz.Roles
}
for _, role := range roleList.Items {
roleName := role.Name
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ var _ = Describe("FeatureStore Controller-Ephemeral services", func() {
Expect(resource.Status.FeastVersion).To(Equal(feastversion.FeastVersion))
Expect(resource.Status.ClientConfigMap).To(Equal(feast.GetFeastServiceName(services.ClientFeastType)))
Expect(resource.Status.Applied.FeastProject).To(Equal(resource.Spec.FeastProject))
Expect(resource.Status.Applied.AuthzConfig).To(Equal(&feastdevv1alpha1.AuthzConfig{}))
Expect(resource.Status.Applied.AuthzConfig).To(BeNil())
Expect(resource.Status.Applied.Services).NotTo(BeNil())
Expect(resource.Status.Applied.Services.OfflineStore).NotTo(BeNil())
Expect(resource.Status.Applied.Services.OfflineStore.Persistence).NotTo(BeNil())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -333,9 +333,9 @@ var _ = Describe("FeatureStore Controller-Kubernetes authorization", func() {
Expect(err).To(HaveOccurred())
Expect(errors.IsNotFound(err)).To(BeTrue())

By("Clearing the kubernetes authorizatino and reconciling")
By("Clearing the kubernetes authorization and reconciling")
resourceNew = resource.DeepCopy()
resourceNew.Spec.AuthzConfig = &feastdevv1alpha1.AuthzConfig{}
resourceNew.Spec.AuthzConfig = nil
err = k8sClient.Update(ctx, resourceNew)
Expect(err).NotTo(HaveOccurred())
_, err = controllerReconciler.Reconcile(ctx, reconcile.Request{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ var _ = Describe("FeatureStore Controller-Ephemeral services", func() {
Expect(resource.Status.FeastVersion).To(Equal(feastversion.FeastVersion))
Expect(resource.Status.ClientConfigMap).To(Equal(feast.GetFeastServiceName(services.ClientFeastType)))
Expect(resource.Status.Applied.FeastProject).To(Equal(resource.Spec.FeastProject))
Expect(resource.Status.Applied.AuthzConfig).To(Equal(&feastdevv1alpha1.AuthzConfig{}))
Expect(resource.Status.Applied.AuthzConfig).To(BeNil())
Expect(resource.Status.Applied.Services).NotTo(BeNil())
Expect(resource.Status.Applied.Services.OfflineStore).To(BeNil())
Expect(resource.Status.Applied.Services.OnlineStore).To(BeNil())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ var _ = Describe("FeatureStore Controller-Ephemeral services", func() {
Expect(resource.Status.FeastVersion).To(Equal(feastversion.FeastVersion))
Expect(resource.Status.ClientConfigMap).To(Equal(feast.GetFeastServiceName(services.ClientFeastType)))
Expect(resource.Status.Applied.FeastProject).To(Equal(resource.Spec.FeastProject))
Expect(resource.Status.Applied.AuthzConfig).To(Equal(&feastdevv1alpha1.AuthzConfig{}))
Expect(resource.Status.Applied.AuthzConfig).To(BeNil())
Expect(resource.Status.Applied.Services).NotTo(BeNil())
Expect(resource.Status.Applied.Services.OfflineStore).NotTo(BeNil())
Expect(resource.Status.Applied.Services.OfflineStore.Persistence).NotTo(BeNil())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ var _ = Describe("FeatureStore Controller", func() {
Expect(resource.Status.ServiceHostnames.OnlineStore).To(BeEmpty())
Expect(resource.Status.ServiceHostnames.Registry).To(Equal(feast.GetFeastServiceName(services.RegistryFeastType) + "." + resource.Namespace + ".svc.cluster.local:80"))
Expect(resource.Status.Applied.FeastProject).To(Equal(resource.Spec.FeastProject))
Expect(resource.Status.Applied.AuthzConfig).To(Equal(&feastdevv1alpha1.AuthzConfig{}))
Expect(resource.Status.Applied.AuthzConfig).To(BeNil())
Expect(resource.Status.Applied.Services).NotTo(BeNil())
Expect(resource.Status.Applied.Services.OfflineStore).To(BeNil())
Expect(resource.Status.Applied.Services.OnlineStore).To(BeNil())
Expand Down Expand Up @@ -458,7 +458,7 @@ var _ = Describe("FeatureStore Controller", func() {
Expect(resource.Status.FeastVersion).To(Equal(feastversion.FeastVersion))
Expect(resource.Status.ClientConfigMap).To(Equal(feast.GetFeastServiceName(services.ClientFeastType)))
Expect(resource.Status.Applied.FeastProject).To(Equal(resource.Spec.FeastProject))
Expect(resource.Status.Applied.AuthzConfig).To(Equal(&feastdevv1alpha1.AuthzConfig{}))
Expect(resource.Status.Applied.AuthzConfig).To(BeNil())
Expect(resource.Status.Applied.Services).NotTo(BeNil())
Expect(resource.Status.Applied.Services.OfflineStore).NotTo(BeNil())
Expect(resource.Status.Applied.Services.OfflineStore.Persistence).NotTo(BeNil())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func (feast *FeastServices) createClientConfigMap() error {

func (feast *FeastServices) setClientConfigMap(cm *corev1.ConfigMap) error {
cm.Labels = feast.getLabels(ClientFeastType)
clientYaml, err := feast.getClientFeatureStoreYaml()
clientYaml, err := feast.getClientFeatureStoreYaml(feast.extractConfigFromSecret)
if err != nil {
return err
}
Expand Down
Loading

0 comments on commit 6e8c611

Please sign in to comment.