Repository: istio/istio
File: cni/pkg/plugin/sidecar_redirect.go (Go)

Code before:
	if _, err := parsePorts(ports); err != nil {
		return fmt.Errorf("portList %q invalid: %v", ports, err)
	}
	return nil
}

func validatePortListWithWildcard(ports string) error {
	if ports != "*" {
		return validatePortList(ports)
	}
	return nil
}

// validateCIDRListWithWildcard validates the includeIPRanges parameter
func validateCIDRListWithWildcard(ipRanges string) error {
	if ipRanges != "*" {
		if e := validateCIDRList(ipRanges); e != nil {
			return fmt.Errorf("IPRanges invalid: %v", e)
		}
	}
	return nil
}

var interfaceNameRegex = regexp.MustCompile(`^[a-zA-Z0-9_][a-zA-Z0-9_.\-]*$`)

func validateInterfaceList(interfaces string) error {
	if len(interfaces) == 0 {
		return nil
	}
	for _, iface := range strings.Split(interfaces, ",") {
		iface = strings.TrimSpace(iface)
		if len(iface) == 0 {
			return fmt.Errorf("empty interface name")
		}
		if len(iface) > 15 {
			return fmt.Errorf("interface name %q too long (max 15 chars)", iface)
		}
		if !interfaceNameRegex.MatchString(iface) {
			return fmt.Errorf("interface name %q contains invalid characters", iface)
		}
	}
	return nil
}

func getAnnotationOrDefault(name string, annotations map[string]string) (isFound bool, val string, err error) {
	if _, ok := annotationRegistry[name]; !ok {
		return false, "", fmt.Errorf("no registered annotation with name=%s", name)
	}
	// use annotation value if present
	if val, found := annotations[annotationRegistry[name].key]; found {
		if err := annotationRegistry[name].validator(val); err != nil {

Review comment (refactor):
The same API is duplicated in the file pkg/kube/inject/validate.go
Its better to move it to some common package and import it whereever its requried.

Code after:
	if _, err := parsePorts(ports); err != nil {
		return fmt.Errorf("portList %q invalid: %v", ports, err)
	}
	return nil
}

func validatePortListWithWildcard(ports string) error {
	if ports != "*" {
		return validatePortList(ports)
	}
	return nil
}

// validateCIDRListWithWildcard validates the includeIPRanges parameter
func validateCIDRListWithWildcard(ipRanges string) error {
	if ipRanges != "*" {
		if e := validateCIDRList(ipRanges); e != nil {
			return fmt.Errorf("IPRanges invalid: %v", e)
		}
	}
	return nil
}

func getAnnotationOrDefault(name string, annotations map[string]string) (isFound bool, val string, err error) {
	if _, ok := annotationRegistry[name]; !ok {
		return false, "", fmt.Errorf("no registered annotation with name=%s", name)
	}
	// use annotation value if present
	if val, found := annotations[annotationRegistry[name].key]; found {
		if err := annotationRegistry[name].validator(val); err != nil {
			return true, annotationRegistry[name].defaultVal, err
		}
		return true, val, nil
	}
	// no annotation found so use default value
	return false, annotationRegistry[name].defaultVal, nil
}

// NewRedirect returns a new Redirect Object constructed from a list of ports and annotations
func NewRedirect(pi *PodInfo) (*Redirect, error) {
	var isFound bool
	var valErr error

	redir := &Redirect{}
	redir.targetPort = defaultRedirectToPort
	isFound, redir.redirectMode, valErr = getAnnotationOrDefault("redirectMode", pi.Annotations)
	if valErr != nil {
		return nil, fmt.Errorf("annotation value error for value %s; annotationFound = %t: %v",
			"redirectMode", isFound, valErr)
	}