Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
feat: Support seperate ports and service for rest-api
Signed-off-by: ntkathole <nikhilkathole2683@gmail.com>
  • Loading branch information
ntkathole committed Jun 10, 2025
commit 06f559c040d3d0ea0f7653a00375f81d76896f33
1 change: 1 addition & 0 deletions infra/feast-operator/api/v1alpha1/featurestore_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -624,6 +624,7 @@ type ServiceHostnames struct {
OfflineStore string `json:"offlineStore,omitempty"`
OnlineStore string `json:"onlineStore,omitempty"`
Registry string `json:"registry,omitempty"`
RegistryRest string `json:"registryRest,omitempty"`
UI string `json:"ui,omitempty"`
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8067,6 +8067,8 @@ spec:
type: string
registry:
type: string
registryRest:
type: string
ui:
type: string
type: object
Expand Down
2 changes: 2 additions & 0 deletions infra/feast-operator/dist/install.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8075,6 +8075,8 @@ spec:
type: string
registry:
type: string
registryRest:
type: string
ui:
type: string
type: object
Expand Down
1 change: 1 addition & 0 deletions infra/feast-operator/docs/api/markdown/ref.md
Original file line number Diff line number Diff line change
Expand Up @@ -773,6 +773,7 @@ _Appears in:_
| `offlineStore` _string_ | |
| `onlineStore` _string_ | |
| `registry` _string_ | |
| `registryRest` _string_ | |
| `ui` _string_ | |


Expand Down
113 changes: 113 additions & 0 deletions infra/feast-operator/internal/controller/services/services.go
Original file line number Diff line number Diff line change
Expand Up @@ -224,8 +224,32 @@ func (feast *FeastServices) deployFeastServiceByType(feastType FeastServiceType)
if err := feast.createService(feastType); err != nil {
return feast.setFeastServiceCondition(err, feastType)
}
// Create REST API service if needed
if feastType == RegistryFeastType && feast.isRegistryServer() {
registry := feast.Handler.FeatureStore.Status.Applied.Services.Registry
if registry.Local.Server.RestAPI != nil && *registry.Local.Server.RestAPI {
if err := feast.createRestService(feastType); err != nil {
Comment thread
ntkathole marked this conversation as resolved.
return feast.setFeastServiceCondition(err, feastType)
}
} else {
// Delete REST API service if REST API is disabled
_ = feast.Handler.DeleteOwnedFeastObj(&corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: feast.GetFeastServiceName(feastType) + "-rest",
Comment thread
tchughesiv marked this conversation as resolved.
Outdated
Namespace: feast.Handler.FeatureStore.Namespace,
},
})
}
}
} else {
_ = feast.Handler.DeleteOwnedFeastObj(feast.initFeastSvc(feastType))
// Delete REST API service if it exists
_ = feast.Handler.DeleteOwnedFeastObj(&corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: feast.GetFeastServiceName(feastType) + "-rest",
Namespace: feast.Handler.FeatureStore.Namespace,
},
})
}
return feast.setFeastServiceCondition(nil, feastType)
}
Expand Down Expand Up @@ -404,6 +428,16 @@ func (feast *FeastServices) setContainer(containers *[]corev1.Container, feastTy
Protocol: corev1.ProtocolTCP,
},
}
if feastType == RegistryFeastType && feast.isRegistryServer() {
registry := feast.Handler.FeatureStore.Status.Applied.Services.Registry
if registry.Local.Server.RestAPI != nil && *registry.Local.Server.RestAPI {
container.Ports = append(container.Ports, corev1.ContainerPort{
Name: name + "-rest",
ContainerPort: getTargetRestPort(feastType, tls),
Protocol: corev1.ProtocolTCP,
})
}
}
Comment thread
tchughesiv marked this conversation as resolved.
Outdated
container.StartupProbe = &corev1.Probe{
ProbeHandler: probeHandler,
PeriodSeconds: 3,
Expand Down Expand Up @@ -509,6 +543,7 @@ func (feast *FeastServices) getContainerCommand(feastType FeastServiceType) []st
}
if registry.Local.Server.RestAPI != nil && *registry.Local.Server.RestAPI {
deploySettings.Args = append(deploySettings.Args, "--rest-api")
deploySettings.Args = append(deploySettings.Args, "--rest-port", strconv.Itoa(int(getTargetRestPort(feastType, tls))))
}
}
if tls.IsTLS() {
Expand Down Expand Up @@ -627,6 +662,70 @@ func (feast *FeastServices) setService(svc *corev1.Service, feastType FeastServi
return controllerutil.SetControllerReference(feast.Handler.FeatureStore, svc, feast.Handler.Scheme)
}

// createRestService creates a separate service for REST API
func (feast *FeastServices) createRestService(feastType FeastServiceType) error {
if feastType != RegistryFeastType || !feast.isRegistryServer() {
return nil
}
Comment thread
ntkathole marked this conversation as resolved.
Outdated

registry := feast.Handler.FeatureStore.Status.Applied.Services.Registry
if registry.Local.Server.RestAPI == nil || !*registry.Local.Server.RestAPI {
return nil
}

svc := &corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Name: feast.GetFeastServiceName(feastType) + "-rest",
Namespace: feast.Handler.FeatureStore.Namespace,
Labels: feast.getFeastTypeLabels(feastType),
},
}
svc.SetGroupVersionKind(corev1.SchemeGroupVersion.WithKind("Service"))

if feast.isOpenShiftTls(feastType) {
if len(svc.Annotations) == 0 {
svc.Annotations = map[string]string{}
}
svc.Annotations["service.beta.openshift.io/serving-cert-secret-name"] = svc.Name + tlsNameSuffix
}

var port int32 = HttpPort
scheme := HttpScheme
tls := feast.getTlsConfigs(feastType)
if tls.IsTLS() {
port = HttpsPort
scheme = HttpsScheme
}

svc.Spec = corev1.ServiceSpec{
Selector: feast.getLabels(),
Type: corev1.ServiceTypeClusterIP,
Ports: []corev1.ServicePort{
{
Name: scheme,
Port: port,
Protocol: corev1.ProtocolTCP,
TargetPort: intstr.FromInt(int(getTargetRestPort(feastType, tls))),
},
},
}

if err := controllerutil.SetControllerReference(feast.Handler.FeatureStore, svc, feast.Handler.Scheme); err != nil {
return err
}

logger := log.FromContext(feast.Handler.Context)
if op, err := controllerutil.CreateOrUpdate(feast.Handler.Context, feast.Handler.Client, svc, controllerutil.MutateFn(func() error {
return nil // No need to mutate as we set everything above
Comment thread
tchughesiv marked this conversation as resolved.
Outdated
})); err != nil {
return err
} else if op == controllerutil.OperationResultCreated || op == controllerutil.OperationResultUpdated {
logger.Info("Successfully reconciled", "Service", svc.Name, "operation", op)
}

return nil
}

func (feast *FeastServices) setServiceAccount(sa *corev1.ServiceAccount) error {
sa.Labels = feast.getLabels()
return controllerutil.SetControllerReference(feast.Handler.FeatureStore, sa, feast.Handler.Scheme)
Expand Down Expand Up @@ -730,8 +829,15 @@ func (feast *FeastServices) setServiceHostnames() error {
}
if feast.isRegistryServer() {
objMeta := feast.initFeastSvc(RegistryFeastType)
registry := feast.Handler.FeatureStore.Status.Applied.Services.Registry
feast.Handler.FeatureStore.Status.ServiceHostnames.Registry = objMeta.Name + "." + objMeta.Namespace + domain +
getPortStr(feast.Handler.FeatureStore.Status.Applied.Services.Registry.Local.Server.TLS)
if registry.Local.Server.RestAPI != nil && *registry.Local.Server.RestAPI {
// Use the REST API service name
restSvcName := objMeta.Name + "-rest"
feast.Handler.FeatureStore.Status.ServiceHostnames.RegistryRest = restSvcName + "." + objMeta.Namespace + domain +
getPortStr(feast.Handler.FeatureStore.Status.Applied.Services.Registry.Local.Server.TLS)
}
} else if feast.isRemoteRegistry() {
return feast.setRemoteRegistryURL()
}
Expand Down Expand Up @@ -1003,6 +1109,13 @@ func getTargetPort(feastType FeastServiceType, tls *feastdevv1alpha1.TlsConfigs)
return FeastServiceConstants[feastType].TargetHttpPort
}

func getTargetRestPort(feastType FeastServiceType, tls *feastdevv1alpha1.TlsConfigs) int32 {
if tls.IsTLS() {
return FeastServiceConstants[feastType].TargetRestHttpsPort
}
return FeastServiceConstants[feastType].TargetRestHttpPort
}

func getProbeHandler(feastType FeastServiceType, tls *feastdevv1alpha1.TlsConfigs) corev1.ProbeHandler {
targetPort := getTargetPort(feastType, tls)
if feastType == OnlineFeastType {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,11 @@ var (
TargetHttpsPort: 6567,
},
RegistryFeastType: {
Args: []string{"serve_registry"},
TargetHttpPort: 6570,
TargetHttpsPort: 6571,
Args: []string{"serve_registry"},
TargetHttpPort: 6570,
TargetHttpsPort: 6571,
TargetRestHttpPort: 6572,
TargetRestHttpsPort: 6573,
},
UIFeastType: {
Args: []string{"ui", "-h", "0.0.0.0"},
Expand Down Expand Up @@ -283,9 +285,11 @@ type AuthzConfig struct {
}

type deploymentSettings struct {
Args []string
TargetHttpPort int32
TargetHttpsPort int32
Args []string
TargetHttpPort int32
TargetHttpsPort int32
TargetRestHttpPort int32
TargetRestHttpsPort int32
}

// CustomCertificatesBundle represents a custom CA bundle configuration
Expand Down
Loading