github.com/danp/terraform@v0.9.5-0.20170426144147-39d740081351/builtin/providers/alicloud/validators.go (about)

     1  package alicloud
     2  
     3  import (
     4  	"fmt"
     5  	"net"
     6  	"strconv"
     7  	"strings"
     8  
     9  	"github.com/denverdino/aliyungo/common"
    10  	"github.com/denverdino/aliyungo/ecs"
    11  	"github.com/denverdino/aliyungo/slb"
    12  	"github.com/hashicorp/terraform/helper/schema"
    13  	"regexp"
    14  )
    15  
    16  // common
    17  func validateInstancePort(v interface{}, k string) (ws []string, errors []error) {
    18  	value := v.(int)
    19  	if value < 1 || value > 65535 {
    20  		errors = append(errors, fmt.Errorf(
    21  			"%q must be a valid port between 1 and 65535",
    22  			k))
    23  		return
    24  	}
    25  	return
    26  }
    27  
    28  func validateInstanceProtocol(v interface{}, k string) (ws []string, errors []error) {
    29  	protocol := v.(string)
    30  	if !isProtocolValid(protocol) {
    31  		errors = append(errors, fmt.Errorf(
    32  			"%q is an invalid value. Valid values are either http, https, tcp or udp",
    33  			k))
    34  		return
    35  	}
    36  	return
    37  }
    38  
    39  // ecs
    40  func validateDiskCategory(v interface{}, k string) (ws []string, errors []error) {
    41  	category := ecs.DiskCategory(v.(string))
    42  	if category != ecs.DiskCategoryCloud && category != ecs.DiskCategoryCloudEfficiency && category != ecs.DiskCategoryCloudSSD {
    43  		errors = append(errors, fmt.Errorf("%s must be one of %s %s %s", k, ecs.DiskCategoryCloud, ecs.DiskCategoryCloudEfficiency, ecs.DiskCategoryCloudSSD))
    44  	}
    45  
    46  	return
    47  }
    48  
    49  func validateInstanceName(v interface{}, k string) (ws []string, errors []error) {
    50  	value := v.(string)
    51  	if len(value) < 2 || len(value) > 128 {
    52  		errors = append(errors, fmt.Errorf("%q cannot be longer than 128 characters", k))
    53  	}
    54  
    55  	if strings.HasPrefix(value, "http://") || strings.HasPrefix(value, "https://") {
    56  		errors = append(errors, fmt.Errorf("%s cannot starts with http:// or https://", k))
    57  	}
    58  
    59  	return
    60  }
    61  
    62  func validateInstanceDescription(v interface{}, k string) (ws []string, errors []error) {
    63  	value := v.(string)
    64  	if len(value) < 2 || len(value) > 256 {
    65  		errors = append(errors, fmt.Errorf("%q cannot be longer than 256 characters", k))
    66  
    67  	}
    68  	return
    69  }
    70  
    71  func validateDiskName(v interface{}, k string) (ws []string, errors []error) {
    72  	value := v.(string)
    73  
    74  	if value == "" {
    75  		return
    76  	}
    77  
    78  	if len(value) < 2 || len(value) > 128 {
    79  		errors = append(errors, fmt.Errorf("%q cannot be longer than 128 characters", k))
    80  	}
    81  
    82  	if strings.HasPrefix(value, "http://") || strings.HasPrefix(value, "https://") {
    83  		errors = append(errors, fmt.Errorf("%s cannot starts with http:// or https://", k))
    84  	}
    85  
    86  	return
    87  }
    88  
    89  func validateDiskDescription(v interface{}, k string) (ws []string, errors []error) {
    90  	value := v.(string)
    91  	if len(value) < 2 || len(value) > 256 {
    92  		errors = append(errors, fmt.Errorf("%q cannot be longer than 256 characters", k))
    93  
    94  	}
    95  	return
    96  }
    97  
    98  //security group
    99  func validateSecurityGroupName(v interface{}, k string) (ws []string, errors []error) {
   100  	value := v.(string)
   101  	if len(value) < 2 || len(value) > 128 {
   102  		errors = append(errors, fmt.Errorf("%q cannot be longer than 128 characters", k))
   103  	}
   104  
   105  	if strings.HasPrefix(value, "http://") || strings.HasPrefix(value, "https://") {
   106  		errors = append(errors, fmt.Errorf("%s cannot starts with http:// or https://", k))
   107  	}
   108  
   109  	return
   110  }
   111  
   112  func validateSecurityGroupDescription(v interface{}, k string) (ws []string, errors []error) {
   113  	value := v.(string)
   114  	if len(value) < 2 || len(value) > 256 {
   115  		errors = append(errors, fmt.Errorf("%q cannot be longer than 256 characters", k))
   116  
   117  	}
   118  	return
   119  }
   120  
   121  func validateSecurityRuleType(v interface{}, k string) (ws []string, errors []error) {
   122  	rt := GroupRuleDirection(v.(string))
   123  	if rt != GroupRuleIngress && rt != GroupRuleEgress {
   124  		errors = append(errors, fmt.Errorf("%s must be one of %s %s", k, GroupRuleIngress, GroupRuleEgress))
   125  	}
   126  
   127  	return
   128  }
   129  
   130  func validateSecurityRuleIpProtocol(v interface{}, k string) (ws []string, errors []error) {
   131  	pt := GroupRuleIpProtocol(v.(string))
   132  	if pt != GroupRuleTcp && pt != GroupRuleUdp && pt != GroupRuleIcmp && pt != GroupRuleGre && pt != GroupRuleAll {
   133  		errors = append(errors, fmt.Errorf("%s must be one of %s %s %s %s %s", k,
   134  			GroupRuleTcp, GroupRuleUdp, GroupRuleIcmp, GroupRuleGre, GroupRuleAll))
   135  	}
   136  
   137  	return
   138  }
   139  
   140  func validateSecurityRuleNicType(v interface{}, k string) (ws []string, errors []error) {
   141  	pt := GroupRuleNicType(v.(string))
   142  	if pt != GroupRuleInternet && pt != GroupRuleIntranet {
   143  		errors = append(errors, fmt.Errorf("%s must be one of %s %s", k, GroupRuleInternet, GroupRuleIntranet))
   144  	}
   145  
   146  	return
   147  }
   148  
   149  func validateSecurityRulePolicy(v interface{}, k string) (ws []string, errors []error) {
   150  	pt := GroupRulePolicy(v.(string))
   151  	if pt != GroupRulePolicyAccept && pt != GroupRulePolicyDrop {
   152  		errors = append(errors, fmt.Errorf("%s must be one of %s %s", k, GroupRulePolicyAccept, GroupRulePolicyDrop))
   153  	}
   154  
   155  	return
   156  }
   157  
   158  func validateSecurityPriority(v interface{}, k string) (ws []string, errors []error) {
   159  	value := v.(int)
   160  	if value < 1 || value > 100 {
   161  		errors = append(errors, fmt.Errorf(
   162  			"%q must be a valid authorization policy priority between 1 and 100",
   163  			k))
   164  		return
   165  	}
   166  	return
   167  }
   168  
   169  // validateCIDRNetworkAddress ensures that the string value is a valid CIDR that
   170  // represents a network address - it adds an error otherwise
   171  func validateCIDRNetworkAddress(v interface{}, k string) (ws []string, errors []error) {
   172  	value := v.(string)
   173  	_, ipnet, err := net.ParseCIDR(value)
   174  	if err != nil {
   175  		errors = append(errors, fmt.Errorf(
   176  			"%q must contain a valid CIDR, got error parsing: %s", k, err))
   177  		return
   178  	}
   179  
   180  	if ipnet == nil || value != ipnet.String() {
   181  		errors = append(errors, fmt.Errorf(
   182  			"%q must contain a valid network CIDR, expected %q, got %q",
   183  			k, ipnet, value))
   184  	}
   185  
   186  	return
   187  }
   188  
   189  func validateRouteEntryNextHopType(v interface{}, k string) (ws []string, errors []error) {
   190  	nht := ecs.NextHopType(v.(string))
   191  	if nht != ecs.NextHopIntance && nht != ecs.NextHopTunnel {
   192  		errors = append(errors, fmt.Errorf("%s must be one of %s %s", k,
   193  			ecs.NextHopIntance, ecs.NextHopTunnel))
   194  	}
   195  
   196  	return
   197  }
   198  
   199  func validateSwitchCIDRNetworkAddress(v interface{}, k string) (ws []string, errors []error) {
   200  	value := v.(string)
   201  	_, ipnet, err := net.ParseCIDR(value)
   202  	if err != nil {
   203  		errors = append(errors, fmt.Errorf(
   204  			"%q must contain a valid CIDR, got error parsing: %s", k, err))
   205  		return
   206  	}
   207  
   208  	if ipnet == nil || value != ipnet.String() {
   209  		errors = append(errors, fmt.Errorf(
   210  			"%q must contain a valid network CIDR, expected %q, got %q",
   211  			k, ipnet, value))
   212  		return
   213  	}
   214  
   215  	mark, _ := strconv.Atoi(strings.Split(ipnet.String(), "/")[1])
   216  	if mark < 16 || mark > 29 {
   217  		errors = append(errors, fmt.Errorf(
   218  			"%q must contain a network CIDR which mark between 16 and 29",
   219  			k))
   220  	}
   221  
   222  	return
   223  }
   224  
   225  // validateIoOptimized ensures that the string value is a valid IoOptimized that
   226  // represents a IoOptimized - it adds an error otherwise
   227  func validateIoOptimized(v interface{}, k string) (ws []string, errors []error) {
   228  	if value := v.(string); value != "" {
   229  		ioOptimized := ecs.IoOptimized(value)
   230  		if ioOptimized != ecs.IoOptimizedNone &&
   231  			ioOptimized != ecs.IoOptimizedOptimized {
   232  			errors = append(errors, fmt.Errorf(
   233  				"%q must contain a valid IoOptimized, expected %s or %s, got %q",
   234  				k, ecs.IoOptimizedNone, ecs.IoOptimizedOptimized, ioOptimized))
   235  		}
   236  	}
   237  
   238  	return
   239  }
   240  
   241  // validateInstanceNetworkType ensures that the string value is a classic or vpc
   242  func validateInstanceNetworkType(v interface{}, k string) (ws []string, errors []error) {
   243  	if value := v.(string); value != "" {
   244  		network := InstanceNetWork(value)
   245  		if network != ClassicNet &&
   246  			network != VpcNet {
   247  			errors = append(errors, fmt.Errorf(
   248  				"%q must contain a valid InstanceNetworkType, expected %s or %s, go %q",
   249  				k, ClassicNet, VpcNet, network))
   250  		}
   251  	}
   252  	return
   253  }
   254  
   255  func validateInstanceChargeType(v interface{}, k string) (ws []string, errors []error) {
   256  	if value := v.(string); value != "" {
   257  		chargeType := common.InstanceChargeType(value)
   258  		if chargeType != common.PrePaid &&
   259  			chargeType != common.PostPaid {
   260  			errors = append(errors, fmt.Errorf(
   261  				"%q must contain a valid InstanceChargeType, expected %s or %s, got %q",
   262  				k, common.PrePaid, common.PostPaid, chargeType))
   263  		}
   264  	}
   265  
   266  	return
   267  }
   268  
   269  func validateInternetChargeType(v interface{}, k string) (ws []string, errors []error) {
   270  	if value := v.(string); value != "" {
   271  		chargeType := common.InternetChargeType(value)
   272  		if chargeType != common.PayByBandwidth &&
   273  			chargeType != common.PayByTraffic {
   274  			errors = append(errors, fmt.Errorf(
   275  				"%q must contain a valid InstanceChargeType, expected %s or %s, got %q",
   276  				k, common.PayByBandwidth, common.PayByTraffic, chargeType))
   277  		}
   278  	}
   279  
   280  	return
   281  }
   282  
   283  func validateInternetMaxBandWidthOut(v interface{}, k string) (ws []string, errors []error) {
   284  	value := v.(int)
   285  	if value < 0 || value > 100 {
   286  		errors = append(errors, fmt.Errorf(
   287  			"%q must be a valid internet bandwidth out between 0 and 100",
   288  			k))
   289  		return
   290  	}
   291  	return
   292  }
   293  
   294  // SLB
   295  func validateSlbName(v interface{}, k string) (ws []string, errors []error) {
   296  	if value := v.(string); value != "" {
   297  		if len(value) < 1 || len(value) > 80 {
   298  			errors = append(errors, fmt.Errorf(
   299  				"%q must be a valid load balancer name characters between 1 and 80",
   300  				k))
   301  			return
   302  		}
   303  	}
   304  
   305  	return
   306  }
   307  
   308  func validateSlbInternetChargeType(v interface{}, k string) (ws []string, errors []error) {
   309  	if value := v.(string); value != "" {
   310  		chargeType := common.InternetChargeType(value)
   311  
   312  		if chargeType != "paybybandwidth" &&
   313  			chargeType != "paybytraffic" {
   314  			errors = append(errors, fmt.Errorf(
   315  				"%q must contain a valid InstanceChargeType, expected %s or %s, got %q",
   316  				k, "paybybandwidth", "paybytraffic", value))
   317  		}
   318  	}
   319  
   320  	return
   321  }
   322  
   323  func validateSlbBandwidth(v interface{}, k string) (ws []string, errors []error) {
   324  	value := v.(int)
   325  	if value < 1 || value > 1000 {
   326  		errors = append(errors, fmt.Errorf(
   327  			"%q must be a valid load balancer bandwidth between 1 and 1000",
   328  			k))
   329  		return
   330  	}
   331  	return
   332  }
   333  
   334  func validateSlbListenerBandwidth(v interface{}, k string) (ws []string, errors []error) {
   335  	value := v.(int)
   336  	if (value < 1 || value > 1000) && value != -1 {
   337  		errors = append(errors, fmt.Errorf(
   338  			"%q must be a valid load balancer bandwidth between 1 and 1000 or -1",
   339  			k))
   340  		return
   341  	}
   342  	return
   343  }
   344  
   345  func validateSlbListenerScheduler(v interface{}, k string) (ws []string, errors []error) {
   346  	if value := v.(string); value != "" {
   347  		scheduler := slb.SchedulerType(value)
   348  
   349  		if scheduler != "wrr" && scheduler != "wlc" {
   350  			errors = append(errors, fmt.Errorf(
   351  				"%q must contain a valid SchedulerType, expected %s or %s, got %q",
   352  				k, "wrr", "wlc", value))
   353  		}
   354  	}
   355  
   356  	return
   357  }
   358  
   359  func validateSlbListenerCookie(v interface{}, k string) (ws []string, errors []error) {
   360  	if value := v.(string); value != "" {
   361  		if len(value) < 1 || len(value) > 200 {
   362  			errors = append(errors, fmt.Errorf("%q cannot be longer than 200 characters", k))
   363  		}
   364  	}
   365  	return
   366  }
   367  
   368  func validateSlbListenerCookieTimeout(v interface{}, k string) (ws []string, errors []error) {
   369  	value := v.(int)
   370  	if value < 0 || value > 86400 {
   371  		errors = append(errors, fmt.Errorf(
   372  			"%q must be a valid load balancer cookie timeout between 0 and 86400",
   373  			k))
   374  		return
   375  	}
   376  	return
   377  }
   378  
   379  func validateSlbListenerPersistenceTimeout(v interface{}, k string) (ws []string, errors []error) {
   380  	value := v.(int)
   381  	if value < 0 || value > 3600 {
   382  		errors = append(errors, fmt.Errorf(
   383  			"%q must be a valid load balancer persistence timeout between 0 and 86400",
   384  			k))
   385  		return
   386  	}
   387  	return
   388  }
   389  
   390  func validateSlbListenerHealthCheckDomain(v interface{}, k string) (ws []string, errors []error) {
   391  	if value := v.(string); value != "" {
   392  		//the len add "$_ip",so to max is 84
   393  		if len(value) < 1 || len(value) > 84 {
   394  			errors = append(errors, fmt.Errorf("%q cannot be longer than 84 characters", k))
   395  		}
   396  	}
   397  	return
   398  }
   399  
   400  func validateSlbListenerHealthCheckUri(v interface{}, k string) (ws []string, errors []error) {
   401  	if value := v.(string); value != "" {
   402  		if len(value) < 1 || len(value) > 80 {
   403  			errors = append(errors, fmt.Errorf("%q cannot be longer than 80 characters", k))
   404  		}
   405  	}
   406  	return
   407  }
   408  
   409  func validateSlbListenerHealthCheckConnectPort(v interface{}, k string) (ws []string, errors []error) {
   410  	value := v.(int)
   411  	if value < 1 || value > 65535 {
   412  		if value != -520 {
   413  			errors = append(errors, fmt.Errorf(
   414  				"%q must be a valid load balancer health check connect port between 1 and 65535 or -520",
   415  				k))
   416  			return
   417  		}
   418  
   419  	}
   420  	return
   421  }
   422  
   423  func validateDBBackupPeriod(v interface{}, k string) (ws []string, errors []error) {
   424  	days := []string{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}
   425  	value := v.(string)
   426  	exist := false
   427  	for _, d := range days {
   428  		if value == d {
   429  			exist = true
   430  			break
   431  		}
   432  	}
   433  	if !exist {
   434  		errors = append(errors, fmt.Errorf(
   435  			"%q must contain a valid backup period value should in array %#v, got %q",
   436  			k, days, value))
   437  	}
   438  
   439  	return
   440  }
   441  
   442  func validateAllowedStringValue(ss []string) schema.SchemaValidateFunc {
   443  	return func(v interface{}, k string) (ws []string, errors []error) {
   444  		value := v.(string)
   445  		existed := false
   446  		for _, s := range ss {
   447  			if s == value {
   448  				existed = true
   449  				break
   450  			}
   451  		}
   452  		if !existed {
   453  			errors = append(errors, fmt.Errorf(
   454  				"%q must contain a valid string value should in array %#v, got %q",
   455  				k, ss, value))
   456  		}
   457  		return
   458  
   459  	}
   460  }
   461  
   462  func validateAllowedSplitStringValue(ss []string, splitStr string) schema.SchemaValidateFunc {
   463  	return func(v interface{}, k string) (ws []string, errors []error) {
   464  		value := v.(string)
   465  		existed := false
   466  		tsList := strings.Split(value, splitStr)
   467  
   468  		for _, ts := range tsList {
   469  			existed = false
   470  			for _, s := range ss {
   471  				if ts == s {
   472  					existed = true
   473  					break
   474  				}
   475  			}
   476  		}
   477  		if !existed {
   478  			errors = append(errors, fmt.Errorf(
   479  				"%q must contain a valid string value should in %#v, got %q",
   480  				k, ss, value))
   481  		}
   482  		return
   483  
   484  	}
   485  }
   486  
   487  func validateAllowedIntValue(is []int) schema.SchemaValidateFunc {
   488  	return func(v interface{}, k string) (ws []string, errors []error) {
   489  		value := v.(int)
   490  		existed := false
   491  		for _, i := range is {
   492  			if i == value {
   493  				existed = true
   494  				break
   495  			}
   496  		}
   497  		if !existed {
   498  			errors = append(errors, fmt.Errorf(
   499  				"%q must contain a valid int value should in array %#v, got %q",
   500  				k, is, value))
   501  		}
   502  		return
   503  
   504  	}
   505  }
   506  
   507  func validateIntegerInRange(min, max int) schema.SchemaValidateFunc {
   508  	return func(v interface{}, k string) (ws []string, errors []error) {
   509  		value := v.(int)
   510  		if value < min {
   511  			errors = append(errors, fmt.Errorf(
   512  				"%q cannot be lower than %d: %d", k, min, value))
   513  		}
   514  		if value > max {
   515  			errors = append(errors, fmt.Errorf(
   516  				"%q cannot be higher than %d: %d", k, max, value))
   517  		}
   518  		return
   519  	}
   520  }
   521  
   522  //data source validate func
   523  //data_source_alicloud_image
   524  func validateNameRegex(v interface{}, k string) (ws []string, errors []error) {
   525  	value := v.(string)
   526  
   527  	if _, err := regexp.Compile(value); err != nil {
   528  		errors = append(errors, fmt.Errorf(
   529  			"%q contains an invalid regular expression: %s",
   530  			k, err))
   531  	}
   532  	return
   533  }
   534  
   535  func validateImageOwners(v interface{}, k string) (ws []string, errors []error) {
   536  	if value := v.(string); value != "" {
   537  		owners := ecs.ImageOwnerAlias(value)
   538  		if owners != ecs.ImageOwnerSystem &&
   539  			owners != ecs.ImageOwnerSelf &&
   540  			owners != ecs.ImageOwnerOthers &&
   541  			owners != ecs.ImageOwnerMarketplace &&
   542  			owners != ecs.ImageOwnerDefault {
   543  			errors = append(errors, fmt.Errorf(
   544  				"%q must contain a valid Image owner , expected %s, %s, %s, %s or %s, got %q",
   545  				k, ecs.ImageOwnerSystem, ecs.ImageOwnerSelf, ecs.ImageOwnerOthers, ecs.ImageOwnerMarketplace, ecs.ImageOwnerDefault, owners))
   546  		}
   547  	}
   548  	return
   549  }
   550  
   551  func validateRegion(v interface{}, k string) (ws []string, errors []error) {
   552  	if value := v.(string); value != "" {
   553  		region := common.Region(value)
   554  		var valid string
   555  		for _, re := range common.ValidRegions {
   556  			if region == re {
   557  				return
   558  			}
   559  			valid = valid + ", " + string(re)
   560  		}
   561  		errors = append(errors, fmt.Errorf(
   562  			"%q must contain a valid Region ID , expected %#v, got %q",
   563  			k, valid, value))
   564  
   565  	}
   566  	return
   567  }
   568  
   569  func validateForwardPort(v interface{}, k string) (ws []string, errors []error) {
   570  	value := v.(string)
   571  	if value != "any" {
   572  		valueConv, err := strconv.Atoi(value)
   573  		if err != nil || valueConv < 1 || valueConv > 65535 {
   574  			errors = append(errors, fmt.Errorf("%q must be a valid port between 1 and 65535 or any ", k))
   575  		}
   576  	}
   577  	return
   578  }