@@ -19,6 +19,7 @@ package v1alpha1
19
19
import (
20
20
"fmt"
21
21
"reflect"
22
+ "strings"
22
23
23
24
corev1 "k8s.io/api/core/v1"
24
25
networkingv1 "k8s.io/api/networking/v1"
@@ -36,6 +37,27 @@ var validPVCAccessModeStrs = []corev1.PersistentVolumeAccessMode{
36
37
corev1 .ReadWriteOncePod ,
37
38
}
38
39
40
+ // validateNIMServiceSpec aggregates all structural validation checks for a NIMService
41
+ // object. It is intended to be invoked by both ValidateCreate and ValidateUpdate to
42
+ // ensure the resource is well-formed before any other validation (e.g. immutability)
43
+ // is performed.
44
+ func validateNIMServiceSpec (spec * appsv1alpha1.NIMServiceSpec , fldPath * field.Path , kubeVersion string ) field.ErrorList {
45
+ errList := field.ErrorList {}
46
+
47
+ // Validate individual sections of the spec using existing helper functions.
48
+ errList = append (errList , validateImageConfiguration (& spec .Image , fldPath .Child ("image" ))... )
49
+ errList = append (errList , validateAuthSecret (& spec .AuthSecret , fldPath .Child ("authSecret" ))... )
50
+ errList = append (errList , validateServiceStorageConfiguration (& spec .Storage , fldPath .Child ("storage" ))... )
51
+ errList = append (errList , validateExposeConfiguration (& spec .Expose , fldPath .Child ("expose" ).Child ("ingress" ))... )
52
+ errList = append (errList , validateMetricsConfiguration (& spec .Metrics , fldPath .Child ("metrics" ))... )
53
+ errList = append (errList , validateScaleConfiguration (& spec .Scale , fldPath .Child ("scale" ))... )
54
+ errList = append (errList , validateResourcesConfiguration (spec .Resources , fldPath .Child ("resources" ))... )
55
+ errList = append (errList , validateDRAResourcesConfiguration (spec , fldPath , kubeVersion )... )
56
+ errList = append (errList , validateKServeConfiguration (spec , fldPath )... )
57
+
58
+ return errList
59
+ }
60
+
39
61
func validateImageConfiguration (image * appsv1alpha1.Image , fldPath * field.Path ) field.ErrorList {
40
62
errList := field.ErrorList {}
41
63
if image .Repository == "" {
@@ -212,22 +234,39 @@ func validateResourcesConfiguration(resources *corev1.ResourceRequirements, fldP
212
234
return errList
213
235
}
214
236
215
- // validateNIMServiceSpec aggregates all structural validation checks for a NIMService
216
- // object. It is intended to be invoked by both ValidateCreate and ValidateUpdate to
217
- // ensure the resource is well-formed before any other validation (e.g. immutability)
218
- // is performed.
219
- func validateNIMServiceSpec (spec * appsv1alpha1.NIMServiceSpec , fldPath * field.Path , kubeVersion string ) field.ErrorList {
237
+ // validateKServeonfiguration implements required KServe validations.
238
+ func validateKServeConfiguration (spec * appsv1alpha1.NIMServiceSpec , fldPath * field.Path ) field.ErrorList {
220
239
errList := field.ErrorList {}
221
240
222
- // Validate individual sections of the spec using existing helper functions.
223
- errList = append (errList , validateImageConfiguration (& spec .Image , fldPath .Child ("image" ))... )
224
- errList = append (errList , validateAuthSecret (& spec .AuthSecret , fldPath .Child ("authSecret" ))... )
225
- errList = append (errList , validateServiceStorageConfiguration (& spec .Storage , fldPath .Child ("storage" ))... )
226
- errList = append (errList , validateExposeConfiguration (& spec .Expose , fldPath .Child ("expose" ).Child ("ingress" ))... )
227
- errList = append (errList , validateMetricsConfiguration (& spec .Metrics , fldPath .Child ("metrics" ))... )
228
- errList = append (errList , validateScaleConfiguration (& spec .Scale , fldPath .Child ("scale" ))... )
229
- errList = append (errList , validateResourcesConfiguration (spec .Resources , fldPath .Child ("resources" ))... )
230
- errList = append (errList , validateDRAResourcesConfiguration (spec , fldPath , kubeVersion )... )
241
+ platformIsKServe := spec .InferencePlatform == appsv1alpha1 .PlatformTypeKServe
242
+
243
+ // mode is the value, and annotated is true if the key-value pair exist.
244
+ mode , annotated := spec .Annotations ["serving.kserve.org/deploymentMode" ]
245
+ // If the annotation is absent, kserve defaults to serverless.
246
+ serverless := ! annotated || strings .EqualFold (mode , "serverless" )
247
+
248
+ // When Spec.InferencePlatform is "kserve" and used in "serverless" mode:
249
+ if platformIsKServe && serverless {
250
+ // Spec.Scale (autoscaling) cannot be set.
251
+ if spec .Scale .Enabled != nil && * spec .Scale .Enabled {
252
+ errList = append (errList , field .Forbidden (fldPath .Child ("scale" ).Child ("enabled" ), fmt .Sprintf ("%s (autoscaling) cannot be set when KServe runs in serverless mode" , fldPath .Child ("scale" ))))
253
+ }
254
+
255
+ // Spec.Expose.Ingress cannot be set.
256
+ if spec .Expose .Ingress .Enabled != nil && * spec .Expose .Ingress .Enabled {
257
+ errList = append (errList , field .Forbidden (fldPath .Child ("expose" ).Child ("ingress" ).Child ("enabled" ), fmt .Sprintf ("%s cannot be set when KServe runs in serverless mode" , fldPath .Child ("expose" ).Child ("ingress" ))))
258
+ }
259
+
260
+ // Spec.Metrics.ServiceMonitor cannot be set.
261
+ if spec .Metrics .Enabled != nil && * spec .Metrics .Enabled {
262
+ errList = append (errList , field .Forbidden (fldPath .Child ("metrics" ).Child ("enabled" ), fmt .Sprintf ("%s cannot be set when KServe runs in serverless mode" , fldPath .Child ("metrics" ).Child ("serviceMonitor" ))))
263
+ }
264
+ }
265
+
266
+ // Spec.MultiNode cannot be enabled when inferencePlatform is kserve.
267
+ if platformIsKServe && spec .MultiNode != nil {
268
+ errList = append (errList , field .Forbidden (fldPath .Child ("multiNode" ), "cannot be set when KServe runs in serverless mode" ))
269
+ }
231
270
232
271
return errList
233
272
}
0 commit comments