Skip to content

Commit

Permalink
fix: Implemented IPv4 address validation for dest_address in the reso…
Browse files Browse the repository at this point in the history
…urce zia_firewall_filtering_rule (#368)

* fix: Implemented IPv4 address validation for dest_address in the resource zia_firewall_filtering_rule
  • Loading branch information
willguibr authored Aug 27, 2024
1 parent 986dbb2 commit 4656294
Show file tree
Hide file tree
Showing 9 changed files with 144 additions and 18 deletions.
39 changes: 39 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
Provide a general summary of your changes in the title above. You should
remove this overview, any sections and any section descriptions you
don't need below before submitting. There isn't a strict requirement to
use this template if you can structure your description and still cover
these points.

## Description

Describe your changes in detail through motivation and context. Why is
this change required? What problem does it solve? If it fixes an open
issue, link to the issue using GitHub's closing issues keywords[1].

## Has your change been tested?

Explain how the change has been tested and what you ran to confirm your
change affects other parts of the code. Automated tests are generally
expected and changes without tests should explain why they aren't
required.

## Screenshots (if appropriate):

## Types of changes

What sort of change does your code introduce/modify?

- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing functionality to change)

## Checklist:

- [ ] My code follows the code style of this project.
- [ ] My change requires a change to the documentation.
- [ ] I have updated the documentation accordingly.
- [ ] I have added tests to cover my changes.
- [ ] All new and existing tests passed.
- [ ] This change is using publicly documented and stable APIs.

[1]: https://help.github.com/articles/closing-issues-using-keywords/
15 changes: 13 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
# Changelog

## 3.0.2 (August, xx 2024)
## 3.0.3 (August, 26 2024)

### Notes

- Release date: **(August, xx 2024)**
- Release date: **(August, 26 2024)**
- Supported Terraform version: **v1.x**

### Bug Fixes

- [PR #368](https://github.com/zscaler/terraform-provider-zia/pull/368) - Implemented runtime validation for the attribute `dest_addresses` in the resource: `zia_firewall_filtering_rule`. The provider now validates if the IP address provided is an IPv4.

## 3.0.2 (August, 19 2024)

### Notes

- Release date: **(August, 19 2024)**
- Supported Terraform version: **v1.x**

### Bug Fixes
Expand Down
6 changes: 3 additions & 3 deletions GNUmakefile
Original file line number Diff line number Diff line change
Expand Up @@ -196,14 +196,14 @@ test\:integration\:zscalertwo:
build13: GOOS=$(shell go env GOOS)
build13: GOARCH=$(shell go env GOARCH)
ifeq ($(OS),Windows_NT) # is Windows_NT on XP, 2000, 7, Vista, 10...
build13: DESTINATION=$(APPDATA)/terraform.d/plugins/$(ZIA_PROVIDER_NAMESPACE)/3.0.2/$(GOOS)_$(GOARCH)
build13: DESTINATION=$(APPDATA)/terraform.d/plugins/$(ZIA_PROVIDER_NAMESPACE)/3.0.3/$(GOOS)_$(GOARCH)
else
build13: DESTINATION=$(HOME)/.terraform.d/plugins/$(ZIA_PROVIDER_NAMESPACE)/3.0.2/$(GOOS)_$(GOARCH)
build13: DESTINATION=$(HOME)/.terraform.d/plugins/$(ZIA_PROVIDER_NAMESPACE)/3.0.3/$(GOOS)_$(GOARCH)
endif
build13: fmtcheck
@echo "==> Installing plugin to $(DESTINATION)"
@mkdir -p $(DESTINATION)
go build -o $(DESTINATION)/terraform-provider-zia_v3.0.2
go build -o $(DESTINATION)/terraform-provider-zia_v3.0.3

coverage: test
@echo "✓ Opening coverage for unit tests ..."
Expand Down
17 changes: 14 additions & 3 deletions docs/guides/release-notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,26 @@ description: |-
Track all ZIA Terraform provider's releases. New resources, features, and bug fixes will be tracked here.

---
``Last updated: v3.0.2``
``Last updated: v3.0.3``

---

## 3.0.2 (August, xx 2024)
## 3.0.3 (August, 26 2024)

### Notes

- Release date: **(August, xx 2024)**
- Release date: **(August, 26 2024)**
- Supported Terraform version: **v1.x**

### Bug Fixes

- [PR #368](https://github.com/zscaler/terraform-provider-zia/pull/368) - Implemented runtime validation for the attribute `dest_addresses` in the resource: `zia_firewall_filtering_rule`. The provider now validates if the IP address provided is an IPv4.

## 3.0.2 (August, 19 2024)

### Notes

- Release date: **(August, 19 2024)**
- Supported Terraform version: **v1.x**

### Bug Fixes
Expand Down
3 changes: 3 additions & 0 deletions docs/resources/zia_dlp_web_rules.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,9 @@ resource "zia_dlp_web_rules" "this" {
icap_server {
id = data.zia_dlp_incident_receiver_servers.this.id
}
notification_template {
id = data.zia_dlp_notification_templates.this.id
}
}
```

Expand Down
7 changes: 2 additions & 5 deletions docs/resources/zia_firewall_filtering_rule.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,15 +92,12 @@ The following arguments are supported:
* `nw_application_groups` - (Optional) Any number of application groups that you want to control with this rule. The service provides predefined applications that you can group, but not modify
* `nw_applications` - (Optional) When not used it applies the rule to all applications. The service provides predefined applications, which you can group, but not modify.

`source ip addresses` supports the following attributes:

* `src_ip_groups` - (Optional) Any number of source IP address groups that you want to control with this rule.
- `id` - (String) Identifier that uniquely identifies an entity
* `src_ips` - (Optional) You can enter individual IP addresses, subnets, or address ranges.

`destinations` supports the following attributes:

* `dest_addresses`** - (Optional) - IP addresses and fully qualified domain names (FQDNs), if the domain has multiple destination IP addresses or if its IP addresses may change. For IP addresses, you can enter individual IP addresses, subnets, or address ranges. If adding multiple items, hit Enter after each entry.
* `dest_addresses`** - (Optional) - IP addresses and fully qualified domain names (FQDNs), if the domain has multiple destination IP addresses or if its IP addresses may change. For IP addresses, you can enter individual IP addresses, subnets, or address ranges.
**NOTE**: PLEASE BE AWARE. The API supports ONLY `IPv4` addresses. `IPV6` addresses are not supported.
* `dest_countries`** - (Optional) Identify destinations based on the location of a server, select Any to apply the rule to all countries or select the countries to which you want to control traffic.
* `dest_ip_categories`** - (Optional) identify destinations based on the URL category of the domain, select Any to apply the rule to all categories or select the specific categories you want to control.
- `id` - (String) Identifier that uniquely identifies an entity
Expand Down
9 changes: 5 additions & 4 deletions zia/resource_zia_cloud_app_control_rules.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,10 @@ func resourceCloudAppControlRules() *schema.Resource {
Description: "Actions allowed for the specified type.",
},
"applications": {
Type: schema.TypeSet,
Elem: &schema.Schema{Type: schema.TypeString},
Optional: true,
Type: schema.TypeSet,
Elem: &schema.Schema{Type: schema.TypeString},
Optional: true,
Description: "List of cloud applications for which rule will be applied",
},
"time_quota": {
Type: schema.TypeInt,
Expand Down Expand Up @@ -168,7 +169,7 @@ func resourceCloudAppControlRules() *schema.Resource {
"cascading_enabled": {
Type: schema.TypeBool,
Optional: true,
Description: "The unique identifier for the device.",
Description: "nforce the URL Filtering policy on a transaction, even after it is explicitly allowed by the Cloud App Control policy.",
},
"cbi_profile": {
Type: schema.TypeList,
Expand Down
6 changes: 5 additions & 1 deletion zia/resource_zia_firewall_filtering_rules.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,11 @@ func resourceFirewallFilteringRules() *schema.Resource {
"dest_addresses": {
Type: schema.TypeSet,
Optional: true,
Elem: &schema.Schema{Type: schema.TypeString},
Elem: &schema.Schema{
Type: schema.TypeString,
ValidateFunc: validateDestAddress, // Apply the custom validation function here
},
Description: "Destination addresses. Supports IPv4, FQDNs, or wildcard FQDNs",
},
"dest_ip_categories": {
Type: schema.TypeSet,
Expand Down
60 changes: 60 additions & 0 deletions zia/validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"context"
"errors"
"fmt"
"net"
"regexp"
"strings"

"github.com/biter777/countries"
Expand Down Expand Up @@ -781,3 +783,61 @@ func validatePredefinedIdentifier(val interface{}, key string) (warns []string,
errs = append(errs, fmt.Errorf("%q is not a valid predefined identifier. Supported identifiers are: %v", key, supportedIdentifiers))
return
}

func validateDestAddress(v interface{}, k string) (ws []string, errors []error) {
value := v.(string)

// Regular expression to match FQDNs and wildcard FQDNs
fqdnRegex := `^(\*\.)?([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}$`

// Regular expression to match IPv4 ranges
ipRangeRegex := `^(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})-(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})$`

// Check if the value is a valid IPv4 CIDR
if _, _, err := net.ParseCIDR(value); err == nil {
ip, _, _ := net.ParseCIDR(value)
if ip.To4() != nil {
// It's a valid IPv4 CIDR
return
} else {
errors = append(errors, fmt.Errorf("invalid IPv4 address: %s. IPv6 addresses are not allowed", value))
return
}
}

// Check if the value is a valid IPv4 address (without CIDR)
if ip := net.ParseIP(value); ip != nil {
if ip.To4() != nil {
// It's a valid IPv4 address
return
} else {
errors = append(errors, fmt.Errorf("invalid IPv4 address: %s. IPv6 addresses are not allowed", value))
return
}
}

// Check if the value is a valid IPv4 range
if matched, _ := regexp.MatchString(ipRangeRegex, value); matched {
parts := strings.Split(value, "-")
if len(parts) == 2 {
startIP := net.ParseIP(parts[0])
endIP := net.ParseIP(parts[1])
if startIP != nil && endIP != nil && startIP.To4() != nil && endIP.To4() != nil {
// It's a valid IPv4 range
return
}
}
errors = append(errors, fmt.Errorf("invalid IPv4 range: %s. Must be a valid IPv4 range", value))
return
}

// Check if the value is a valid FQDN or wildcard FQDN
if matched, _ := regexp.MatchString(fqdnRegex, value); matched {
// It's a valid FQDN or wildcard FQDN
return
}

// If none of the above checks passed, it must be an invalid address
errors = append(errors, fmt.Errorf("invalid address: %s. Must be a valid IPv4 address, IPv4 CIDR, IPv4 range, FQDN, or wildcard FQDN", value))
return
}

0 comments on commit 4656294

Please sign in to comment.