Skip to content

Commit

Permalink
Add check if DestinationRule CRD is present before creating it (trust…
Browse files Browse the repository at this point in the history
…yai-explainability#316)

* Add check for DestinationRule CRD

* Add API extensions to operator's scheme

* Add permission for CRD resource
  • Loading branch information
ruivieira authored Oct 10, 2024
1 parent 97a5a5d commit d11408c
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 4 deletions.
8 changes: 8 additions & 0 deletions config/rbac/role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,14 @@ rules:
- list
- update
- watch
- apiGroups:
- apiextensions.k8s.io
resources:
- customresourcedefinitions
verbs:
- get
- list
- watch
- apiGroups:
- apps
resources:
Expand Down
20 changes: 20 additions & 0 deletions controllers/destination_rule.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (

trustyaiopendatahubiov1alpha1 "github.com/trustyai-explainability/trustyai-service-operator/api/v1alpha1"
templateParser "github.com/trustyai-explainability/trustyai-service-operator/controllers/templates"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/types"
Expand All @@ -16,6 +17,7 @@ import (

const (
destinationRuleTemplatePath = "service/destination-rule.tmpl.yaml"
destinationRuleCDRName = "destinationrules.networking.istio.io"
)

// DestinationRuleConfig has the variables for the DestinationRule template
Expand All @@ -25,7 +27,25 @@ type DestinationRuleConfig struct {
DestinationRuleName string
}

// isDestinationRuleCRDPresent returns true if the DestinationRule CRD is present, false otherwise
func (r *TrustyAIServiceReconciler) isDestinationRuleCRDPresent(ctx context.Context) (bool, error) {
crd := &apiextensionsv1.CustomResourceDefinition{}

err := r.Get(ctx, types.NamespacedName{Name: destinationRuleCDRName}, crd)
if err != nil {
if !errors.IsNotFound(err) {
return false, fmt.Errorf("error getting "+destinationRuleCDRName+" CRD: %v", err)
}
// Not found
return false, nil
}

// Found
return true, nil
}

func (r *TrustyAIServiceReconciler) ensureDestinationRule(ctx context.Context, instance *trustyaiopendatahubiov1alpha1.TrustyAIService) error {

destinationRuleName := instance.Name + "-internal"

existingDestinationRule := &unstructured.Unstructured{}
Expand Down
20 changes: 18 additions & 2 deletions controllers/inference_services.go
Original file line number Diff line number Diff line change
Expand Up @@ -275,10 +275,26 @@ func (r *TrustyAIServiceReconciler) patchKServe(ctx context.Context, instance *t
// Only if the Istio sidecar annotation is set
annotations := infService.GetAnnotations()
if inject, exists := annotations["sidecar.istio.io/inject"]; exists && inject == "true" {
err := r.ensureDestinationRule(ctx, instance)

// Check if DestinationRule CRD is present. If there's an error, don't proceed and return the error
exists, err := r.isDestinationRuleCRDPresent(ctx)
if err != nil {
return fmt.Errorf("failed to ensure DestinationRule: %v", err)
log.FromContext(ctx).Error(err, "Error verifying DestinationRule CRD is present")
return err
}

// Try to create the DestinationRule, since CRD exists
if exists {
err := r.ensureDestinationRule(ctx, instance)
if err != nil {
return fmt.Errorf("failed to ensure DestinationRule: %v", err)
}
} else {
// DestinationRule CRD does not exist. Do not attempt to create it and log error
err := fmt.Errorf("the DestinationRule CRD is not present in this cluster")
log.FromContext(ctx).Error(err, "InferenceService has service mesh annotation but DestinationRule CRD not found")
}

}

// Update the InferenceService
Expand Down
1 change: 1 addition & 0 deletions controllers/trustyaiservice_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ type TrustyAIServiceReconciler struct {
//+kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=clusterrolebindings,verbs=get;list;watch;create;update;delete
//+kubebuilder:rbac:groups=coordination.k8s.io,resources=leases,verbs=get;create;update
//+kubebuilder:rbac:groups=networking.istio.io,resources=destinationrules,verbs=create;list;watch;get;update;patch;delete
//+kubebuilder:rbac:groups=apiextensions.k8s.io,resources=customresourcedefinitions,verbs=list;watch;get

// Reconcile is part of the main kubernetes reconciliation loop which aims to
// move the current state of the cluster closer to the desired state.
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ require (
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/apiextensions-apiserver v0.26.4 // indirect
k8s.io/apiextensions-apiserver v0.26.4
k8s.io/component-base v0.26.4 // indirect
k8s.io/klog/v2 v2.100.1 // indirect
k8s.io/kube-openapi v0.0.0-20230515203736-54b630e78af5 // indirect
Expand Down
5 changes: 4 additions & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,13 @@ package main

import (
"flag"
"os"

kservev1alpha1 "github.com/kserve/kserve/pkg/apis/serving/v1alpha1"
kservev1beta1 "github.com/kserve/kserve/pkg/apis/serving/v1beta1"
routev1 "github.com/openshift/api/route/v1"
monitoringv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
"os"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"

// Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.)
// to ensure that exec-entrypoint and run can make use of them.
Expand Down Expand Up @@ -52,6 +54,7 @@ func init() {
utilruntime.Must(kservev1alpha1.AddToScheme(scheme))
utilruntime.Must(kservev1beta1.AddToScheme(scheme))
utilruntime.Must(routev1.AddToScheme(scheme))
utilruntime.Must(apiextensionsv1.AddToScheme(scheme))
//+kubebuilder:scaffold:scheme
}

Expand Down

0 comments on commit d11408c

Please sign in to comment.