diff --git a/config/base/kustomization.yaml b/config/base/kustomization.yaml index 7e488d2..1c5f68c 100644 --- a/config/base/kustomization.yaml +++ b/config/base/kustomization.yaml @@ -37,4 +37,11 @@ vars: name: config apiVersion: v1 fieldref: - fieldpath: data.trustyaiOperatorImage \ No newline at end of file + fieldpath: data.trustyaiOperatorImage + - name: oauthProxyImage + objref: + kind: ConfigMap + name: config + apiVersion: v1 + fieldref: + fieldpath: data.oauthProxyImage \ No newline at end of file diff --git a/config/base/params.env b/config/base/params.env index d05cce3..a5d271b 100644 --- a/config/base/params.env +++ b/config/base/params.env @@ -1,2 +1,3 @@ trustyaiServiceImage=quay.io/trustyai/trustyai-service:latest -trustyaiOperatorImage=quay.io/trustyai/trustyai-service-operator:latest \ No newline at end of file +trustyaiOperatorImage=quay.io/trustyai/trustyai-service-operator:latest +oauthProxyImage=registry.redhat.io/openshift4/ose-oauth-proxy:latest \ No newline at end of file diff --git a/controllers/config_maps.go b/controllers/config_maps.go new file mode 100644 index 0000000..795a348 --- /dev/null +++ b/controllers/config_maps.go @@ -0,0 +1,46 @@ +package controllers + +import ( + "context" + "fmt" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/types" +) + +// getImageFromConfigMap gets a custom image value from a ConfigMap in the operator's namespace +func (r *TrustyAIServiceReconciler) getImageFromConfigMap(ctx context.Context, key string, defaultImage string) (string, error) { + if r.Namespace != "" { + // Define the key for the ConfigMap + configMapKey := types.NamespacedName{ + Namespace: r.Namespace, + Name: imageConfigMap, + } + + // Create an empty ConfigMap object + var cm corev1.ConfigMap + + // Try to get the ConfigMap + if err := r.Get(ctx, configMapKey, &cm); err != nil { + if errors.IsNotFound(err) { + // ConfigMap not found, fallback to default values + return defaultImage, nil + } + // Other error occurred when trying to fetch the ConfigMap + return defaultImage, fmt.Errorf("error reading configmap %s", configMapKey) + } + + // ConfigMap is found, extract the image and tag + image, ok := cm.Data[key] + + if !ok { + // One or both of the keys are not present in the ConfigMap, return error + return defaultImage, fmt.Errorf("configmap %s does not contain necessary keys", configMapKey) + } + + // Return the image and tag + return image, nil + } else { + return defaultImage, nil + } +} diff --git a/controllers/constants.go b/controllers/constants.go index 1bff24f..fa5ca30 100644 --- a/controllers/constants.go +++ b/controllers/constants.go @@ -13,15 +13,15 @@ const ( modelMeshLabelValue = "modelmesh-serving" volumeMountName = "volume" defaultRequeueDelay = time.Minute + imageConfigMap = "trustyai-service-operator-config" ) // OAuth constants const ( - OAuthServicePort = 443 - OAuthName = "oauth-proxy" - OAuthServicePortName = "oauth-proxy" - OAuthProxyImage = "registry.redhat.io/openshift4/ose-oauth-proxy:latest" - ServiceAccountName = componentName + OAuthServicePort = 443 + OAuthName = "oauth-proxy" + OAuthServicePortName = "oauth-proxy" + defaultOAuthProxyImage = "registry.redhat.io/openshift4/ose-oauth-proxy:latest" ) // Status types diff --git a/controllers/deployment.go b/controllers/deployment.go index 648aea4..cff9b70 100644 --- a/controllers/deployment.go +++ b/controllers/deployment.go @@ -31,7 +31,12 @@ func (r *TrustyAIServiceReconciler) createDeploymentObject(ctx context.Context, } // Create the OAuth-Proxy container spec - oauthProxyContainer := generateOAuthProxyContainer(cr, OAuthConfig{ProxyImage: OAuthProxyImage}) + + oauthProxyImage, err := r.getImageFromConfigMap(ctx, "oauthProxyImage", defaultOAuthProxyImage) + if err != nil { + log.FromContext(ctx).Error(err, "Error getting OAuth image from ConfigMap. Using the default image value of "+defaultOAuthProxyImage) + } + oauthProxyContainer := generateOAuthProxyContainer(cr, oauthProxyImage) containers := []corev1.Container{ { @@ -84,7 +89,7 @@ func (r *TrustyAIServiceReconciler) createDeploymentObject(ctx context.Context, }, }, } - volumes := generateOAuthVolumes(cr, OAuthConfig{ProxyImage: OAuthProxyImage}) + volumes := generateOAuthVolumes(cr, OAuthConfig{ProxyImage: defaultOAuthProxyImage}) volumes = append(volumes, volume) @@ -158,7 +163,7 @@ func (r *TrustyAIServiceReconciler) ensureDeployment(ctx context.Context, instan // Get image and tag from ConfigMap // If there's a ConfigMap with custom images, it is only applied when the operator is first deployed // Changing (or creating) the ConfigMap after the operator is deployed will not have any effect - image, err := r.getImageFromConfigMap(ctx) + image, err := r.getImageFromConfigMap(ctx, "trustyaiServiceImage", defaultImage) if err != nil { return err } diff --git a/controllers/oauth.go b/controllers/oauth.go index 2bfba80..0317a13 100644 --- a/controllers/oauth.go +++ b/controllers/oauth.go @@ -19,10 +19,10 @@ type OAuthConfig struct { } // generateOAuthProxyContainer create the OAuth-proxy container object for a TrustyAI service instance -func generateOAuthProxyContainer(instance *trustyaiopendatahubiov1alpha1.TrustyAIService, oauth OAuthConfig) corev1.Container { +func generateOAuthProxyContainer(instance *trustyaiopendatahubiov1alpha1.TrustyAIService, oauthProxyImage string) corev1.Container { proxyContainer := corev1.Container{ Name: OAuthName, - Image: oauth.ProxyImage, + Image: oauthProxyImage, ImagePullPolicy: corev1.PullAlways, Env: []corev1.EnvVar{{ Name: "NAMESPACE", diff --git a/controllers/trustyaiservice_controller.go b/controllers/trustyaiservice_controller.go index fb1068f..14db50b 100644 --- a/controllers/trustyaiservice_controller.go +++ b/controllers/trustyaiservice_controller.go @@ -19,7 +19,6 @@ package controllers import ( "context" goerrors "errors" - "fmt" kservev1alpha1 "github.com/kserve/kserve/pkg/apis/serving/v1alpha1" kservev1beta1 "github.com/kserve/kserve/pkg/apis/serving/v1beta1" trustyaiopendatahubiov1alpha1 "github.com/trustyai-explainability/trustyai-service-operator/api/v1alpha1" @@ -29,7 +28,6 @@ import ( apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" - "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/client-go/tools/record" ctrl "sigs.k8s.io/controller-runtime" @@ -294,40 +292,3 @@ func (r *TrustyAIServiceReconciler) SetupWithManager(mgr ctrl.Manager) error { Watches(&source.Kind{Type: &kservev1alpha1.ServingRuntime{}}, &handler.EnqueueRequestForObject{}). Complete(r) } - -// getTrustyAIImageAndTagFromConfigMap gets a custom TrustyAI image and tag from a ConfigMap in the operator's namespace -func (r *TrustyAIServiceReconciler) getImageFromConfigMap(ctx context.Context) (string, error) { - if r.Namespace != "" { - // Define the key for the ConfigMap - configMapKey := types.NamespacedName{ - Namespace: r.Namespace, - Name: "trustyai-service-operator-config", - } - - // Create an empty ConfigMap object - var cm corev1.ConfigMap - - // Try to get the ConfigMap - if err := r.Get(ctx, configMapKey, &cm); err != nil { - if errors.IsNotFound(err) { - // ConfigMap not found, fallback to default values - return defaultImage, nil - } - // Other error occurred when trying to fetch the ConfigMap - return defaultImage, fmt.Errorf("error reading configmap %s", configMapKey) - } - - // ConfigMap is found, extract the image and tag - image, ok := cm.Data["trustyaiServiceImage"] - - if !ok { - // One or both of the keys are not present in the ConfigMap, return error - return defaultImage, fmt.Errorf("configmap %s does not contain necessary keys", configMapKey) - } - - // Return the image and tag - return image, nil - } else { - return defaultImage, nil - } -}