diff --git a/api/v1alpha1/dspipeline_types.go b/api/v1alpha1/dspipeline_types.go index 1dcb30a9c..2401a0e09 100644 --- a/api/v1alpha1/dspipeline_types.go +++ b/api/v1alpha1/dspipeline_types.go @@ -86,6 +86,19 @@ type APIServer struct { // for the api server to use instead. CustomServerConfig *ScriptConfigMap `json:"customServerConfigMap,omitempty"` + // When specified, the `data` contents of the `kfp-launcher` ConfigMap that DSPO writes + // will be fully replaced with the `data` contents of the ConfigMap specified here. + // This allows the user to fully replace the `data` contents of the kfp-launcher ConfigMap. + // The `kfp-launcher` component requires a ConfigMap to exist in the namespace + // where it runs (i.e. the namespace where pipelines run). This ConfigMap contains + // object storage configuration, as well as pipeline root (object store root path + // where artifacts will be uploaded) configuration. Currently this ConfigMap *must* + // be named "kfp-launcher". We currently deploy a default copy of the kfp-launcher + // ConfigMap via DSPO, but a user may want to provide their own ConfigMap configuration, + // so that they can specify multiple object storage sources and paths. + // +kubebuilder:validation:Optional + CustomKfpLauncherConfigMap string `json:"customKfpLauncherConfigMap,omitempty"` + // Default: true // Deprecated: DSP V1 only, will be removed in the future. // +kubebuilder:default:=true diff --git a/config/crd/bases/datasciencepipelinesapplications.opendatahub.io_datasciencepipelinesapplications.yaml b/config/crd/bases/datasciencepipelinesapplications.opendatahub.io_datasciencepipelinesapplications.yaml index a8af2afb7..3f4e8d8aa 100644 --- a/config/crd/bases/datasciencepipelinesapplications.opendatahub.io_datasciencepipelinesapplications.yaml +++ b/config/crd/bases/datasciencepipelinesapplications.opendatahub.io_datasciencepipelinesapplications.yaml @@ -112,6 +112,21 @@ spec: description: 'Default: true Deprecated: DSP V1 only, will be removed in the future.' type: boolean + customKfpLauncherConfigMap: + description: "When specified, the `data` contents of the `kfp-launcher` + ConfigMap that DSPO writes will be fully replaced with the `data` + contents of the ConfigMap specified here. This allows the user + to fully replace the `data` contents of the kfp-launcher ConfigMap. + The `kfp-launcher` component requires a ConfigMap to exist in + the namespace where it runs (i.e. the\tnamespace where\tpipelines + run).\tThis ConfigMap contains object storage configuration, + as well as pipeline root (object store root path where artifacts + will be uploaded) configuration. Currently this ConfigMap *must* + be named \"kfp-launcher\". We currently deploy a default copy + of the kfp-launcher ConfigMap via DSPO, but a user may want + to provide their own ConfigMap configuration, so that they can + specify multiple object storage sources and paths." + type: string customServerConfigMap: description: CustomServerConfig is a custom config file that you can provide for the api server to use instead. diff --git a/config/internal/apiserver/default/kfp_launcher_config.yaml.tmpl b/config/internal/apiserver/default/kfp_launcher_config.yaml.tmpl index 1d497b584..8d85bf00b 100644 --- a/config/internal/apiserver/default/kfp_launcher_config.yaml.tmpl +++ b/config/internal/apiserver/default/kfp_launcher_config.yaml.tmpl @@ -1,5 +1,8 @@ apiVersion: v1 data: + {{ if .APIServer.CustomKfpLauncherConfigMap }} + {{.CustomKfpLauncherConfigMapData}} + {{ else }} {{ if .ObjectStorageConnection.BasePath }} defaultPipelineRoot: s3://{{.ObjectStorageConnection.Bucket}}/{{.ObjectStorageConnection.BasePath}} {{ else }} @@ -13,6 +16,7 @@ data: secretName: {{.ObjectStorageConnection.CredentialsSecret.SecretName}} accessKeyKey: {{.ObjectStorageConnection.CredentialsSecret.AccessKey}} secretKeyKey: {{.ObjectStorageConnection.CredentialsSecret.SecretKey}} + {{ end }} kind: ConfigMap metadata: name: kfp-launcher diff --git a/config/samples/v2/dspa-all-fields/dspa_all_fields.yaml b/config/samples/v2/dspa-all-fields/dspa_all_fields.yaml index ab66c9474..8697a4611 100644 --- a/config/samples/v2/dspa-all-fields/dspa_all_fields.yaml +++ b/config/samples/v2/dspa-all-fields/dspa_all_fields.yaml @@ -11,6 +11,7 @@ metadata: spec: dspVersion: v2 apiServer: + customKfpLauncherConfigMap: configmapname deploy: true enableSamplePipeline: true image: quay.io/opendatahub/ds-pipelines-api-server:latest diff --git a/controllers/dspipeline_params.go b/controllers/dspipeline_params.go index 3c17c9bd4..6cfe319a5 100644 --- a/controllers/dspipeline_params.go +++ b/controllers/dspipeline_params.go @@ -66,6 +66,7 @@ type DSPAParams struct { Minio *dspa.Minio MLMD *dspa.MLMD WorkflowController *dspa.WorkflowController + CustomKfpLauncherConfigMapData string DBConnection ObjectStorageConnection @@ -646,6 +647,25 @@ func (p *DSPAParams) ExtractParams(ctx context.Context, dsp *dspa.DataSciencePip } } + if p.APIServer.CustomKfpLauncherConfigMap != "" { + cm, err := util.GetConfigMap(ctx, p.APIServer.CustomKfpLauncherConfigMap, p.Namespace, client) + if err != nil { + // If the custom kfp-launcher ConfigMap is not available, that is ok. Just log it and move along. + if !apierrs.IsNotFound(err) { + log.Error(err, fmt.Sprintf("Error fetching ConfigMap referenced by CustomKfpLauncherConfig: [%s]", p.APIServer.CustomKfpLauncherConfigMap)) + } + } else { + // when setting a map into the `data` field of a ConfigMap, text/template works well with a json object + jsonData, err := json.Marshal(cm.Data) + if err != nil { + // If the custom kfp-launcher ConfigMap can't be read, that is ok. Just log it and move along. + log.Error(err, fmt.Sprintf("Error reading data of ConfigMap referenced by CustomKfpLauncherConfig: [%s]", p.APIServer.CustomKfpLauncherConfigMap)) + } else { + p.CustomKfpLauncherConfigMapData = string(jsonData) + } + } + } + // Track whether the "ca-bundle.crt" configmap key from odh-trusted-ca bundle // was found, this will be used to decide whether we need to account for this // ourselves later or not.