diff --git a/ibm/provider.go b/ibm/provider.go index 6c27610147..f2bb0d2b01 100644 --- a/ibm/provider.go +++ b/ibm/provider.go @@ -443,6 +443,7 @@ func Validator() ValidatorDict { ResourceValidatorDictionary: map[string]*ResourceValidator{ "ibm_is_vpc": resourceIBMISVPCValidator(), "ibm_is_ike_policy": resourceIBMISIKEValidator(), + "ibm_is_network_acl": resourceIBMISNetworkACLValidator(), "ibm_iam_custom_role": resourceIBMIAMCustomRoleValidator(), "ibm_cis_rate_limit": resourceIBMCISRateLimitValidator(), "ibm_tg_gateway": resourceIBMTGValidator(), diff --git a/ibm/resource_ibm_is_networkacls.go b/ibm/resource_ibm_is_networkacls.go index 8f472b41de..b685b1fe6a 100644 --- a/ibm/resource_ibm_is_networkacls.go +++ b/ibm/resource_ibm_is_networkacls.go @@ -57,7 +57,7 @@ func resourceIBMISNetworkACL() *schema.Resource { Type: schema.TypeString, Required: true, ForceNew: false, - ValidateFunc: validateISName, + ValidateFunc: InvokeValidator("ibm_is_network_acl", isNetworkACLName), Description: "Network ACL name", }, isNetworkACLVPC: { @@ -106,35 +106,39 @@ func resourceIBMISNetworkACL() *schema.Resource { Computed: true, }, isNetworkACLRuleName: { - Type: schema.TypeString, - Required: true, - ForceNew: false, + Type: schema.TypeString, + Required: true, + ForceNew: false, + ValidateFunc: InvokeValidator("ibm_is_network_acl", isNetworkACLRuleName), }, isNetworkACLRuleAction: { - Type: schema.TypeString, - Required: true, - ForceNew: false, + Type: schema.TypeString, + Required: true, + ForceNew: false, + ValidateFunc: InvokeValidator("ibm_is_network_acl", isNetworkACLRuleAction), }, isNetworkACLRuleIPVersion: { Type: schema.TypeString, Computed: true, }, isNetworkACLRuleSource: { - Type: schema.TypeString, - Required: true, - ForceNew: false, + Type: schema.TypeString, + Required: true, + ForceNew: false, + ValidateFunc: InvokeValidator("ibm_is_network_acl", isNetworkACLRuleSource), }, isNetworkACLRuleDestination: { - Type: schema.TypeString, - Required: true, - ForceNew: false, + Type: schema.TypeString, + Required: true, + ForceNew: false, + ValidateFunc: InvokeValidator("ibm_is_network_acl", isNetworkACLRuleDestination), }, isNetworkACLRuleDirection: { Type: schema.TypeString, Required: true, ForceNew: false, Description: "Direction of traffic to enforce, either inbound or outbound", - ValidateFunc: validateIsNetworkAclRuleDirection, + ValidateFunc: InvokeValidator("ibm_is_network_acl", isNetworkACLRuleDirection), }, isNetworkACLSubnets: { Type: schema.TypeInt, @@ -148,12 +152,14 @@ func resourceIBMISNetworkACL() *schema.Resource { Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ isNetworkACLRuleICMPCode: { - Type: schema.TypeInt, - Optional: true, + Type: schema.TypeInt, + Optional: true, + ValidateFunc: InvokeValidator("ibm_is_network_acl", isNetworkACLRuleICMPCode), }, isNetworkACLRuleICMPType: { - Type: schema.TypeInt, - Optional: true, + Type: schema.TypeInt, + Optional: true, + ValidateFunc: InvokeValidator("ibm_is_network_acl", isNetworkACLRuleICMPType), }, }, }, @@ -167,24 +173,28 @@ func resourceIBMISNetworkACL() *schema.Resource { Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ isNetworkACLRulePortMax: { - Type: schema.TypeInt, - Optional: true, - Default: 65535, + Type: schema.TypeInt, + Optional: true, + Default: 65535, + ValidateFunc: InvokeValidator("ibm_is_network_acl", isNetworkACLRulePortMax), }, isNetworkACLRulePortMin: { - Type: schema.TypeInt, - Optional: true, - Default: 1, + Type: schema.TypeInt, + Optional: true, + Default: 1, + ValidateFunc: InvokeValidator("ibm_is_network_acl", isNetworkACLRulePortMin), }, isNetworkACLRuleSourcePortMax: { - Type: schema.TypeInt, - Optional: true, - Default: 65535, + Type: schema.TypeInt, + Optional: true, + Default: 65535, + ValidateFunc: InvokeValidator("ibm_is_network_acl", isNetworkACLRuleSourcePortMax), }, isNetworkACLRuleSourcePortMin: { - Type: schema.TypeInt, - Optional: true, - Default: 1, + Type: schema.TypeInt, + Optional: true, + Default: 1, + ValidateFunc: InvokeValidator("ibm_is_network_acl", isNetworkACLRuleSourcePortMin), }, }, }, @@ -198,24 +208,28 @@ func resourceIBMISNetworkACL() *schema.Resource { Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ isNetworkACLRulePortMax: { - Type: schema.TypeInt, - Optional: true, - Default: 65535, + Type: schema.TypeInt, + Optional: true, + Default: 65535, + ValidateFunc: InvokeValidator("ibm_is_network_acl", isNetworkACLRulePortMax), }, isNetworkACLRulePortMin: { - Type: schema.TypeInt, - Optional: true, - Default: 1, + Type: schema.TypeInt, + Optional: true, + Default: 1, + ValidateFunc: InvokeValidator("ibm_is_network_acl", isNetworkACLRulePortMin), }, isNetworkACLRuleSourcePortMax: { - Type: schema.TypeInt, - Optional: true, - Default: 65535, + Type: schema.TypeInt, + Optional: true, + Default: 65535, + ValidateFunc: InvokeValidator("ibm_is_network_acl", isNetworkACLRuleSourcePortMax), }, isNetworkACLRuleSourcePortMin: { - Type: schema.TypeInt, - Optional: true, - Default: 1, + Type: schema.TypeInt, + Optional: true, + Default: 1, + ValidateFunc: InvokeValidator("ibm_is_network_acl", isNetworkACLRuleSourcePortMin), }, }, }, @@ -227,6 +241,103 @@ func resourceIBMISNetworkACL() *schema.Resource { } } +func resourceIBMISNetworkACLValidator() *ResourceValidator { + + validateSchema := make([]ValidateSchema, 1) + direction := "inbound, outbound" + action := "allow, deny" + + validateSchema = append(validateSchema, + ValidateSchema{ + Identifier: isNetworkACLRuleAction, + ValidateFunctionIdentifier: ValidateAllowedStringValue, + Type: TypeString, + Required: true, + AllowedValues: action}) + validateSchema = append(validateSchema, + ValidateSchema{ + Identifier: isNetworkACLRuleDirection, + ValidateFunctionIdentifier: ValidateAllowedStringValue, + Type: TypeString, + Required: true, + AllowedValues: direction}) + validateSchema = append(validateSchema, + ValidateSchema{ + Identifier: isNetworkACLName, + ValidateFunctionIdentifier: ValidateRegexpLen, + Type: TypeString, + Required: true, + Regexp: `^([a-z]|[a-z][-a-z0-9]*[a-z0-9])$`, + MinValueLength: 1, + MaxValueLength: 63}) + validateSchema = append(validateSchema, + ValidateSchema{ + Identifier: isNetworkACLRuleName, + ValidateFunctionIdentifier: ValidateRegexpLen, + Type: TypeString, + Required: true, + Regexp: `^([a-z]|[a-z][-a-z0-9]*[a-z0-9])$`, + MinValueLength: 1, + MaxValueLength: 63}) + validateSchema = append(validateSchema, + ValidateSchema{ + Identifier: isNetworkACLRuleDestination, + ValidateFunctionIdentifier: ValidateIPorCIDR, + Type: TypeString, + Required: true}) + validateSchema = append(validateSchema, + ValidateSchema{ + Identifier: isNetworkACLRuleSource, + ValidateFunctionIdentifier: ValidateIPorCIDR, + Type: TypeString, + Required: true}) + validateSchema = append(validateSchema, + ValidateSchema{ + Identifier: isNetworkACLRuleICMPType, + ValidateFunctionIdentifier: IntBetween, + Type: TypeInt, + MinValue: "0", + MaxValue: "254"}) + validateSchema = append(validateSchema, + ValidateSchema{ + Identifier: isNetworkACLRuleICMPCode, + ValidateFunctionIdentifier: IntBetween, + Type: TypeInt, + MinValue: "0", + MaxValue: "255"}) + validateSchema = append(validateSchema, + ValidateSchema{ + Identifier: isNetworkACLRulePortMin, + ValidateFunctionIdentifier: IntBetween, + Type: TypeInt, + MinValue: "1", + MaxValue: "65535"}) + validateSchema = append(validateSchema, + ValidateSchema{ + Identifier: isNetworkACLRulePortMax, + ValidateFunctionIdentifier: IntBetween, + Type: TypeInt, + MinValue: "1", + MaxValue: "65535"}) + validateSchema = append(validateSchema, + ValidateSchema{ + Identifier: isNetworkACLRuleSourcePortMin, + ValidateFunctionIdentifier: IntBetween, + Type: TypeInt, + MinValue: "1", + MaxValue: "65535"}) + validateSchema = append(validateSchema, + ValidateSchema{ + Identifier: isNetworkACLRuleSourcePortMax, + ValidateFunctionIdentifier: IntBetween, + Type: TypeInt, + MinValue: "1", + MaxValue: "65535"}) + + ibmISNetworkACLResourceValidator := ResourceValidator{ResourceName: "ibm_is_network_acl", Schema: validateSchema} + return &ibmISNetworkACLResourceValidator +} + func resourceIBMISNetworkACLCreate(d *schema.ResourceData, meta interface{}) error { userDetails, err := meta.(ClientSession).BluemixUserDetails() if err != nil { diff --git a/ibm/resource_ibm_is_networkacls_test.go b/ibm/resource_ibm_is_networkacls_test.go index ebd86dc3ac..4997a8223b 100644 --- a/ibm/resource_ibm_is_networkacls_test.go +++ b/ibm/resource_ibm_is_networkacls_test.go @@ -167,7 +167,7 @@ func testAccCheckIBMISNetworkACLConfig() string { func testAccCheckIBMISNetworkACLConfig1() string { return fmt.Sprintf(` resource "ibm_is_vpc" "testacc_vpc" { - name = "vpctest" + name = "tf-nwacl-vpc" } resource "ibm_is_network_acl" "isExampleACL" { diff --git a/ibm/validators.go b/ibm/validators.go index 84bf957115..23e83012ed 100644 --- a/ibm/validators.go +++ b/ibm/validators.go @@ -345,26 +345,6 @@ func validateSecurityRuleDirection(v interface{}, k string) (ws []string, errors return } -func validateIsNetworkAclRuleDirection(v interface{}, k string) (ws []string, errors []error) { - validDirections := map[string]bool{ - "inbound": true, - "outbound": true, - } - - value := v.(string) - _, found := validDirections[value] - if !found { - strarray := make([]string, 0, len(validDirections)) - for key := range validDirections { - strarray = append(strarray, key) - } - errors = append(errors, fmt.Errorf( - "%q contains an invalid Network Acls direction %q. Valid types are %q.", - k, value, strings.Join(strarray, ","))) - } - return -} - func validateIsSecurityRuleDirection(v interface{}, k string) (ws []string, errors []error) { validDirections := map[string]bool{ "inbound": true, @@ -441,6 +421,21 @@ func validateRemoteIP(v interface{}, k string) (ws []string, errors []error) { return } +//validateIPorCIDR... +func validateIPorCIDR() schema.SchemaValidateFunc { + return func(v interface{}, k string) (ws []string, errors []error) { + _, err1 := validateCIDR(v, k) + _, err2 := validateIP(v, k) + + if len(err1) != 0 && len(err2) != 0 { + errors = append(errors, fmt.Errorf( + "%q must be a valid remote ip address (cidr or ip)", + k)) + } + return + } +} + func validateSecurityRuleProtocol(v interface{}, k string) (ws []string, errors []error) { validProtocols := map[string]bool{ "icmp": true, @@ -833,6 +828,7 @@ func validateAuthProtocol(v interface{}, k string) (ws []string, errors []error) return } +//ValidateIPVersion func validateIPVersion(v interface{}, k string) (ws []string, errors []error) { validVersions := map[string]bool{ "ipv4": true, @@ -1031,6 +1027,7 @@ func validateLBListenerConnectionLimit(v interface{}, k string) (ws []string, er return } +//ValidateISName func validateISName(v interface{}, k string) (ws []string, errors []error) { name := v.(string) acceptedcharacters, _ := regexp.MatchString(`^[a-z][-a-z0-9]*$`, name) @@ -1072,7 +1069,7 @@ const ( IntAtMost ValidateAllowedStringValue StringLenBetween - ValidateCIDR + ValidateIPorCIDR ValidateAllowedIntValue ValidateRegexpLen ValidateRegexp @@ -1203,8 +1200,8 @@ func invokeValidatorInternal(schema ValidateSchema) schema.SchemaValidateFunc { return validateAllowedStringValue(allowedValues.([]string)) case StringLenBetween: return validation.StringLenBetween(schema.MinValueLength, schema.MaxValueLength) - case ValidateCIDR: - return nil + case ValidateIPorCIDR: + return validateIPorCIDR() case ValidateAllowedIntValue: allowedValues := schema.GetValue(AllowedValues) return validateAllowedIntValue(allowedValues.([]int))