github.com/42z-io/confik@v0.0.2-0.20231103050132-21d8f377356c/validators.go (about)

     1  package confik
     2  
     3  import (
     4  	"fmt"
     5  	"net"
     6  	"net/url"
     7  	"os"
     8  	"strconv"
     9  )
    10  
    11  // Validator is the type a function must implement to provide string validation on environment variables.
    12  type Validator = func(envName, value string) error
    13  
    14  func validateUri(envName string, value string) error {
    15  	if _, err := url.ParseRequestURI(value); err != nil {
    16  		return fmt.Errorf("%s=%s is not a URI: %w", envName, value, err)
    17  	}
    18  	return nil
    19  }
    20  
    21  func validateIp(envName string, value string) error {
    22  	if ip := net.ParseIP(value); ip == nil {
    23  		return fmt.Errorf("%s=%s is not a valid IP: invalid format", envName, value)
    24  	}
    25  	return nil
    26  }
    27  
    28  func validatePort(envName string, value string) error {
    29  	_, err := strconv.ParseUint(value, 10, 16)
    30  	if err != nil {
    31  		return fmt.Errorf("%s=%s is not a valid port: 0-65535", envName, value)
    32  	}
    33  	return nil
    34  }
    35  
    36  func validateHostport(envName string, value string) error {
    37  	_, port, err := net.SplitHostPort(value)
    38  	if err != nil {
    39  		return fmt.Errorf("%s=%s is not a valid hostport: %w", envName, value, err)
    40  	}
    41  	err = validatePort(envName, port)
    42  	if err != nil {
    43  		return fmt.Errorf("%s=%s is not a valid hostport: invalid port (%s): 0-65535", envName, value, port)
    44  	}
    45  	return nil
    46  }
    47  
    48  func validateCidr(envName string, value string) error {
    49  	_, _, err := net.ParseCIDR(value)
    50  	if err != nil {
    51  		return fmt.Errorf("%s=%s is not a valid CIDR: %w", envName, value, err)
    52  	}
    53  	return nil
    54  }
    55  
    56  func validateFile(envName string, value string) error {
    57  	stat, err := os.Stat(value)
    58  	if err != nil {
    59  		return fmt.Errorf("%s=%s is not a valid file", envName, value)
    60  	}
    61  	if stat.IsDir() {
    62  		return fmt.Errorf("%s=%s exists but is not a file", envName, value)
    63  	}
    64  	return nil
    65  }
    66  
    67  func validateDir(envName string, value string) error {
    68  	stat, err := os.Stat(value)
    69  	if err != nil {
    70  		return fmt.Errorf("%s=%s is not a valid directory", envName, value)
    71  	}
    72  	if !stat.IsDir() {
    73  		return fmt.Errorf("%s=%s exists but is not a directory", envName, value)
    74  	}
    75  	return nil
    76  }
    77  
    78  var fieldValidators = map[string]Validator{
    79  	"uri":      validateUri,
    80  	"ip":       validateIp,
    81  	"port":     validatePort,
    82  	"hostport": validateHostport,
    83  	"cidr":     validateCidr,
    84  	"file":     validateFile,
    85  	"dir":      validateDir,
    86  }