Skip to content

Commit

Permalink
Add support for creating a route for ModelRegistry http REST service, f…
Browse files Browse the repository at this point in the history
  • Loading branch information
dhirajsb committed Nov 17, 2023
1 parent 5c1b0db commit 600fe05
Show file tree
Hide file tree
Showing 11 changed files with 108 additions and 11 deletions.
5 changes: 5 additions & 0 deletions api/v1alpha1/modelregistry_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,11 @@ type RestSpec struct {
// Listen port for REST connections, defaults to 8080.
Port *int32 `json:"port,omitempty"`

//+kubebuilder:validation:Enum=disabled;enabled
//+kubebuilder:default=disabled
// Create an OpenShift Route for REST Service
ServiceRoute string `json:"serviceRoute,omitempty"`

// Resource requirements
//+optional
Resources *v1.ResourceRequirements `json:"resources,omitempty"`
Expand Down
4 changes: 4 additions & 0 deletions api/v1alpha1/modelregistry_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ func (r *ModelRegistry) Default() {
if len(r.Spec.Grpc.Image) == 0 {
r.Spec.Grpc.Image = config.GetStringConfigWithDefault(config.GrpcImage, config.DefaultGrpcImage)
}

if len(r.Spec.Rest.ServiceRoute) == 0 {
r.Spec.Rest.ServiceRoute = config.RouteDisabled
}
if r.Spec.Rest.Resources == nil {
r.Spec.Rest.Resources = config.MlmdRestResourceRequirements.DeepCopy()
}
Expand Down
17 changes: 17 additions & 0 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package main

import (
"flag"
"k8s.io/client-go/discovery"
"os"

"github.com/opendatahub-io/model-registry-operator/internal/controller/config"
Expand All @@ -26,6 +27,7 @@ import (
// to ensure that exec-entrypoint and run can make use of them.
_ "k8s.io/client-go/plugin/pkg/client/auth"

oapi "github.com/openshift/api"
"k8s.io/apimachinery/pkg/runtime"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
Expand All @@ -48,6 +50,7 @@ const EnableWebhooks = "ENABLE_WEBHOOKS"

func init() {
utilruntime.Must(clientgoscheme.AddToScheme(scheme))
utilruntime.Must(oapi.Install(scheme))

utilruntime.Must(modelregistryv1alpha1.AddToScheme(scheme))
//+kubebuilder:scaffold:scheme
Expand Down Expand Up @@ -100,6 +103,19 @@ func main() {
}
setupLog.Info("parsed kubernetes templates", "templates", template.DefinedTemplates())

discoveryClient := discovery.NewDiscoveryClientForConfigOrDie(mgr.GetConfig())
groups, err := discoveryClient.ServerGroups()
if err != nil {
setupLog.Error(err, "error discovering server groups")
os.Exit(1)
}
isOpenShift := false
for _, g := range groups.Groups {
if g.Name == "route.openshift.io" {
isOpenShift = true
}
}

enableWebhooks := os.Getenv(EnableWebhooks) != "false"
if err = (&controller.ModelRegistryReconciler{
Client: mgr.GetClient(),
Expand All @@ -108,6 +124,7 @@ func main() {
Log: ctrl.Log.WithName("controller"),
Template: template,
EnableWebhooks: enableWebhooks,
IsOpenShift: isOpenShift,
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "ModelRegistry")
os.Exit(1)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,13 @@ spec:
Limits. More info: https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/'
type: object
type: object
serviceRoute:
default: disabled
description: Create an OpenShift Route for REST Service
enum:
- disabled
- enabled
type: string
type: object
required:
- grpc
Expand Down
1 change: 1 addition & 0 deletions config/samples/modelregistry_v1alpha1_modelregistry.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ spec:
port: 9090
rest:
port: 8080
serviceRoute: disabled
postgres:
host: model-registry-db
database: model-registry
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ require (
github.com/go-logr/logr v1.3.0
github.com/onsi/ginkgo/v2 v2.13.1
github.com/onsi/gomega v1.30.0
github.com/openshift/api v0.0.0-20231116201359-a5824a0c15b6
github.com/spf13/viper v1.17.0
k8s.io/api v0.28.3
k8s.io/apimachinery v0.28.3
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,8 @@ github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGV
github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.30.0 h1:hvMK7xYz4D3HapigLTeGdId/NcfQx1VHMJc60ew99+8=
github.com/onsi/gomega v1.30.0/go.mod h1:9sxs+SwGrKI0+PWe4Fxa9tFQQBG5xSsSbMXOI8PPpoQ=
github.com/openshift/api v0.0.0-20231116201359-a5824a0c15b6 h1:4RuImZKF08UNKj3vt77jPLDdWIKOXudGhPSV25Vwca8=
github.com/openshift/api v0.0.0-20231116201359-a5824a0c15b6/go.mod h1:qNtV0315F+f8ld52TLtPvrfivZpdimOzTi3kn9IVbtU=
github.com/pelletier/go-toml/v2 v2.1.0 h1:FnwAJ4oYMvbT/34k9zzHuZNrhlz48GB3/s6at6/MHO4=
github.com/pelletier/go-toml/v2 v2.1.0/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
Expand Down
2 changes: 2 additions & 0 deletions internal/controller/config/defaults.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ const (
RestImage = "REST_IMAGE"
DefaultGrpcImage = "gcr.io/tfx-oss-public/ml_metadata_store_server:1.14.0"
DefaultRestImage = "quay.io/opendatahub/model-registry:latest"
RouteDisabled = "disabled"
RouteEnabled = "enabled"
)

// Default ResourceRequirements
Expand Down
14 changes: 14 additions & 0 deletions internal/controller/config/templates/http-route.yaml.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
apiVersion: route.openshift.io/v1
kind: Route
metadata:
name: {{.Name}}-http
namespace: {{.Namespace}}
labels:
app: {{.Name}}
component: model-registry
spec:
to:
kind: Service
name: {{.Name}}
port:
targetPort: http-api
61 changes: 51 additions & 10 deletions internal/controller/modelregistry_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ import (
"fmt"
"github.com/banzaicloud/k8s-objectmatcher/patch"
"github.com/go-logr/logr"
modelregistryv1alpha1 "github.com/opendatahub-io/model-registry-operator/api/v1alpha1"
"github.com/opendatahub-io/model-registry-operator/internal/controller/config"
routev1 "github.com/openshift/api/route/v1"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
Expand All @@ -35,8 +38,6 @@ import (
klog "sigs.k8s.io/controller-runtime/pkg/log"
"strings"
"text/template"

modelregistryv1alpha1 "github.com/opendatahub-io/model-registry-operator/api/v1alpha1"
)

const modelRegistryFinalizer = "modelregistry.opendatahub.io/finalizer"
Expand Down Expand Up @@ -65,6 +66,7 @@ type ModelRegistryReconciler struct {
Log logr.Logger
Template *template.Template
EnableWebhooks bool
IsOpenShift bool
}

// Reconcile is part of the main kubernetes reconciliation loop which aims to
Expand Down Expand Up @@ -215,12 +217,15 @@ func IgnoreDeletingErrors(err error) error {

// SetupWithManager sets up the controller with the Manager.
func (r *ModelRegistryReconciler) SetupWithManager(mgr ctrl.Manager) error {
return ctrl.NewControllerManagedBy(mgr).
builder := ctrl.NewControllerManagedBy(mgr).
For(&modelregistryv1alpha1.ModelRegistry{}).
Owns(&corev1.Service{}).
Owns(&corev1.ServiceAccount{}).
Owns(&appsv1.Deployment{}).
Complete(r)
Owns(&appsv1.Deployment{})
if r.IsOpenShift {
builder = builder.Owns(&routev1.Route{})
}
return builder.Complete(r)
}

//+kubebuilder:rbac:groups=modelregistry.opendatahub.io,resources=modelregistries,verbs=get;list;watch;create;update;patch;delete
Expand All @@ -232,7 +237,7 @@ func (r *ModelRegistryReconciler) SetupWithManager(mgr ctrl.Manager) error {
//+kubebuilder:rbac:groups=core,resources=services;serviceaccounts,verbs=get;list;watch;create;update;patch;delete

func (r *ModelRegistryReconciler) updateRegistryResources(ctx context.Context, params *ModelRegistryParams, registry *modelregistryv1alpha1.ModelRegistry) (OperationResult, error) {
var result, result2, result3 OperationResult
var result, result2 OperationResult

var err error
result, err = r.createOrUpdateServiceAccount(ctx, params, registry, "serviceaccount.yaml.tmpl")
Expand All @@ -248,12 +253,22 @@ func (r *ModelRegistryReconciler) updateRegistryResources(ctx context.Context, p
result = result2
}

result3, err = r.createOrUpdateDeployment(ctx, params, registry, "deployment.yaml.tmpl")
if r.IsOpenShift {
result2, err = r.createOrUpdateRoute(ctx, params, registry, "http-route.yaml.tmpl")
if err != nil {
return result2, err
}
if result2 != ResourceUnchanged {
result = result2
}
}

result2, err = r.createOrUpdateDeployment(ctx, params, registry, "deployment.yaml.tmpl")
if err != nil {
return result3, err
return result2, err
}
if result3 != ResourceUnchanged {
result = result3
if result2 != ResourceUnchanged {
result = result2
}

return result, nil
Expand Down Expand Up @@ -341,6 +356,32 @@ func (r *ModelRegistryReconciler) createOrUpdateDeployment(ctx context.Context,
return result, nil
}

func (r *ModelRegistryReconciler) createOrUpdateRoute(ctx context.Context, params *ModelRegistryParams,
registry *modelregistryv1alpha1.ModelRegistry, templateName string) (result OperationResult, err error) {
result = ResourceUnchanged
var route routev1.Route
if err = r.Apply(params, templateName, &route); err != nil {
return result, err
}
if err = ctrl.SetControllerReference(registry, &route, r.Scheme); err != nil {
return result, err
}

if registry.Spec.Rest.ServiceRoute == config.RouteEnabled {
if result, err = r.createOrUpdate(ctx, route.DeepCopy(), &route); err != nil {
return result, err
}
} else {
// delete the route if it exists
if err = r.Client.Delete(ctx, &route); client.IgnoreNotFound(err) != nil {
result = ResourceUpdated
return result, err
}
}

return result, nil
}

func (r *ModelRegistryReconciler) createOrUpdateService(ctx context.Context, params *ModelRegistryParams,
registry *modelregistryv1alpha1.ModelRegistry, templateName string) (result OperationResult, err error) {
result = ResourceUnchanged
Expand Down
5 changes: 4 additions & 1 deletion internal/controller/modelregistry_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"context"
"fmt"
"github.com/opendatahub-io/model-registry-operator/internal/controller/config"
"github.com/openshift/api"
"k8s.io/apimachinery/pkg/api/meta"
"k8s.io/client-go/tools/record"
"os"
Expand Down Expand Up @@ -135,9 +136,11 @@ var _ = Describe("ModelRegistry controller", func() {
return k8sClient.Get(ctx, typeNamespaceName, found)
}, time.Minute, time.Second).Should(Succeed())

scheme := k8sClient.Scheme()
_ = api.Install(scheme)
modelRegistryReconciler := &ModelRegistryReconciler{
Client: k8sClient,
Scheme: k8sClient.Scheme(),
Scheme: scheme,
Recorder: &record.FakeRecorder{},
Log: ctrl.Log.WithName("controller"),
Template: template,
Expand Down

0 comments on commit 600fe05

Please sign in to comment.