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 }