From 4656294bb0ffc32ab53b865218114617879a192b Mon Sep 17 00:00:00 2001 From: William Guilherme Date: Tue, 27 Aug 2024 04:07:04 -1000 Subject: [PATCH] fix: Implemented IPv4 address validation for dest_address in the resource zia_firewall_filtering_rule (#368) * fix: Implemented IPv4 address validation for dest_address in the resource zia_firewall_filtering_rule --- .github/pull_request_template.md | 39 ++++++++++++ CHANGELOG.md | 15 ++++- GNUmakefile | 6 +- docs/guides/release-notes.md | 17 +++++- docs/resources/zia_dlp_web_rules.md | 3 + docs/resources/zia_firewall_filtering_rule.md | 7 +-- zia/resource_zia_cloud_app_control_rules.go | 9 +-- zia/resource_zia_firewall_filtering_rules.go | 6 +- zia/validator.go | 60 +++++++++++++++++++ 9 files changed, 144 insertions(+), 18 deletions(-) create mode 100644 .github/pull_request_template.md diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 00000000..9efebb3a --- /dev/null +++ b/.github/pull_request_template.md @@ -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/ diff --git a/CHANGELOG.md b/CHANGELOG.md index 475ede08..ad34ecd5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/GNUmakefile b/GNUmakefile index eff9a3fa..456a68a4 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -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 ..." diff --git a/docs/guides/release-notes.md b/docs/guides/release-notes.md index be1e3db6..9597cc98 100644 --- a/docs/guides/release-notes.md +++ b/docs/guides/release-notes.md @@ -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 diff --git a/docs/resources/zia_dlp_web_rules.md b/docs/resources/zia_dlp_web_rules.md index ff4d8cea..eeade607 100644 --- a/docs/resources/zia_dlp_web_rules.md +++ b/docs/resources/zia_dlp_web_rules.md @@ -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 + } } ``` diff --git a/docs/resources/zia_firewall_filtering_rule.md b/docs/resources/zia_firewall_filtering_rule.md index 4faef571..05e1621b 100644 --- a/docs/resources/zia_firewall_filtering_rule.md +++ b/docs/resources/zia_firewall_filtering_rule.md @@ -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 diff --git a/zia/resource_zia_cloud_app_control_rules.go b/zia/resource_zia_cloud_app_control_rules.go index 73621d8b..6b04bceb 100644 --- a/zia/resource_zia_cloud_app_control_rules.go +++ b/zia/resource_zia_cloud_app_control_rules.go @@ -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, @@ -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, diff --git a/zia/resource_zia_firewall_filtering_rules.go b/zia/resource_zia_firewall_filtering_rules.go index 381460e5..2a267867 100644 --- a/zia/resource_zia_firewall_filtering_rules.go +++ b/zia/resource_zia_firewall_filtering_rules.go @@ -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, diff --git a/zia/validator.go b/zia/validator.go index 239fa195..b03098a2 100644 --- a/zia/validator.go +++ b/zia/validator.go @@ -4,6 +4,8 @@ import ( "context" "errors" "fmt" + "net" + "regexp" "strings" "github.com/biter777/countries" @@ -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 +}