Skip to content

Commit

Permalink
fix: validate resourcePrefix in NCP DP
Browse files Browse the repository at this point in the history
In the admission controller, the "resourcePrefix" field
in Device Plugins configuration is now validated to be
a valid FQDN.

Signed-off-by: Fred Rolland <[email protected]>
  • Loading branch information
rollandf committed Oct 25, 2023
1 parent 053bc17 commit bb5e1ac
Show file tree
Hide file tree
Showing 2 changed files with 130 additions and 270 deletions.
60 changes: 48 additions & 12 deletions api/v1alpha1/nicclusterpolicy_webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ import (
"sigs.k8s.io/controller-runtime/pkg/webhook"
)

const (
fqdnRegex = `^[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z]{2,})+$`
sriovResourceNameRegex = `^([A-Za-z0-9][A-Za-z0-9_.]*)?[A-Za-z0-9]$`
rdmaResourceNameRegex = `^([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]$`
)

// log is for logging in this package.
var nicClusterPolicyLog = logf.Log.WithName("nicclusterpolicy-resource")

Expand Down Expand Up @@ -198,12 +204,9 @@ func (dp *DevicePluginSpec) validateSriovNetworkDevicePlugin(fldPath *field.Path
resourceJSONLoader := gojsonschema.NewStringLoader(string(resourceJSONString))
var selectorResult *gojsonschema.Result
var selectorErr error
resourceName := resource["resourceName"].(string)
if !isValidSriovNetworkDevicePluginResourceName(resourceName) {
allErrs = append(allErrs, field.Invalid(fldPath.Child("Config"), dp.Config,
"Invalid Resource name, it must consist of alphanumeric characters, '_' or '.', "+
"and must start and end with an alphanumeric character (e.g. 'MyName', or 'my.name', "+
"or '123_abc', regex used for validation is '([A-Za-z0-9][A-Za-z0-9_.]*)?[A-Za-z0-9]')"))
var ok bool
ok, allErrs = validateResourceNamePrefix(resource, allErrs, fldPath, dp)
if !ok {
return allErrs
}
deviceType := resource["deviceType"]
Expand All @@ -229,6 +232,28 @@ func (dp *DevicePluginSpec) validateSriovNetworkDevicePlugin(fldPath *field.Path
return allErrs
}

func validateResourceNamePrefix(resource map[string]interface{},
allErrs field.ErrorList, fldPath *field.Path, dp *DevicePluginSpec) (bool, field.ErrorList) {
resourceName := resource["resourceName"].(string)
if !isValidSriovNetworkDevicePluginResourceName(resourceName) {
allErrs = append(allErrs, field.Invalid(fldPath.Child("Config"), dp.Config,
"Invalid Resource name, it must consist of alphanumeric characters, '_' or '.', "+
"and must start and end with an alphanumeric character (e.g. 'MyName', or 'my.name', "+
"or '123_abc', regex used for validation is "+sriovResourceNameRegex))
return false, allErrs
}
resourcePrefix, ok := resource["resourcePrefix"]
if ok {
if !isValidFQDN(resourcePrefix.(string)) {
allErrs = append(allErrs, field.Invalid(fldPath.Child("Config"), dp.Config,
"Invalid Resource prefix, it must be a valid FQDN"+
"regex used for validation is "+fqdnRegex))
return false, allErrs
}
}
return true, allErrs
}

func (dp *DevicePluginSpec) validateRdmaSharedDevicePlugin(fldPath *field.Path) field.ErrorList {
var allErrs field.ErrorList
var rdmaSharedDevicePluginConfigJSON map[string]interface{}
Expand Down Expand Up @@ -263,8 +288,16 @@ func (dp *DevicePluginSpec) validateRdmaSharedDevicePlugin(fldPath *field.Path)
allErrs = append(allErrs, field.Invalid(fldPath.Child("Config"),
dp.Config, "Invalid Resource name, it must consist of alphanumeric characters, "+
"'-', '_' or '.', and must start and end with an alphanumeric character "+
"(e.g. 'MyName', or 'my.name', or '123-abc', regex used for validation is '([A-Za-z0-9][-A-Za-z0"+
"-9_.]*)?[A-Za-z0-9]')"))
"(e.g. 'MyName', or 'my.name', or '123-abc') regex used for validation is "+rdmaResourceNameRegex))
}
resourcePrefix, ok := config["resourcePrefix"]
if ok {
if !isValidFQDN(resourcePrefix.(string)) {
allErrs = append(allErrs, field.Invalid(fldPath.Child("Config"), dp.Config,
"Invalid Resource prefix, it must be a valid FQDN "+
"regex used for validation is "+fqdnRegex))
return allErrs
}
}
}
} else {
Expand Down Expand Up @@ -336,17 +369,20 @@ func isValidOFEDVersion(version string) bool {
}

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

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

func isValidFQDN(input string) bool {
regex := regexp.MustCompile(fqdnRegex)
return regex.MatchString(input)
}

// +kubebuilder:object:generate=false
type schemaValidator struct {
schemas map[string]*gojsonschema.Schema
Expand Down
Loading

0 comments on commit bb5e1ac

Please sign in to comment.