github.com/hashicorp/terraform-plugin-sdk@v1.17.2/helper/validation/network.go (about)

     1  package validation
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"net"
     7  	"strings"
     8  
     9  	"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
    10  )
    11  
    12  // SingleIP returns a SchemaValidateFunc which tests if the provided value
    13  // is of type string, and in valid single Value notation
    14  //
    15  // Deprecated: use IsIPAddress instead
    16  func SingleIP() schema.SchemaValidateFunc {
    17  	return IsIPAddress
    18  }
    19  
    20  // IsIPAddress is a SchemaValidateFunc which tests if the provided value is of type string and is a single IP (v4 or v6)
    21  func IsIPAddress(i interface{}, k string) (warnings []string, errors []error) {
    22  	v, ok := i.(string)
    23  	if !ok {
    24  		errors = append(errors, fmt.Errorf("expected type of %q to be string", k))
    25  		return warnings, errors
    26  	}
    27  
    28  	ip := net.ParseIP(v)
    29  	if ip == nil {
    30  		errors = append(errors, fmt.Errorf("expected %s to contain a valid IP, got: %s", k, v))
    31  	}
    32  
    33  	return warnings, errors
    34  }
    35  
    36  // IsIPv6Address is a SchemaValidateFunc which tests if the provided value is of type string and a valid IPv6 address
    37  func IsIPv6Address(i interface{}, k string) (warnings []string, errors []error) {
    38  	v, ok := i.(string)
    39  	if !ok {
    40  		errors = append(errors, fmt.Errorf("expected type of %q to be string", k))
    41  		return warnings, errors
    42  	}
    43  
    44  	ip := net.ParseIP(v)
    45  	if six := ip.To16(); six == nil {
    46  		errors = append(errors, fmt.Errorf("expected %s to contain a valid IPv6 address, got: %s", k, v))
    47  	}
    48  
    49  	return warnings, errors
    50  }
    51  
    52  // IsIPv4Address is a SchemaValidateFunc which tests if the provided value is of type string and a valid IPv4 address
    53  func IsIPv4Address(i interface{}, k string) (warnings []string, errors []error) {
    54  	v, ok := i.(string)
    55  	if !ok {
    56  		errors = append(errors, fmt.Errorf("expected type of %q to be string", k))
    57  		return warnings, errors
    58  	}
    59  
    60  	ip := net.ParseIP(v)
    61  	if four := ip.To4(); four == nil {
    62  		errors = append(errors, fmt.Errorf("expected %s to contain a valid IPv4 address, got: %s", k, v))
    63  	}
    64  
    65  	return warnings, errors
    66  }
    67  
    68  // IPRange returns a SchemaValidateFunc which tests if the provided value is of type string, and in valid IP range
    69  //
    70  // Deprecated: use IsIPv4Range instead
    71  func IPRange() schema.SchemaValidateFunc {
    72  	return IsIPv4Range
    73  }
    74  
    75  // IsIPv4Range is a SchemaValidateFunc which tests if the provided value is of type string, and in valid IP range
    76  func IsIPv4Range(i interface{}, k string) (warnings []string, errors []error) {
    77  	v, ok := i.(string)
    78  	if !ok {
    79  		errors = append(errors, fmt.Errorf("expected type of %s to be string", k))
    80  		return warnings, errors
    81  	}
    82  
    83  	ips := strings.Split(v, "-")
    84  	if len(ips) != 2 {
    85  		errors = append(errors, fmt.Errorf("expected %s to contain a valid IP range, got: %s", k, v))
    86  		return warnings, errors
    87  	}
    88  
    89  	ip1 := net.ParseIP(ips[0])
    90  	ip2 := net.ParseIP(ips[1])
    91  	if ip1 == nil || ip2 == nil || bytes.Compare(ip1, ip2) > 0 {
    92  		errors = append(errors, fmt.Errorf("expected %s to contain a valid IP range, got: %s", k, v))
    93  	}
    94  
    95  	return warnings, errors
    96  }
    97  
    98  // IsCIDR is a SchemaValidateFunc which tests if the provided value is of type string and a valid CIDR
    99  func IsCIDR(i interface{}, k string) (warnings []string, errors []error) {
   100  	v, ok := i.(string)
   101  	if !ok {
   102  		errors = append(errors, fmt.Errorf("expected type of %s to be string", k))
   103  		return warnings, errors
   104  	}
   105  
   106  	if _, _, err := net.ParseCIDR(v); err != nil {
   107  		errors = append(errors, fmt.Errorf("expected %q to be a valid IPv4 Value, got %v: %v", k, i, err))
   108  	}
   109  
   110  	return warnings, errors
   111  }
   112  
   113  // CIDRNetwork returns a SchemaValidateFunc which tests if the provided value
   114  // is of type string, is in valid Value network notation, and has significant bits between min and max (inclusive)
   115  //
   116  // Deprecated: use IsCIDRNetwork instead
   117  func CIDRNetwork(min, max int) schema.SchemaValidateFunc {
   118  	return IsCIDRNetwork(min, max)
   119  }
   120  
   121  // IsCIDRNetwork returns a SchemaValidateFunc which tests if the provided value
   122  // is of type string, is in valid Value network notation, and has significant bits between min and max (inclusive)
   123  func IsCIDRNetwork(min, max int) schema.SchemaValidateFunc {
   124  	return func(i interface{}, k string) (warnings []string, errors []error) {
   125  		v, ok := i.(string)
   126  		if !ok {
   127  			errors = append(errors, fmt.Errorf("expected type of %s to be string", k))
   128  			return warnings, errors
   129  		}
   130  
   131  		_, ipnet, err := net.ParseCIDR(v)
   132  		if err != nil {
   133  			errors = append(errors, fmt.Errorf("expected %s to contain a valid Value, got: %s with err: %s", k, v, err))
   134  			return warnings, errors
   135  		}
   136  
   137  		if ipnet == nil || v != ipnet.String() {
   138  			errors = append(errors, fmt.Errorf("expected %s to contain a valid network Value, expected %s, got %s",
   139  				k, ipnet, v))
   140  		}
   141  
   142  		sigbits, _ := ipnet.Mask.Size()
   143  		if sigbits < min || sigbits > max {
   144  			errors = append(errors, fmt.Errorf("expected %q to contain a network Value with between %d and %d significant bits, got: %d", k, min, max, sigbits))
   145  		}
   146  
   147  		return warnings, errors
   148  	}
   149  }
   150  
   151  // IsMACAddress is a SchemaValidateFunc which tests if the provided value is of type string and a valid MAC address
   152  func IsMACAddress(i interface{}, k string) (warnings []string, errors []error) {
   153  	v, ok := i.(string)
   154  	if !ok {
   155  		errors = append(errors, fmt.Errorf("expected type of %q to be string", k))
   156  		return warnings, errors
   157  	}
   158  
   159  	if _, err := net.ParseMAC(v); err != nil {
   160  		errors = append(errors, fmt.Errorf("expected %q to be a valid MAC address, got %v: %v", k, i, err))
   161  	}
   162  
   163  	return warnings, errors
   164  }
   165  
   166  // IsPortNumber is a SchemaValidateFunc which tests if the provided value is of type string and a valid TCP Port Number
   167  func IsPortNumber(i interface{}, k string) (warnings []string, errors []error) {
   168  	v, ok := i.(int)
   169  	if !ok {
   170  		errors = append(errors, fmt.Errorf("expected type of %q to be integer", k))
   171  		return warnings, errors
   172  	}
   173  
   174  	if 1 > v || v > 65535 {
   175  		errors = append(errors, fmt.Errorf("expected %q to be a valid port number, got: %v", k, v))
   176  	}
   177  
   178  	return warnings, errors
   179  }
   180  
   181  // IsPortNumberOrZero is a SchemaValidateFunc which tests if the provided value is of type string and a valid TCP Port Number or zero
   182  func IsPortNumberOrZero(i interface{}, k string) (warnings []string, errors []error) {
   183  	v, ok := i.(int)
   184  	if !ok {
   185  		errors = append(errors, fmt.Errorf("expected type of %q to be integer", k))
   186  		return warnings, errors
   187  	}
   188  
   189  	if 0 > v || v > 65535 {
   190  		errors = append(errors, fmt.Errorf("expected %q to be a valid port number or 0, got: %v", k, v))
   191  	}
   192  
   193  	return warnings, errors
   194  }