Skip to content

Commit

Permalink
feat: Add Operator support for spec.feastProject & status.applied fie…
Browse files Browse the repository at this point in the history
…lds (feast-dev#4656)

spec.feastProject & status.applied logic

Signed-off-by: Tommy Hughes <tohughes@redhat.com>
  • Loading branch information
tchughesiv authored Oct 29, 2024
1 parent a61b93c commit 430ac53
Show file tree
Hide file tree
Showing 16 changed files with 1,237 additions and 42 deletions.
20 changes: 20 additions & 0 deletions infra/feast-operator/api/feastversion/version.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
Copyright 2024 Feast Community.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package feastversion

// Feast release version
const FeastVersion = "0.40.0"
45 changes: 40 additions & 5 deletions infra/feast-operator/api/v1alpha1/featurestore_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,24 +20,59 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN!
// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized.
const (
// Feast phases:
ReadyPhase = "Ready"
PendingPhase = "Pending"
FailedPhase = "Failed"

// Feast condition types:
ClientReadyType = "Client"
RegistryReadyType = "Registry"
ReadyType = "FeatureStore"

// Feast condition reasons:
ReadyReason = "Ready"
FailedReason = "FeatureStoreFailed"
RegistryFailedReason = "RegistryDeploymentFailed"
ClientFailedReason = "ClientDeploymentFailed"

// Feast condition messages:
ReadyMessage = "FeatureStore installation complete"
RegistryReadyMessage = "Registry installation complete"
ClientReadyMessage = "Client installation complete"

// entity_key_serialization_version
SerializationVersion = 3
)

// FeatureStoreSpec defines the desired state of FeatureStore
type FeatureStoreSpec struct {
// +kubebuilder:validation:Pattern="^[A-Za-z0-9][A-Za-z0-9_]*$"
// FeastProject is the Feast project id. This can be any alphanumeric string with underscores, but it cannot start with an underscore.
// FeastProject is the Feast project id. This can be any alphanumeric string with underscores, but it cannot start with an underscore. Required.
FeastProject string `json:"feastProject"`
}

// FeatureStoreStatus defines the observed state of FeatureStore
type FeatureStoreStatus struct {
// INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
// Important: Run "make" to regenerate code after modifying this file
Applied FeatureStoreSpec `json:"applied,omitempty"`
ClientConfigMap string `json:"clientConfigMap,omitempty"`
Conditions []metav1.Condition `json:"conditions,omitempty"`
FeastVersion string `json:"feastVersion,omitempty"`
Phase string `json:"phase,omitempty"`
ServiceUrls ServiceUrls `json:"serviceUrls,omitempty"`
}

// ServiceUrls
type ServiceUrls struct {
Registry string `json:"registry,omitempty"`
}

//+kubebuilder:object:root=true
//+kubebuilder:subresource:status
//+kubebuilder:resource:shortName=feast
//+kubebuilder:printcolumn:name="Status",type=string,JSONPath=`.status.phase`
//+kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp`

// FeatureStore is the Schema for the featurestores API
type FeatureStore struct {
Expand Down
27 changes: 26 additions & 1 deletion 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 @@ -8,17 +8,15 @@ metadata:
"apiVersion": "feast.dev/v1alpha1",
"kind": "FeatureStore",
"metadata": {
"labels": {
"app.kubernetes.io/managed-by": "kustomize",
"app.kubernetes.io/name": "feast-operator"
},
"name": "featurestore-sample"
"name": "sample"
},
"spec": null
"spec": {
"feastProject": "my_project"
}
}
]
capabilities: Basic Install
createdAt: "2024-10-09T16:16:53Z"
createdAt: "2024-10-21T16:35:01Z"
operators.operatorframework.io/builder: operator-sdk-v1.37.0
operators.operatorframework.io/project_layout: go.kubebuilder.io/v4
name: feast-operator.v0.40.0
Expand All @@ -41,6 +39,29 @@ spec:
spec:
clusterPermissions:
- rules:
- apiGroups:
- apps
resources:
- deployments
verbs:
- create
- delete
- get
- list
- update
- watch
- apiGroups:
- ""
resources:
- configmaps
- services
verbs:
- create
- delete
- get
- list
- update
- watch
- apiGroups:
- feast.dev
resources:
Expand Down
107 changes: 105 additions & 2 deletions infra/feast-operator/bundle/manifests/feast.dev_featurestores.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,19 @@ spec:
kind: FeatureStore
listKind: FeatureStoreList
plural: featurestores
shortNames:
- feast
singular: featurestore
scope: Namespaced
versions:
- name: v1alpha1
- additionalPrinterColumns:
- jsonPath: .status.phase
name: Status
type: string
- jsonPath: .metadata.creationTimestamp
name: Age
type: date
name: v1alpha1
schema:
openAPIV3Schema:
description: FeatureStore is the Schema for the featurestores API
Expand Down Expand Up @@ -42,14 +51,108 @@ spec:
feastProject:
description: FeastProject is the Feast project id. This can be any
alphanumeric string with underscores, but it cannot start with an
underscore.
underscore. Required.
pattern: ^[A-Za-z0-9][A-Za-z0-9_]*$
type: string
required:
- feastProject
type: object
status:
description: FeatureStoreStatus defines the observed state of FeatureStore
properties:
applied:
description: FeatureStoreSpec defines the desired state of FeatureStore
properties:
feastProject:
description: FeastProject is the Feast project id. This can be
any alphanumeric string with underscores, but it cannot start
with an underscore. Required.
pattern: ^[A-Za-z0-9][A-Za-z0-9_]*$
type: string
required:
- feastProject
type: object
clientConfigMap:
type: string
conditions:
items:
description: "Condition contains details for one aspect of the current
state of this API Resource.\n---\nThis struct is intended for
direct use as an array at the field path .status.conditions. For
example,\n\n\n\ttype FooStatus struct{\n\t // Represents the
observations of a foo's current state.\n\t // Known .status.conditions.type
are: \"Available\", \"Progressing\", and \"Degraded\"\n\t //
+patchMergeKey=type\n\t // +patchStrategy=merge\n\t // +listType=map\n\t
\ // +listMapKey=type\n\t Conditions []metav1.Condition `json:\"conditions,omitempty\"
patchStrategy:\"merge\" patchMergeKey:\"type\" protobuf:\"bytes,1,rep,name=conditions\"`\n\n\n\t
\ // other fields\n\t}"
properties:
lastTransitionTime:
description: |-
lastTransitionTime is the last time the condition transitioned from one status to another.
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
format: date-time
type: string
message:
description: |-
message is a human readable message indicating details about the transition.
This may be an empty string.
maxLength: 32768
type: string
observedGeneration:
description: |-
observedGeneration represents the .metadata.generation that the condition was set based upon.
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
with respect to the current state of the instance.
format: int64
minimum: 0
type: integer
reason:
description: |-
reason contains a programmatic identifier indicating the reason for the condition's last transition.
Producers of specific condition types may define expected values and meanings for this field,
and whether the values are considered a guaranteed API.
The value should be a CamelCase string.
This field may not be empty.
maxLength: 1024
minLength: 1
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
type: string
status:
description: status of the condition, one of True, False, Unknown.
enum:
- "True"
- "False"
- Unknown
type: string
type:
description: |-
type of condition in CamelCase or in foo.example.com/CamelCase.
---
Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be
useful (see .node.status.conditions), the ability to deconflict is important.
The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt)
maxLength: 316
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
type: string
required:
- lastTransitionTime
- message
- reason
- status
- type
type: object
type: array
feastVersion:
type: string
phase:
type: string
serviceUrls:
description: ServiceUrls
properties:
registry:
type: string
type: object
type: object
type: object
served: true
Expand Down
9 changes: 9 additions & 0 deletions infra/feast-operator/cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,12 @@ import (
// to ensure that exec-entrypoint and run can make use of them.
_ "k8s.io/client-go/plugin/pkg/client/auth"

corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/runtime"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/healthz"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
Expand Down Expand Up @@ -116,6 +118,13 @@ func main() {
// if you are doing or is intended to do any operation such as perform cleanups
// after the manager stops then its usage might be unsafe.
// LeaderElectionReleaseOnCancel: true,
Client: client.Options{
Cache: &client.CacheOptions{
DisableFor: []client.Object{
&corev1.ConfigMap{},
},
},
},
})
if err != nil {
setupLog.Error(err, "unable to start manager")
Expand Down
Loading

0 comments on commit 430ac53

Please sign in to comment.