Skip to content

Commit 9890794

Browse files
authored
fix: validate resourcePrefix in NCP DP (#650)
In the admission controller, the `resourcePrefix` field in Device Plugins configuration is now validated to be a valid FQDN.
2 parents 62247e5 + bb5e1ac commit 9890794

File tree

2 files changed

+130
-270
lines changed

2 files changed

+130
-270
lines changed

api/v1alpha1/nicclusterpolicy_webhook.go

Lines changed: 48 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@ import (
3535
"sigs.k8s.io/controller-runtime/pkg/webhook"
3636
)
3737

38+
const (
39+
fqdnRegex = `^[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z]{2,})+$`
40+
sriovResourceNameRegex = `^([A-Za-z0-9][A-Za-z0-9_.]*)?[A-Za-z0-9]$`
41+
rdmaResourceNameRegex = `^([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]$`
42+
)
43+
3844
// log is for logging in this package.
3945
var nicClusterPolicyLog = logf.Log.WithName("nicclusterpolicy-resource")
4046

@@ -200,12 +206,9 @@ func (dp *DevicePluginSpec) validateSriovNetworkDevicePlugin(fldPath *field.Path
200206
resourceJSONLoader := gojsonschema.NewStringLoader(string(resourceJSONString))
201207
var selectorResult *gojsonschema.Result
202208
var selectorErr error
203-
resourceName := resource["resourceName"].(string)
204-
if !isValidSriovNetworkDevicePluginResourceName(resourceName) {
205-
allErrs = append(allErrs, field.Invalid(fldPath.Child("Config"), dp.Config,
206-
"Invalid Resource name, it must consist of alphanumeric characters, '_' or '.', "+
207-
"and must start and end with an alphanumeric character (e.g. 'MyName', or 'my.name', "+
208-
"or '123_abc', regex used for validation is '([A-Za-z0-9][A-Za-z0-9_.]*)?[A-Za-z0-9]')"))
209+
var ok bool
210+
ok, allErrs = validateResourceNamePrefix(resource, allErrs, fldPath, dp)
211+
if !ok {
209212
return allErrs
210213
}
211214
deviceType := resource["deviceType"]
@@ -231,6 +234,28 @@ func (dp *DevicePluginSpec) validateSriovNetworkDevicePlugin(fldPath *field.Path
231234
return allErrs
232235
}
233236

237+
func validateResourceNamePrefix(resource map[string]interface{},
238+
allErrs field.ErrorList, fldPath *field.Path, dp *DevicePluginSpec) (bool, field.ErrorList) {
239+
resourceName := resource["resourceName"].(string)
240+
if !isValidSriovNetworkDevicePluginResourceName(resourceName) {
241+
allErrs = append(allErrs, field.Invalid(fldPath.Child("Config"), dp.Config,
242+
"Invalid Resource name, it must consist of alphanumeric characters, '_' or '.', "+
243+
"and must start and end with an alphanumeric character (e.g. 'MyName', or 'my.name', "+
244+
"or '123_abc', regex used for validation is "+sriovResourceNameRegex))
245+
return false, allErrs
246+
}
247+
resourcePrefix, ok := resource["resourcePrefix"]
248+
if ok {
249+
if !isValidFQDN(resourcePrefix.(string)) {
250+
allErrs = append(allErrs, field.Invalid(fldPath.Child("Config"), dp.Config,
251+
"Invalid Resource prefix, it must be a valid FQDN"+
252+
"regex used for validation is "+fqdnRegex))
253+
return false, allErrs
254+
}
255+
}
256+
return true, allErrs
257+
}
258+
234259
func (dp *DevicePluginSpec) validateRdmaSharedDevicePlugin(fldPath *field.Path) field.ErrorList {
235260
var allErrs field.ErrorList
236261
var rdmaSharedDevicePluginConfigJSON map[string]interface{}
@@ -265,8 +290,16 @@ func (dp *DevicePluginSpec) validateRdmaSharedDevicePlugin(fldPath *field.Path)
265290
allErrs = append(allErrs, field.Invalid(fldPath.Child("Config"),
266291
dp.Config, "Invalid Resource name, it must consist of alphanumeric characters, "+
267292
"'-', '_' or '.', and must start and end with an alphanumeric character "+
268-
"(e.g. 'MyName', or 'my.name', or '123-abc', regex used for validation is '([A-Za-z0-9][-A-Za-z0"+
269-
"-9_.]*)?[A-Za-z0-9]')"))
293+
"(e.g. 'MyName', or 'my.name', or '123-abc') regex used for validation is "+rdmaResourceNameRegex))
294+
}
295+
resourcePrefix, ok := config["resourcePrefix"]
296+
if ok {
297+
if !isValidFQDN(resourcePrefix.(string)) {
298+
allErrs = append(allErrs, field.Invalid(fldPath.Child("Config"), dp.Config,
299+
"Invalid Resource prefix, it must be a valid FQDN "+
300+
"regex used for validation is "+fqdnRegex))
301+
return allErrs
302+
}
270303
}
271304
}
272305
} else {
@@ -386,17 +419,20 @@ func isValidOFEDVersion(version string) bool {
386419
}
387420

388421
func isValidSriovNetworkDevicePluginResourceName(resourceName string) bool {
389-
resourceNamePattern := `^([A-Za-z0-9][A-Za-z0-9_.]*)?[A-Za-z0-9]$`
390-
resourceNameRegex := regexp.MustCompile(resourceNamePattern)
422+
resourceNameRegex := regexp.MustCompile(sriovResourceNameRegex)
391423
return resourceNameRegex.MatchString(resourceName)
392424
}
393425

394426
func isValidRdmaSharedDevicePluginResourceName(resourceName string) bool {
395-
resourceNamePattern := `^([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]$`
396-
resourceNameRegex := regexp.MustCompile(resourceNamePattern)
427+
resourceNameRegex := regexp.MustCompile(rdmaResourceNameRegex)
397428
return resourceNameRegex.MatchString(resourceName)
398429
}
399430

431+
func isValidFQDN(input string) bool {
432+
regex := regexp.MustCompile(fqdnRegex)
433+
return regex.MatchString(input)
434+
}
435+
400436
// +kubebuilder:object:generate=false
401437
type schemaValidator struct {
402438
schemas map[string]*gojsonschema.Schema

0 commit comments

Comments
 (0)