From 1eb0655d803d8639c59b82b3819b2b996b489698 Mon Sep 17 00:00:00 2001 From: William Guilherme Date: Sat, 5 Oct 2024 23:03:12 -0700 Subject: [PATCH] Fix: Fixed Application Segment Port Configuration Resource (#496) * Fix: Fixed Application Segment Port Configuration Resource * fix: Fixed application segment browser access microtenant * fix: Added New Access Policy Object Type Risk Factor --- .github/workflows/zpa-test.yml | 2 +- CHANGELOG.md | 23 ++ GNUmakefile | 6 +- docs/guides/release-notes.md | 25 +- .../zpa_application_segment_browser_access.md | 5 +- docs/resources/zpa_policy_access_rule.md | 1 + ..._policy_access_rule_application_segment.md | 1 + .../zpa_policy_access_rule_browser_access.md | 1 + .../zpa_policy_access_rule_posture_profile.md | 1 + .../zpa_policy_access_rule_risk_factor.md | 135 +++++++ docs/resources/zpa_policy_access_rule_saml.md | 1 + .../zpa_policy_access_rule_scim_attribute.md | 1 + .../zpa_policy_access_rule_scim_group.md | 1 + ...zpa_policy_access_rule_trusted_networks.md | 3 +- docs/resources/zpa_policy_access_rule_v2.md | 27 ++ go.mod | 2 +- go.sum | 4 +- zpa/common.go | 186 ++++++++-- ...ata_source_zpa_app_connector_controller.go | 254 ++++++++++++- zpa/data_source_zpa_app_connector_group.go | 6 +- zpa/data_source_zpa_application_segment.go | 55 +-- ..._zpa_application_segment_browser_access.go | 13 +- ...ce_zpa_application_segment_by_type_test.go | 2 + ...urce_zpa_application_segment_inspection.go | 15 +- ...data_source_zpa_application_segment_pra.go | 14 +- zpa/data_source_zpa_server_group.go | 335 +++--------------- zpa/resource_zpa_app_connector_group.go | 4 +- zpa/resource_zpa_application_segment.go | 198 ++--------- ..._zpa_application_segment_browser_access.go | 98 ++--- ...urce_zpa_application_segment_inspection.go | 92 ++--- ...zpa_application_segment_inspection_test.go | 4 +- zpa/resource_zpa_application_segment_pra.go | 123 ++++--- ...source_zpa_application_segment_pra_test.go | 4 +- zpa/resource_zpa_application_segment_test.go | 22 +- ...urce_zpa_policy_access_redirection_rule.go | 6 +- ...zpa_policy_access_redirection_rule_test.go | 2 +- zpa/resource_zpa_policy_access_rule.go | 15 +- zpa/resource_zpa_policy_access_rule_test.go | 32 +- zpa/resource_zpa_policy_access_rule_v2.go | 13 +- ...resource_zpa_policy_access_rule_v2_test.go | 52 ++- zpa/resource_zpa_segment_group.go | 102 +++--- zpa/resource_zpa_server_group.go | 73 ++-- zpa/utils.go | 84 +++-- 43 files changed, 1163 insertions(+), 880 deletions(-) create mode 100644 docs/resources/zpa_policy_access_rule_risk_factor.md diff --git a/.github/workflows/zpa-test.yml b/.github/workflows/zpa-test.yml index 3ad85a02..a4c71404 100644 --- a/.github/workflows/zpa-test.yml +++ b/.github/workflows/zpa-test.yml @@ -229,7 +229,7 @@ jobs: ZPA_ACC_TEST_FORCE_SWEEPERS: ${{ secrets.ZPA_ACC_TEST_FORCE_SWEEPERS }} zpa-prod-tenants: - needs: [zpa-beta-tenants] + # needs: [zpa-beta-tenants] runs-on: ubuntu-latest strategy: fail-fast: false diff --git a/CHANGELOG.md b/CHANGELOG.md index 20ae4d18..cefe9f0a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,28 @@ # Changelog +## 3.33.7 (October, 3 2024) + +### Notes + +- Release date: **(October, 3 2024)** +- Supported Terraform version: **v1.x** + +### Enhancements +- [PR #496](/~https://github.com/zscaler/terraform-provider-zpa/pull/496) - Added new `object_type` `RISK_FACTOR_TYPE` to the following ZPA access policy resources: `zpa_policy_access_rule`, and `zpa_policy_access_rule_v2` + +### Bug Fixes +- [PR #496](/~https://github.com/zscaler/terraform-provider-zpa/pull/496) - Fixed issue with attribute `tcp_port_range`/`udp_port_range` and `tcp_port_ranges`/`udp_port_ranges` within `zpa_application_segment`. The fix ensure that both port configuration formats are suported separately without mid-conversion in between. The fix also ensure the port configuration order is ignored during apply and update process. [Issue #490](/~https://github.com/zscaler/terraform-provider-zpa/issues/490). + + +### Internal Changes +- [PR #496](/~https://github.com/zscaler/terraform-provider-zpa/pull/496) Consolidated multiple functions supported common/cross-shared resources. The following new common functions were introduced for simplicity: + - `expandCommonServerGroups` + - `expandCommonAppConnectorGroups` + - `expandCommonServiceEdgeGroups` + - `flattenCommonAppConnectorGroups` + - `flattenCommonAppServerGroups` + - `flattenCommonServiceEdgeGroups` + ## 3.33.6 (October, 1 2024) ### Notes diff --git a/GNUmakefile b/GNUmakefile index a6def29a..21a30ef6 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -55,14 +55,14 @@ test\:integration\:zpa: 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/$(ZPA_PROVIDER_NAMESPACE)/3.33.6/$(GOOS)_$(GOARCH) +build13: DESTINATION=$(APPDATA)/terraform.d/plugins/$(ZPA_PROVIDER_NAMESPACE)/3.33.7/$(GOOS)_$(GOARCH) else -build13: DESTINATION=$(HOME)/.terraform.d/plugins/$(ZPA_PROVIDER_NAMESPACE)/3.33.6/$(GOOS)_$(GOARCH) +build13: DESTINATION=$(HOME)/.terraform.d/plugins/$(ZPA_PROVIDER_NAMESPACE)/3.33.7/$(GOOS)_$(GOARCH) endif build13: fmtcheck @echo "==> Installing plugin to $(DESTINATION)" @mkdir -p $(DESTINATION) - go build -o $(DESTINATION)/terraform-provider-zpa_v3.33.6 + go build -o $(DESTINATION)/terraform-provider-zpa_v3.33.7 vet: @echo "==> Checking source code against go vet and staticcheck" diff --git a/docs/guides/release-notes.md b/docs/guides/release-notes.md index 196b540c..36b9aaf3 100644 --- a/docs/guides/release-notes.md +++ b/docs/guides/release-notes.md @@ -12,10 +12,33 @@ Track all ZPA Terraform provider's releases. New resources, features, and bug fi --- -``Last updated: v3.33.6`` +``Last updated: v3.33.7`` --- +## 3.33.7 (October, 3 2024) + +### Notes + +- Release date: **(October, 3 2024)** +- Supported Terraform version: **v1.x** + +### Enhancements +- [PR #496](/~https://github.com/zscaler/terraform-provider-zpa/pull/496) - Added new `object_type` `RISK_FACTOR_TYPE` to the following ZPA access policy resources: `zpa_policy_access_rule`, and `zpa_policy_access_rule_v2` + +### Bug Fixes +- [PR #496](/~https://github.com/zscaler/terraform-provider-zpa/pull/496) - Fixed issue with attribute `tcp_port_range`/`udp_port_range` and `tcp_port_ranges`/`udp_port_ranges` within `zpa_application_segment`. The fix ensure that both port configuration formats are suported separately without mid-conversion in between. The fix also ensure the port configuration order is ignored during apply and update process. [Issue #490](/~https://github.com/zscaler/terraform-provider-zpa/issues/490). + + +### Internal Changes +- [PR #496](/~https://github.com/zscaler/terraform-provider-zpa/pull/496) Consolidated multiple functions supported common/cross-shared resources. The following new common functions were introduced for simplicity: + - `expandCommonServerGroups` + - `expandCommonAppConnectorGroups` + - `expandCommonServiceEdgeGroups` + - `flattenCommonAppConnectorGroups` + - `flattenCommonAppServerGroups` + - `flattenCommonServiceEdgeGroups` + ## 3.33.6 (October, 1 2024) ### Notes diff --git a/docs/resources/zpa_application_segment_browser_access.md b/docs/resources/zpa_application_segment_browser_access.md index dad3b4f7..9fd8b9d4 100644 --- a/docs/resources/zpa_application_segment_browser_access.md +++ b/docs/resources/zpa_application_segment_browser_access.md @@ -108,6 +108,9 @@ The following arguments are supported: - `certificate_id` - (String) - ID of the BA certificate. Refer to the data source documentation for [`zpa_ba_certificate`](/~https://github.com/zscaler/terraform-provider-zpa/blob/master/docs/data-sources/zpa_ba_certificate.md) - `domain` - (String) - Domain name or IP address of the BA app. - `allow_options` - (Boolean) - If you want ZPA to forward unauthenticated HTTP preflight OPTIONS requests from the browser to the app.. Supported values: `true` and `false` + - `microtenant_id` (Boolean) The unique identifier of the Microtenant for the ZPA tenant. If you are within the Default Microtenant, pass microtenant_id as `0` when making requests to retrieve data from the Default Microtenant. Pass microtenant_id as null to retrieve data from all customers associated with the tenant. + +⚠️ **WARNING:**: The attribute ``microtenant_id`` is optional and requires the microtenant license and feature flag enabled for the respective tenant. The provider also supports the microtenant ID configuration via the environment variable `ZPA_MICROTENANT_ID` which is the recommended method. ### Optional @@ -130,7 +133,7 @@ In addition to all arguments above, the following attributes are exported: - `use_in_dr_mode` - (Boolean) Whether or not the application resource is designated for disaster recovery. Supported values: `true`, `false` - `is_incomplete_dr_config` - (Boolean) Indicates whether or not the disaster recovery configuration is incomplete. Supported values: `true`, `false` -- `microtenant_id` (Boolean) The unique identifier of the Microtenant for the ZPA tenant. If you are within the Default Microtenant, pass microtenantId as `0` when making requests to retrieve data from the Default Microtenant. Pass microtenantId as null to retrieve data from all customers associated with the tenant. +- `microtenant_id` (Boolean) The unique identifier of the Microtenant for the ZPA tenant. If you are within the Default Microtenant, pass microtenant_id as `0` when making requests to retrieve data from the Default Microtenant. Pass microtenant_id as null to retrieve data from all customers associated with the tenant. ⚠️ **WARNING:**: The attribute ``microtenant_id`` is optional and requires the microtenant license and feature flag enabled for the respective tenant. The provider also supports the microtenant ID configuration via the environment variable `ZPA_MICROTENANT_ID` which is the recommended method. diff --git a/docs/resources/zpa_policy_access_rule.md b/docs/resources/zpa_policy_access_rule.md index ad8380ce..ddc9f52b 100644 --- a/docs/resources/zpa_policy_access_rule.md +++ b/docs/resources/zpa_policy_access_rule.md @@ -138,3 +138,4 @@ terraform import zpa_policy_access_rule.example | [POSTURE](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/data-sources/zpa_posture_profile) | ``posture_udid`` | ``"true"`` / ``"false"`` | | [TRUSTED_NETWORK](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/data-sources/zpa_trusted_network) | ``network_id`` | ``"true"`` | | [COUNTRY_CODE](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/data-sources/zpa_access_policy_platforms) | [2 Letter ISO3166 Alpha2](https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes) | ``"true"`` / ``"false"`` | +| [RISK_FACTOR_TYPE](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/resources/zpa_policy_access_rule) | ``ZIA`` | ``"UNKNOWN", "LOW", "MEDIUM", "HIGH", "CRITICAL"`` | diff --git a/docs/resources/zpa_policy_access_rule_application_segment.md b/docs/resources/zpa_policy_access_rule_application_segment.md index 1bb324b2..610f244d 100644 --- a/docs/resources/zpa_policy_access_rule_application_segment.md +++ b/docs/resources/zpa_policy_access_rule_application_segment.md @@ -146,3 +146,4 @@ terraform import zpa_policy_access_rule.example | [POSTURE](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/data-sources/zpa_posture_profile) | ``posture_udid`` | ``"true"`` / ``"false"`` | | [TRUSTED_NETWORK](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/data-sources/zpa_trusted_network) | ``network_id`` | ``"true"`` | | [COUNTRY_CODE](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/data-sources/zpa_access_policy_platforms) | [2 Letter ISO3166 Alpha2](https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes) | ``"true"`` / ``"false"`` | +| [RISK_FACTOR_TYPE](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/resources/zpa_policy_access_rule) | ``ZIA`` | ``"UNKNOWN", "LOW", "MEDIUM", "HIGH", "CRITICAL"`` | \ No newline at end of file diff --git a/docs/resources/zpa_policy_access_rule_browser_access.md b/docs/resources/zpa_policy_access_rule_browser_access.md index 2eab4637..aa882f61 100644 --- a/docs/resources/zpa_policy_access_rule_browser_access.md +++ b/docs/resources/zpa_policy_access_rule_browser_access.md @@ -161,3 +161,4 @@ terraform import zpa_policy_access_rule.example | [POSTURE](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/data-sources/zpa_posture_profile) | ``posture_udid`` | ``"true"`` / ``"false"`` | | [TRUSTED_NETWORK](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/data-sources/zpa_trusted_network) | ``network_id`` | ``"true"`` | | [COUNTRY_CODE](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/data-sources/zpa_access_policy_platforms) | [2 Letter ISO3166 Alpha2](https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes) | ``"true"`` / ``"false"`` | +| [RISK_FACTOR_TYPE](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/resources/zpa_policy_access_rule) | ``ZIA`` | ``"UNKNOWN", "LOW", "MEDIUM", "HIGH", "CRITICAL"`` | \ No newline at end of file diff --git a/docs/resources/zpa_policy_access_rule_posture_profile.md b/docs/resources/zpa_policy_access_rule_posture_profile.md index 5253ec21..ffd61cc4 100644 --- a/docs/resources/zpa_policy_access_rule_posture_profile.md +++ b/docs/resources/zpa_policy_access_rule_posture_profile.md @@ -115,3 +115,4 @@ terraform import zpa_policy_access_rule.example | [POSTURE](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/data-sources/zpa_posture_profile) | ``posture_udid`` | ``"true"`` / ``"false"`` | | [TRUSTED_NETWORK](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/data-sources/zpa_trusted_network) | ``network_id`` | ``"true"`` | | [COUNTRY_CODE](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/data-sources/zpa_access_policy_platforms) | [2 Letter ISO3166 Alpha2](https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes) | ``"true"`` / ``"false"`` | +| [RISK_FACTOR_TYPE](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/resources/zpa_policy_access_rule) | ``ZIA`` | ``"UNKNOWN", "LOW", "MEDIUM", "HIGH", "CRITICAL"`` | \ No newline at end of file diff --git a/docs/resources/zpa_policy_access_rule_risk_factor.md b/docs/resources/zpa_policy_access_rule_risk_factor.md new file mode 100644 index 00000000..e403ac5a --- /dev/null +++ b/docs/resources/zpa_policy_access_rule_risk_factor.md @@ -0,0 +1,135 @@ +--- +page_title: "zpa_policy_access_rule Resource - terraform-provider-zpa" +subcategory: "Policy Set Controller" +description: |- + Official documentation https://help.zscaler.com/zpa/about-access-policy + API documentation https://help.zscaler.com/zpa/configuring-access-policies-using-api + Creates and manages ZPA Policy Access Rule with Risk Factor conditions. +--- + +# zpa_policy_access_rule (Resource) + +* [Official documentation](https://help.zscaler.com/zpa/about-access-policy) +* [API documentation](https://help.zscaler.com/zpa/configuring-access-policies-using-api) + +The **zpa_policy_access_rule** resource creates and manages a policy access rule with Risk Factor conditions in the Zscaler Private Access cloud. + + ⚠️ **WARNING:**: The attribute ``rule_order`` is now deprecated in favor of the new resource [``policy_access_rule_reorder``](zpa_policy_access_rule_reorder.md) + +## Example Usage + +```terraform + +resource "zpa_policy_access_rule" "access_policy_allow_machinetunnel" { + action = "ALLOW" + name = "Example_Risk_Score_Test" + description = "Example_Risk_Score_Test" + operator = "AND" + + conditions { + operator = "OR" + operands { + lhs = "ZIA" + object_type = "RISK_FACTOR_TYPE" + rhs = "UNKNOWN" + } + operands { + lhs = "ZIA" + object_type = "RISK_FACTOR_TYPE" + rhs = "LOW" + } + operands { + lhs = "ZIA" + object_type = "RISK_FACTOR_TYPE" + rhs = "MEDIUM" + } + operands { + lhs = "ZIA" + object_type = "RISK_FACTOR_TYPE" + rhs = "HIGH" + } + operands { + lhs = "ZIA" + object_type = "RISK_FACTOR_TYPE" + rhs = "CRITICAL" + } + } +} +``` + +## Schema + +### Required + +- `name` (String) This is the name of the policy rule. + +### Optional + +* `policy_set_id` - (String) Use [zpa_policy_type](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/data-sources/zpa_policy_type) data source to retrieve the necessary policy Set ID ``policy_set_id`` + ~> **NOTE** As of v3.2.0 the ``policy_set_id`` attribute is now optional, and will be automatically determined based on the policy type being configured. The attribute is being kept for backwards compatibility, but can be safely removed from existing configurations.`zpa_policy_type` [PR #432](/~https://github.com/zscaler/terraform-provider-zpa/pull/432) +- `action` (String) This is for providing the rule action. Supported values: ``ALLOW``, ``DENY`` +- `custom_msg` (String) This is for providing a customer message for the user. +- `description` (String) This is the description of the access policy rule. +- `operator` (String) Supported values: ``AND``, ``OR`` +- `policy_type` (String) Supported values: ``ACCESS_POLICY`` or ``GLOBAL_POLICY`` +- `rule_order` (String, Deprecated) + + ⚠️ **WARNING:**: The attribute ``rule_order`` is now deprecated in favor of the new resource [``policy_access_rule_reorder``](zpa_policy_access_rule_reorder.md) + +- `microtenant_id` (String) The ID of the microtenant the resource is to be associated with. + +⚠️ **WARNING:**: The attribute ``microtenant_id`` is optional and requires the microtenant license and feature flag enabled for the respective tenant. The provider also supports the microtenant ID configuration via the environment variable `ZPA_MICROTENANT_ID` which is the recommended method. + +- `conditions` (Block Set) + - `operator` (String) Supported values: ``AND``, and ``OR`` + - `microtenant_id` (String) The ID of the microtenant the resource is to be associated with. + + ⚠️ **WARNING:**: The attribute ``microtenant_id`` is optional and requires the microtenant license and feature flag enabled for the respective tenant. The provider also supports the microtenant ID configuration via the environment variable `ZPA_MICROTENANT_ID` which is the recommended method. + + - `operands` (Block Set) - Operands block must be repeated if multiple per `object_type` conditions are to be added to the rule. + - `object_type` (String) This is for specifying the policy critiera. For posture profile the supported value is: `POSTURE` + - `name` (String) + - `lhs` (String) - Posture Profile (posture_udid) required when ``object_type = "POSTURE"``. Use [zpa_posture_profile](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/data-sources/zpa_posture_profile) data source to retrieve the ``posture_udid`` + - `rhs` (String) Required when ``object_type = "POSTURE"``. Supported values are: + - ``true`` = ``VERIFIED`` + - ``false`` = ``VERIFICATION FAILED`` + + ⚠️ **WARNING:**: The attribute ``microtenant_id`` is not supported within the `operands` block when the `object_type` is set to `POSTURE`. ZPA automatically assumes the posture profile ID that belongs to the parent tenant. + +- `app_connector_groups` (Block Set) + * `id` (String) The ID of an app connector group resource + +- `app_server_groups` (Block Set) + * `id` (String) The ID of a server group resource + +## Import + +Zscaler offers a dedicated tool called Zscaler-Terraformer to allow the automated import of ZPA configurations into Terraform-compliant HashiCorp Configuration Language. +[Visit](/~https://github.com/zscaler/zscaler-terraformer) + +Policy Access Rule for Browser Access can be imported by using`` as the import ID. + +For example: + +```shell +terraform import zpa_policy_access_rule.example +``` + +## LHS and RHS Values + +| Object Type | LHS| RHS +|----------|-----------|---------- +| [APP](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/resources/zpa_application_segment) | ``"id"`` | ``application_segment_id`` | +| [APP_GROUP](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/resources/zpa_segment_group) | ``"id"`` | ``segment_group_id``| +| [CLIENT_TYPE](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/data-sources/zpa_access_policy_client_types) | ``"id"`` | ``zpn_client_type_zappl``, ``zpn_client_type_exporter``, ``zpn_client_type_browser_isolation``, ``zpn_client_type_ip_anchoring``, ``zpn_client_type_edge_connector``, ``zpn_client_type_branch_connector``, ``zpn_client_type_zapp_partner``, ``zpn_client_type_zapp`` | +| [EDGE_CONNECTOR_GROUP](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/data-sources/zpa_cloud_connector_group) | ``"id"`` | ```` | +| [IDP](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/data-sources/zpa_idp_controller) | ``"id"`` | ``identity_provider_id`` | +| [SAML](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/data-sources/zpa_saml_attribute) | ``saml_attribute_id`` | ``attribute_value_to_match`` | +| [SCIM](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/data-sources/zpa_scim_attribute_header) | ``scim_attribute_id`` | ``attribute_value_to_match`` | +| [SCIM_GROUP](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/data-sources/zpa_scim_groups) | ``scim_group_attribute_id`` | ``attribute_value_to_match`` | +| [PLATFORM](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/resources/zpa_policy_access_rule) | ``mac``, ``ios``, ``windows``, ``android``, ``linux`` | ``"true"`` / ``"false"`` | +| [MACHINE_GRP](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/data-sources/zpa_machine_group) | ``"id"`` | ``machine_group_id`` | +| [POSTURE](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/data-sources/zpa_posture_profile) | ``posture_udid`` | ``"true"`` / ``"false"`` | +| [TRUSTED_NETWORK](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/data-sources/zpa_trusted_network) | ``network_id`` | ``"true"`` | +| [COUNTRY_CODE](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/data-sources/zpa_access_policy_platforms) | [2 Letter ISO3166 Alpha2](https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes) | ``"true"`` / ``"false"`` | +| [RISK_FACTOR_TYPE](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/resources/zpa_policy_access_rule) | ``ZIA`` | ``"UNKNOWN", "LOW", "MEDIUM", "HIGH", "CRITICAL"`` | \ No newline at end of file diff --git a/docs/resources/zpa_policy_access_rule_saml.md b/docs/resources/zpa_policy_access_rule_saml.md index ca9b5b17..98ea2462 100644 --- a/docs/resources/zpa_policy_access_rule_saml.md +++ b/docs/resources/zpa_policy_access_rule_saml.md @@ -118,3 +118,4 @@ terraform import zpa_policy_access_rule.example | [POSTURE](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/data-sources/zpa_posture_profile) | ``posture_udid`` | ``"true"`` / ``"false"`` | | [TRUSTED_NETWORK](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/data-sources/zpa_trusted_network) | ``network_id`` | ``"true"`` | | [COUNTRY_CODE](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/data-sources/zpa_access_policy_platforms) | [2 Letter ISO3166 Alpha2](https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes) | ``"true"`` / ``"false"`` | +| [RISK_FACTOR_TYPE](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/resources/zpa_policy_access_rule) | ``ZIA`` | ``"UNKNOWN", "LOW", "MEDIUM", "HIGH", "CRITICAL"`` | \ No newline at end of file diff --git a/docs/resources/zpa_policy_access_rule_scim_attribute.md b/docs/resources/zpa_policy_access_rule_scim_attribute.md index 6dc30cd2..ae22016e 100644 --- a/docs/resources/zpa_policy_access_rule_scim_attribute.md +++ b/docs/resources/zpa_policy_access_rule_scim_attribute.md @@ -127,3 +127,4 @@ terraform import zpa_policy_access_rule.example | [POSTURE](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/data-sources/zpa_posture_profile) | ``posture_udid`` | ``"true"`` / ``"false"`` | | [TRUSTED_NETWORK](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/data-sources/zpa_trusted_network) | ``network_id`` | ``"true"`` | | [COUNTRY_CODE](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/data-sources/zpa_access_policy_platforms) | [2 Letter ISO3166 Alpha2](https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes) | ``"true"`` / ``"false"`` | +| [RISK_FACTOR_TYPE](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/resources/zpa_policy_access_rule) | ``ZIA`` | ``"UNKNOWN", "LOW", "MEDIUM", "HIGH", "CRITICAL"`` | \ No newline at end of file diff --git a/docs/resources/zpa_policy_access_rule_scim_group.md b/docs/resources/zpa_policy_access_rule_scim_group.md index 3ee65e3d..cede91d6 100644 --- a/docs/resources/zpa_policy_access_rule_scim_group.md +++ b/docs/resources/zpa_policy_access_rule_scim_group.md @@ -119,3 +119,4 @@ terraform import zpa_policy_access_rule.example | [POSTURE](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/data-sources/zpa_posture_profile) | ``posture_udid`` | ``"true"`` / ``"false"`` | | [TRUSTED_NETWORK](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/data-sources/zpa_trusted_network) | ``network_id`` | ``"true"`` | | [COUNTRY_CODE](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/data-sources/zpa_access_policy_platforms) | [2 Letter ISO3166 Alpha2](https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes) | ``"true"`` / ``"false"`` | +| [RISK_FACTOR_TYPE](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/resources/zpa_policy_access_rule) | ``ZIA`` | ``"UNKNOWN", "LOW", "MEDIUM", "HIGH", "CRITICAL"`` | \ No newline at end of file diff --git a/docs/resources/zpa_policy_access_rule_trusted_networks.md b/docs/resources/zpa_policy_access_rule_trusted_networks.md index f8ac9602..fa116990 100644 --- a/docs/resources/zpa_policy_access_rule_trusted_networks.md +++ b/docs/resources/zpa_policy_access_rule_trusted_networks.md @@ -102,7 +102,7 @@ terraform import zpa_policy_access_rule.example | [APP](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/resources/zpa_application_segment) | ``"id"`` | ``application_segment_id`` | | [APP_GROUP](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/resources/zpa_segment_group) | ``"id"`` | ``segment_group_id``| | [CLIENT_TYPE](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/data-sources/zpa_access_policy_client_types) | ``"id"`` | ``zpn_client_type_zappl``, ``zpn_client_type_exporter``, ``zpn_client_type_browser_isolation``, ``zpn_client_type_ip_anchoring``, ``zpn_client_type_edge_connector``, ``zpn_client_type_branch_connector``, ``zpn_client_type_zapp_partner``, ``zpn_client_type_zapp`` | -| [EDGE_CONNECTOR_GROUP](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/data-sources/zpa_cloud_connector_group) | ``"id"`` | ``edge_connector_id`` | +| [EDGE_CONNECTOR_GROUP](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/data-sources/zpa_cloud_connector_group) | ``"id"`` | ```` | | [IDP](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/data-sources/zpa_idp_controller) | ``"id"`` | ``identity_provider_id`` | | [SAML](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/data-sources/zpa_saml_attribute) | ``saml_attribute_id`` | ``attribute_value_to_match`` | | [SCIM](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/data-sources/zpa_scim_attribute_header) | ``scim_attribute_id`` | ``attribute_value_to_match`` | @@ -112,3 +112,4 @@ terraform import zpa_policy_access_rule.example | [POSTURE](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/data-sources/zpa_posture_profile) | ``posture_udid`` | ``"true"`` / ``"false"`` | | [TRUSTED_NETWORK](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/data-sources/zpa_trusted_network) | ``network_id`` | ``"true"`` | | [COUNTRY_CODE](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/data-sources/zpa_access_policy_platforms) | [2 Letter ISO3166 Alpha2](https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes) | ``"true"`` / ``"false"`` | +| [RISK_FACTOR_TYPE](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/resources/zpa_policy_access_rule) | ``ZIA`` | ``"UNKNOWN", "LOW", "MEDIUM", "HIGH", "CRITICAL"`` | \ No newline at end of file diff --git a/docs/resources/zpa_policy_access_rule_v2.md b/docs/resources/zpa_policy_access_rule_v2.md index c69a1f37..772cc009 100644 --- a/docs/resources/zpa_policy_access_rule_v2.md +++ b/docs/resources/zpa_policy_access_rule_v2.md @@ -126,6 +126,32 @@ resource "zpa_policy_access_rule_v2" "this" { } } } + conditions { + operator = "OR" + operands { + object_type = "RISK_FACTOR_TYPE" + entry_values { + lhs = "ZIA" + rhs = "UNKNOWN" + } + entry_values { + lhs = "ZIA" + rhs = "LOW" + } + entry_values { + lhs = "ZIA" + rhs = "MEDIUM" + } + entry_values { + lhs = "ZIA" + rhs = "HIGH" + } + entry_values { + lhs = "ZIA" + rhs = "CRITICAL" + } + } + } ``` ## Schema @@ -229,3 +255,4 @@ terraform import zpa_policy_access_rule_v2.example | [POSTURE](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/data-sources/zpa_posture_profile) | ``posture_udid`` | ``"true"`` / ``"false"`` | | [TRUSTED_NETWORK](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/data-sources/zpa_trusted_network) | ``network_id`` | ``"true"`` | | [COUNTRY_CODE](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/data-sources/zpa_access_policy_platforms) | [2 Letter ISO3166 Alpha2](https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes) | ``"true"`` / ``"false"`` | +| [RISK_FACTOR_TYPE](https://registry.terraform.io/providers/zscaler/zpa/latest/docs/resources/zpa_policy_access_rule) | ``ZIA`` | ``"UNKNOWN", "LOW", "MEDIUM", "HIGH", "CRITICAL"`` | \ No newline at end of file diff --git a/go.mod b/go.mod index 4360d94e..eaeb515f 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,7 @@ require ( github.com/hashicorp/terraform-plugin-docs v0.19.4 github.com/hashicorp/terraform-plugin-sdk v1.17.2 github.com/hashicorp/terraform-plugin-sdk/v2 v2.34.0 - github.com/zscaler/zscaler-sdk-go/v2 v2.72.3 + github.com/zscaler/zscaler-sdk-go/v2 v2.72.4 ) require ( diff --git a/go.sum b/go.sum index 5fe9ad4d..83770597 100644 --- a/go.sum +++ b/go.sum @@ -441,8 +441,8 @@ github.com/zclconf/go-cty v1.14.4/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgr github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b h1:FosyBZYxY34Wul7O/MSKey3txpPYyCqVO5ZyceuQJEI= github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8= github.com/zclconf/go-cty-yaml v1.0.2/go.mod h1:IP3Ylp0wQpYm50IHK8OZWKMu6sPJIUgKa8XhiVHura0= -github.com/zscaler/zscaler-sdk-go/v2 v2.72.3 h1:tkevJxm0QjZMuw2OQJBG12P5/xjQIbhcgLPo+6JOrtA= -github.com/zscaler/zscaler-sdk-go/v2 v2.72.3/go.mod h1:DW8JW8Cv2uxsfdlPN/Szk+CX9/nPyjhk/aERtTbJVYo= +github.com/zscaler/zscaler-sdk-go/v2 v2.72.4 h1:GMCmD87QiazaWxoJANTvfeGdmuCxbyaN2OQxBz09Me0= +github.com/zscaler/zscaler-sdk-go/v2 v2.72.4/go.mod h1:DW8JW8Cv2uxsfdlPN/Szk+CX9/nPyjhk/aERtTbJVYo= go.abhg.dev/goldmark/frontmatter v0.2.0 h1:P8kPG0YkL12+aYk2yU3xHv4tcXzeVnN+gU0tJ5JnxRw= go.abhg.dev/goldmark/frontmatter v0.2.0/go.mod h1:XqrEkZuM57djk7zrlRUB02x8I5J0px76YjkOzhB4YlU= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= diff --git a/zpa/common.go b/zpa/common.go index 682dbb3f..7e64c384 100644 --- a/zpa/common.go +++ b/zpa/common.go @@ -12,6 +12,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" + "github.com/zscaler/zscaler-sdk-go/v2/zpa/services/appconnectorgroup" "github.com/zscaler/zscaler-sdk-go/v2/zpa/services/applicationsegment" "github.com/zscaler/zscaler-sdk-go/v2/zpa/services/cloudconnectorgroup" "github.com/zscaler/zscaler-sdk-go/v2/zpa/services/common" @@ -24,6 +25,8 @@ import ( "github.com/zscaler/zscaler-sdk-go/v2/zpa/services/samlattribute" "github.com/zscaler/zscaler-sdk-go/v2/zpa/services/scimattributeheader" "github.com/zscaler/zscaler-sdk-go/v2/zpa/services/segmentgroup" + "github.com/zscaler/zscaler-sdk-go/v2/zpa/services/servergroup" + "github.com/zscaler/zscaler-sdk-go/v2/zpa/services/serviceedgegroup" "github.com/zscaler/zscaler-sdk-go/v2/zpa/services/trustednetwork" ) @@ -196,6 +199,17 @@ func validateOperand(operand policysetcontroller.Operands, zClient *Client, micr return lhsWarn(operand.ObjectType, "valid ISO-3166 Alpha-2 country code. Please visit the following site for reference: https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes", operand.LHS, nil) } return nil + case "RISK_FACTOR_TYPE": + // Check if lhs is "ZIA" + if operand.LHS != "ZIA" { + return lhsWarn(operand.ObjectType, "\"ZIA\"", operand.LHS, nil) + } + // Validate rhs for RISK_FACTOR_TYPE + validRHSValues := []string{"UNKNOWN", "LOW", "MEDIUM", "HIGH", "CRITICAL"} + if !contains(validRHSValues, operand.RHS) { + return rhsWarn(operand.ObjectType, "\"UNKNOWN\", \"LOW\", \"MEDIUM\", \"HIGH\", \"CRITICAL\"", operand.RHS, nil) + } + return nil default: return fmt.Errorf("[WARN] invalid operand object type %s", operand.ObjectType) } @@ -552,31 +566,9 @@ func flattenNetworkPorts(ports []common.NetworkPorts) []interface{} { return portsObj } -/* -func expandNetwokPorts(d *schema.ResourceData, key string) []common.NetworkPorts { - var ports []common.NetworkPorts - if portsInterface, ok := d.GetOk(key); ok { - portSet, ok := portsInterface.(*schema.Set) - if !ok { - log.Printf("[ERROR] conversion failed, destUdpPortsInterface") - return ports - } - ports = make([]common.NetworkPorts, len(portSet.List())) - for i, val := range portSet.List() { - portItem := val.(map[string]interface{}) - ports[i] = common.NetworkPorts{ - From: portItem["from"].(string), - To: portItem["to"].(string), - } - } - } - return ports -} -*/ - func resourceAppSegmentPortRange(desc string) *schema.Schema { return &schema.Schema{ - Type: schema.TypeSet, + Type: schema.TypeList, Optional: true, Computed: true, // Activate the "Attributes as Blocks" processing mode to permit dynamic declaration of no ports @@ -1014,6 +1006,8 @@ func ValidatePolicyRuleConditions(d *schema.ResourceData) error { validPlatformTypes := []string{"mac", "linux", "ios", "windows", "android"} + validRiskScore := []string{"UNKNOWN", "LOW", "MEDIUM", "HIGH", "CRITICAL"} + // Adjust to handle *schema.Set instead of []interface{} conditionsSet := conditions.(*schema.Set) for _, condition := range conditionsSet.List() { @@ -1080,6 +1074,27 @@ func ValidatePolicyRuleConditions(d *schema.ResourceData) error { return fmt.Errorf("rhs value must be 'true' for PLATFORM object_type") } } + case "RISK_FACTOR_TYPE": + entryValuesSet, ok := operandMap["entry_values"].(*schema.Set) + if !ok || entryValuesSet.Len() == 0 { + return fmt.Errorf("please provide valid risk factor values: %v", validRiskScore) + } + for _, ev := range entryValuesSet.List() { + evMap := ev.(map[string]interface{}) + lhs, lhsOk := evMap["lhs"].(string) + rhs, rhsOk := evMap["rhs"].(string) + + // Ensure lhs is "ZIA" + if !lhsOk || lhs != "ZIA" { + return fmt.Errorf("LHS must be 'ZIA' for RISK_FACTOR_TYPE") + } + + // Ensure rhs is one of the valid risk scores + validRHSValues := []string{"UNKNOWN", "LOW", "MEDIUM", "HIGH", "CRITICAL"} + if !rhsOk || !contains(validRHSValues, rhs) { + return fmt.Errorf("RHS must be one of 'UNKNOWN', 'LOW', 'MEDIUM', 'HIGH', 'CRITICAL' for RISK_FACTOR_TYPE") + } + } case "POSTURE": entryValuesSet, ok := operandMap["entry_values"].(*schema.Set) if !ok || entryValuesSet.Len() == 0 { @@ -1247,7 +1262,7 @@ func ConvertV1ResponseToV2Request(v1Response policysetcontrollerv2.PolicyRuleRes switch operand.ObjectType { case "APP", "APP_GROUP", "CONSOLE", "MACHINE_GRP", "LOCATION", "BRANCH_CONNECTOR_GROUP", "EDGE_CONNECTOR_GROUP", "CLIENT_TYPE": operandMap[operand.ObjectType] = append(operandMap[operand.ObjectType], operand.RHS) - case "PLATFORM", "POSTURE", "TRUSTED_NETWORK", "SAML", "SCIM", "SCIM_GROUP", "COUNTRY_CODE": + case "PLATFORM", "POSTURE", "TRUSTED_NETWORK", "SAML", "SCIM", "SCIM_GROUP", "COUNTRY_CODE", "RISK_FACTOR_TYPE": entryValuesMap[operand.ObjectType] = append(entryValuesMap[operand.ObjectType], policysetcontrollerv2.OperandsResourceLHSRHSValue{ LHS: operand.LHS, RHS: operand.RHS, @@ -1415,3 +1430,126 @@ func flattenPredefinedControls(predControl []common.CustomCommonControls) []inte } return predControls } + +func expandCommonServerGroups(d *schema.ResourceData) []servergroup.ServerGroup { + serverGroupInterface, ok := d.GetOk("server_groups") + if ok { + serverGroupSet, ok := serverGroupInterface.(*schema.Set) + if !ok { + return []servergroup.ServerGroup{} + } + log.Printf("[INFO] server group data: %+v\n", serverGroupSet) + var serverGroups []servergroup.ServerGroup + for _, serverGroup := range serverGroupSet.List() { + serverGroupMap, ok := serverGroup.(map[string]interface{}) + if ok && serverGroupMap != nil { + idSet, ok := serverGroupMap["id"].(*schema.Set) + if !ok { + continue + } + for _, id := range idSet.List() { + serverGroups = append(serverGroups, servergroup.ServerGroup{ + ID: id.(string), + }) + } + } + } + return serverGroups + } + + return []servergroup.ServerGroup{} +} + +func expandCommonAppConnectorGroups(d *schema.ResourceData) []appconnectorgroup.AppConnectorGroup { + appConnectorGroupInterface, ok := d.GetOk("app_connector_groups") + if ok { + appConnectorGroupSet, ok := appConnectorGroupInterface.(*schema.Set) + if !ok { + return []appconnectorgroup.AppConnectorGroup{} + } + log.Printf("[INFO] app connector group data: %+v\n", appConnectorGroupSet) + var appConnectorGroups []appconnectorgroup.AppConnectorGroup + for _, appConnectorGroup := range appConnectorGroupSet.List() { + appConnectorGroupMap, ok := appConnectorGroup.(map[string]interface{}) + if ok && appConnectorGroupMap != nil { + idSet, ok := appConnectorGroupMap["id"].(*schema.Set) + if !ok { + continue + } + for _, id := range idSet.List() { + appConnectorGroups = append(appConnectorGroups, appconnectorgroup.AppConnectorGroup{ + ID: id.(string), + }) + } + } + } + return appConnectorGroups + } + + return []appconnectorgroup.AppConnectorGroup{} +} + +func expandCommonServiceEdgeGroups(d *schema.ResourceData) []serviceedgegroup.ServiceEdgeGroup { + serviceEdgeGroupInterface, ok := d.GetOk("service_edge_groups") + if ok { + serviceEdgeGroupSet, ok := serviceEdgeGroupInterface.(*schema.Set) + if !ok { + return []serviceedgegroup.ServiceEdgeGroup{} + } + log.Printf("[INFO] service edge group data: %+v\n", serviceEdgeGroupSet) + var serviceEdgeGroups []serviceedgegroup.ServiceEdgeGroup + for _, serviceEdgeGroup := range serviceEdgeGroupSet.List() { + serviceEdgeGroupMap, ok := serviceEdgeGroup.(map[string]interface{}) + if ok && serviceEdgeGroupMap != nil { + idSet, ok := serviceEdgeGroupMap["id"].(*schema.Set) + if !ok { + continue + } + for _, id := range idSet.List() { + serviceEdgeGroups = append(serviceEdgeGroups, serviceedgegroup.ServiceEdgeGroup{ + ID: id.(string), + }) + } + } + } + return serviceEdgeGroups + } + + return []serviceedgegroup.ServiceEdgeGroup{} +} + +func flattenCommonAppConnectorGroups(appConnectorGroups []appconnectorgroup.AppConnectorGroup) []interface{} { + result := make([]interface{}, 1) + mapIds := make(map[string]interface{}) + ids := make([]string, len(appConnectorGroups)) + for i, appConnectorGroup := range appConnectorGroups { + ids[i] = appConnectorGroup.ID + } + mapIds["id"] = ids + result[0] = mapIds + return result +} + +func flattenCommonAppServerGroups(serverGroups []servergroup.ServerGroup) []interface{} { + result := make([]interface{}, 1) + mapIds := make(map[string]interface{}) + ids := make([]string, len(serverGroups)) + for i, serverGroup := range serverGroups { + ids[i] = serverGroup.ID + } + mapIds["id"] = ids + result[0] = mapIds + return result +} + +func flattenCommonServiceEdgeGroups(serviceEdgeGroups []serviceedgegroup.ServiceEdgeGroup) []interface{} { + result := make([]interface{}, 1) + mapIds := make(map[string]interface{}) + ids := make([]string, len(serviceEdgeGroups)) + for i, serviceEdgeGroup := range serviceEdgeGroups { + ids[i] = serviceEdgeGroup.ID + } + mapIds["id"] = ids + result[0] = mapIds + return result +} diff --git a/zpa/data_source_zpa_app_connector_controller.go b/zpa/data_source_zpa_app_connector_controller.go index 22e913ab..5bc73639 100644 --- a/zpa/data_source_zpa_app_connector_controller.go +++ b/zpa/data_source_zpa_app_connector_controller.go @@ -104,7 +104,7 @@ func dataSourceAppConnectorController() *schema.Resource { Type: schema.TypeString, Computed: true, }, - "modifiedby": { + "modified_by": { Type: schema.TypeString, Computed: true, }, @@ -128,6 +128,10 @@ func dataSourceAppConnectorController() *schema.Resource { Type: schema.TypeString, Computed: true, }, + "platform_detail": { + Type: schema.TypeString, + Computed: true, + }, "previous_version": { Type: schema.TypeString, Computed: true, @@ -140,6 +144,10 @@ func dataSourceAppConnectorController() *schema.Resource { Type: schema.TypeString, Computed: true, }, + "runtime_os": { + Type: schema.TypeString, + Computed: true, + }, "sarge_version": { Type: schema.TypeString, Computed: true, @@ -165,6 +173,190 @@ func dataSourceAppConnectorController() *schema.Resource { Type: schema.TypeString, Optional: true, }, + "assistant_version": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + }, + "application_start_time": { + Type: schema.TypeString, + Computed: true, + }, + "app_connector_group_id": { + Type: schema.TypeString, + Computed: true, + }, + "broker_id": { + Type: schema.TypeString, + Computed: true, + }, + "creation_time": { + Type: schema.TypeString, + Computed: true, + }, + "ctrl_channel_status": { + Type: schema.TypeString, + Computed: true, + }, + "current_version": { + Type: schema.TypeString, + Computed: true, + }, + "disable_auto_update": { + Type: schema.TypeBool, + Computed: true, + }, + "expected_version": { + Type: schema.TypeString, + Computed: true, + }, + "last_broker_connect_time": { + Type: schema.TypeString, + Computed: true, + }, + "last_broker_disconnect_time": { + Type: schema.TypeString, + Computed: true, + }, + "last_upgraded_time": { + Type: schema.TypeString, + Computed: true, + }, + "lone_warrior": { + Type: schema.TypeBool, + Computed: true, + }, + "latitude": { + Type: schema.TypeString, + Computed: true, + }, + "longitude": { + Type: schema.TypeString, + Computed: true, + }, + "modified_by": { + Type: schema.TypeString, + Computed: true, + }, + "modified_time": { + Type: schema.TypeString, + Computed: true, + }, + "platform": { + Type: schema.TypeString, + Computed: true, + }, + "platform_detail": { + Type: schema.TypeString, + Computed: true, + }, + "previous_version": { + Type: schema.TypeString, + Computed: true, + }, + "private_ip": { + Type: schema.TypeString, + Computed: true, + }, + "public_ip": { + Type: schema.TypeString, + Computed: true, + }, + "restart_time_in_sec": { + Type: schema.TypeString, + Computed: true, + }, + "runtime_os": { + Type: schema.TypeString, + Computed: true, + }, + "sarge_version": { + Type: schema.TypeString, + Computed: true, + }, + "system_start_time": { + Type: schema.TypeString, + Computed: true, + }, + "mtunnel_id": { + Type: schema.TypeString, + Computed: true, + }, + "upgrade_attempt": { + Type: schema.TypeString, + Computed: true, + }, + "upgrade_status": { + Type: schema.TypeString, + Computed: true, + }, + "upgrade_now_once": { + Type: schema.TypeBool, + Computed: true, + }, + }, + }, + }, + "zpn_sub_module_upgrade_list": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Computed: true, + }, + "creation_time": { + Type: schema.TypeString, + Computed: true, + }, + "current_version": { + Type: schema.TypeString, + Computed: true, + }, + "entity_gid": { + Type: schema.TypeString, + Computed: true, + }, + "entity_type": { + Type: schema.TypeString, + Computed: true, + }, + "expected_version": { + Type: schema.TypeString, + Computed: true, + }, + "modified_by": { + Type: schema.TypeString, + Computed: true, + }, + "modified_time": { + Type: schema.TypeString, + Computed: true, + }, + "previous_version": { + Type: schema.TypeString, + Computed: true, + }, + "role": { + Type: schema.TypeString, + Computed: true, + }, + "upgrade_status": { + Type: schema.TypeString, + Computed: true, + }, + "upgrade_time": { + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, }, } } @@ -199,6 +391,10 @@ func dataSourceAppConnectorControllerRead(d *schema.ResourceData, meta interface } if resp != nil { d.SetId(resp.ID) + _ = d.Set("id", resp.ID) + _ = d.Set("name", resp.Name) + _ = d.Set("description", resp.Description) + _ = d.Set("enabled", resp.Enabled) _ = d.Set("application_start_time", resp.ApplicationStartTime) _ = d.Set("app_connector_group_id", resp.AppConnectorGroupID) _ = d.Set("app_connector_group_name", resp.AppConnectorGroupName) @@ -206,8 +402,6 @@ func dataSourceAppConnectorControllerRead(d *schema.ResourceData, meta interface _ = d.Set("creation_time", resp.CreationTime) _ = d.Set("ctrl_broker_name", resp.CtrlBrokerName) _ = d.Set("current_version", resp.CurrentVersion) - _ = d.Set("description", resp.Description) - _ = d.Set("enabled", resp.Enabled) _ = d.Set("expected_upgrade_time", resp.ExpectedUpgradeTime) _ = d.Set("expected_version", resp.ExpectedVersion) _ = d.Set("fingerprint", resp.Fingerprint) @@ -221,15 +415,16 @@ func dataSourceAppConnectorControllerRead(d *schema.ResourceData, meta interface _ = d.Set("latitude", resp.Latitude) _ = d.Set("location", resp.Location) _ = d.Set("longitude", resp.Longitude) - _ = d.Set("modifiedby", resp.ModifiedBy) + _ = d.Set("modified_by", resp.ModifiedBy) _ = d.Set("modified_time", resp.ModifiedTime) - _ = d.Set("name", resp.Name) _ = d.Set("provisioning_key_id", resp.ProvisioningKeyID) _ = d.Set("provisioning_key_name", resp.ProvisioningKeyName) _ = d.Set("platform", resp.Platform) + _ = d.Set("platform_detail", resp.PlatformDetail) _ = d.Set("previous_version", resp.PreviousVersion) _ = d.Set("private_ip", resp.PrivateIP) _ = d.Set("public_ip", resp.PublicIP) + _ = d.Set("runtime_os", resp.RuntimeOS) _ = d.Set("sarge_version", resp.SargeVersion) _ = d.Set("enrollment_cert", resp.EnrollmentCert) _ = d.Set("upgrade_attempt", resp.UpgradeAttempt) @@ -237,9 +432,58 @@ func dataSourceAppConnectorControllerRead(d *schema.ResourceData, meta interface _ = d.Set("microtenant_id", resp.MicroTenantID) _ = d.Set("microtenant_name", resp.MicroTenantName) + if err := d.Set("zpn_sub_module_upgrade_list", flattenZPNSubModuleUpgrade(resp.ZPNSubModuleUpgrade)); err != nil { + return fmt.Errorf("failed to read app server groups %s", err) + } + + if err := d.Set("assistant_version", flattenAssistantVersion(&resp.AssistantVersion)); err != nil { + return fmt.Errorf("failed to read app server groups %s", err) + } } else { return fmt.Errorf("couldn't find any app connector with name '%s' or id '%s'", name, id) } return nil } + +func flattenAssistantVersion(assistantVersion *appconnectorcontroller.AssistantVersion) []interface{} { + if assistantVersion == nil { + return []interface{}{} + } + + result := make(map[string]interface{}) + + // Flattening the basic fields of PrivateBrokerVersion + result["id"] = assistantVersion.ID + result["application_start_time"] = assistantVersion.ApplicationStartTime + result["app_connector_group_id"] = assistantVersion.AppConnectorGroupID + result["broker_id"] = assistantVersion.BrokerId + result["creation_time"] = assistantVersion.CreationTime + result["ctrl_channel_status"] = assistantVersion.CtrlChannelStatus + result["current_version"] = assistantVersion.CurrentVersion + result["disable_auto_update"] = assistantVersion.DisableAutoUpdate + result["expected_version"] = assistantVersion.ExpectedVersion + result["last_broker_connect_time"] = assistantVersion.LastBrokerConnectTime + result["last_broker_disconnect_time"] = assistantVersion.LastBrokerDisconnectTime + result["last_upgraded_time"] = assistantVersion.LastUpgradedTime + result["latitude"] = assistantVersion.Latitude + result["lone_warrior"] = assistantVersion.LoneWarrior + result["longitude"] = assistantVersion.Longitude + result["modified_by"] = assistantVersion.ModifiedBy + result["modified_time"] = assistantVersion.ModifiedTime + result["mtunnel_id"] = assistantVersion.MtunnelID + result["platform"] = assistantVersion.Platform + result["platform_detail"] = assistantVersion.PlatformDetail + result["previous_version"] = assistantVersion.PreviousVersion + result["private_ip"] = assistantVersion.PrivateIP + result["public_ip"] = assistantVersion.PublicIP + result["restart_time_in_sec"] = assistantVersion.RestartTimeInSec + result["runtime_os"] = assistantVersion.RuntimeOS + result["sarge_version"] = assistantVersion.SargeVersion + result["system_start_time"] = assistantVersion.SystemStartTime + result["upgrade_attempt"] = assistantVersion.UpgradeAttempt + result["upgrade_status"] = assistantVersion.UpgradeStatus + result["upgrade_now_once"] = assistantVersion.UpgradeNowOnce + + return []interface{}{result} +} diff --git a/zpa/data_source_zpa_app_connector_group.go b/zpa/data_source_zpa_app_connector_group.go index 0162ffe1..29b95eac 100644 --- a/zpa/data_source_zpa_app_connector_group.go +++ b/zpa/data_source_zpa_app_connector_group.go @@ -372,13 +372,15 @@ func dataSourceConnectorGroupRead(d *schema.ResourceData, meta interface{}) erro _ = d.Set("upgrade_time_in_secs", resp.UpgradeTimeInSecs) _ = d.Set("version_profile_id", resp.VersionProfileID) _ = d.Set("version_profile_name", resp.VersionProfileName) - _ = d.Set("connectors", flattenConnectors(resp)) _ = d.Set("microtenant_id", resp.MicroTenantID) _ = d.Set("microtenant_name", resp.MicroTenantName) + _ = d.Set("connectors", flattenConnectors(resp)) + if err := d.Set("server_groups", flattenServerGroups(resp)); err != nil { - return fmt.Errorf("failed to read server groups %s", err) + return fmt.Errorf("failed to read app server groups %s", err) } + } else { return fmt.Errorf("couldn't find any app connector group with name '%s' or id '%s'", name, id) } diff --git a/zpa/data_source_zpa_application_segment.go b/zpa/data_source_zpa_application_segment.go index f81d8489..053b654b 100644 --- a/zpa/data_source_zpa_application_segment.go +++ b/zpa/data_source_zpa_application_segment.go @@ -107,45 +107,17 @@ func dataSourceApplicationSegment() *schema.Resource { Computed: true, }, "server_groups": { - Type: schema.TypeList, - Computed: true, + Type: schema.TypeSet, + Computed: true, + Description: "List of the server group IDs.", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ - "config_space": { - Type: schema.TypeString, - Computed: true, - }, - "creation_time": { - Type: schema.TypeString, - Computed: true, - }, - "description": { - Type: schema.TypeString, - Computed: true, - }, - "enabled": { - Type: schema.TypeBool, - Computed: true, - }, "id": { - Type: schema.TypeString, - Computed: true, - }, - "dynamic_discovery": { - Type: schema.TypeBool, - Computed: true, - }, - "modifiedby": { - Type: schema.TypeString, - Computed: true, - }, - "modified_time": { - Type: schema.TypeString, - Computed: true, - }, - "name": { - Type: schema.TypeString, + Type: schema.TypeList, Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, }, }, }, @@ -226,13 +198,18 @@ func dataSourceApplicationSegmentRead(d *schema.ResourceData, meta interface{}) _ = d.Set("passive_health_enabled", resp.PassiveHealthEnabled) _ = d.Set("microtenant_id", resp.MicroTenantID) _ = d.Set("microtenant_name", resp.MicroTenantName) - _ = d.Set("tcp_port_ranges", convertPortsToListString(resp.TCPAppPortRange)) - _ = d.Set("udp_port_ranges", convertPortsToListString(resp.UDPAppPortRange)) - if err := d.Set("server_groups", flattenAppServerGroups(resp)); err != nil { + if err := d.Set("server_groups", flattenCommonAppServerGroups(resp.ServerGroups)); err != nil { return fmt.Errorf("failed to read app server groups %s", err) } + if err := d.Set("tcp_port_ranges", resp.TCPPortRanges); err != nil { + return err + } + if err := d.Set("udp_port_ranges", resp.UDPPortRanges); err != nil { + return err + } + if err := d.Set("tcp_port_range", flattenNetworkPorts(resp.TCPAppPortRange)); err != nil { return err } @@ -248,6 +225,7 @@ func dataSourceApplicationSegmentRead(d *schema.ResourceData, meta interface{}) return nil } +/* func flattenAppServerGroups(serverGroup *applicationsegment.ApplicationSegmentResource) []interface{} { serverGroups := make([]interface{}, len(serverGroup.ServerGroups)) for i, val := range serverGroup.ServerGroups { @@ -266,3 +244,4 @@ func flattenAppServerGroups(serverGroup *applicationsegment.ApplicationSegmentRe return serverGroups } +*/ diff --git a/zpa/data_source_zpa_application_segment_browser_access.go b/zpa/data_source_zpa_application_segment_browser_access.go index e7b5df13..e9d2237e 100644 --- a/zpa/data_source_zpa_application_segment_browser_access.go +++ b/zpa/data_source_zpa_application_segment_browser_access.go @@ -245,22 +245,27 @@ func dataSourceApplicationSegmentBrowserAccessRead(d *schema.ResourceData, meta _ = d.Set("is_cname_enabled", resp.IsCnameEnabled) _ = d.Set("ip_anchored", resp.IPAnchored) _ = d.Set("health_reporting", resp.HealthReporting) - _ = d.Set("tcp_port_ranges", resp.TCPPortRanges) - _ = d.Set("udp_port_ranges", resp.UDPPortRanges) if err := d.Set("clientless_apps", flattenBaClientlessApps(resp)); err != nil { return fmt.Errorf("failed to read clientless apps %s", err) } - if err := d.Set("server_groups", flattenClientlessAppServerGroups(resp.AppServerGroups)); err != nil { + if err := d.Set("server_groups", flattenCommonAppServerGroups(resp.AppServerGroups)); err != nil { return fmt.Errorf("failed to read app server groups %s", err) } + if err := d.Set("tcp_port_ranges", resp.TCPPortRanges); err != nil { + return err + } + if err := d.Set("udp_port_ranges", resp.UDPPortRanges); err != nil { + return err + } + if err := d.Set("tcp_port_range", flattenNetworkPorts(resp.TCPAppPortRange)); err != nil { return err } - if err := d.Set("tcp_port_range", flattenNetworkPorts(resp.UDPAppPortRange)); err != nil { + if err := d.Set("udp_port_range", flattenNetworkPorts(resp.UDPAppPortRange)); err != nil { return err } } else { diff --git a/zpa/data_source_zpa_application_segment_by_type_test.go b/zpa/data_source_zpa_application_segment_by_type_test.go index 9f0c13dc..ad1af300 100644 --- a/zpa/data_source_zpa_application_segment_by_type_test.go +++ b/zpa/data_source_zpa_application_segment_by_type_test.go @@ -1,5 +1,6 @@ package zpa +/* import ( "fmt" "testing" @@ -135,3 +136,4 @@ data "zpa_application_segment_by_type" "ba" { resourceNameSuffix, ) } +*/ diff --git a/zpa/data_source_zpa_application_segment_inspection.go b/zpa/data_source_zpa_application_segment_inspection.go index 0db68cb0..e5b650e0 100644 --- a/zpa/data_source_zpa_application_segment_inspection.go +++ b/zpa/data_source_zpa_application_segment_inspection.go @@ -225,22 +225,27 @@ func dataSourceApplicationSegmentInspectionRead(d *schema.ResourceData, meta int _ = d.Set("modified_time", resp.ModifiedTime) _ = d.Set("ip_anchored", resp.IPAnchored) _ = d.Set("health_reporting", resp.HealthReporting) - _ = d.Set("tcp_port_ranges", resp.TCPPortRanges) - _ = d.Set("udp_port_ranges", resp.UDPPortRanges) if err := d.Set("inspection_apps", flattenInspectionApps(resp.InspectionAppDto)); err != nil { return fmt.Errorf("failed to read inspection apps in application segment %s", err) } - if err := d.Set("server_groups", flattenInspectionAppServerGroups(resp.AppServerGroups)); err != nil { + if err := d.Set("server_groups", flattenCommonAppServerGroups(resp.AppServerGroups)); err != nil { return fmt.Errorf("failed to read server groups for inspection app %s", err) } + if err := d.Set("tcp_port_ranges", resp.TCPPortRanges); err != nil { + return err + } + if err := d.Set("udp_port_ranges", resp.UDPPortRanges); err != nil { + return err + } + if err := d.Set("tcp_port_range", flattenNetworkPorts(resp.TCPAppPortRange)); err != nil { return err } - if err := d.Set("tcp_port_range", flattenNetworkPorts(resp.UDPAppPortRange)); err != nil { + if err := d.Set("udp_port_range", flattenNetworkPorts(resp.UDPAppPortRange)); err != nil { return err } } else { @@ -250,6 +255,7 @@ func dataSourceApplicationSegmentInspectionRead(d *schema.ResourceData, meta int return nil } +/* func flattenInspectionAppServerGroups(appServerGroup []applicationsegmentinspection.AppServerGroups) []interface{} { result := make([]interface{}, 1) mapIds := make(map[string]interface{}) @@ -261,3 +267,4 @@ func flattenInspectionAppServerGroups(appServerGroup []applicationsegmentinspect result[0] = mapIds return result } +*/ diff --git a/zpa/data_source_zpa_application_segment_pra.go b/zpa/data_source_zpa_application_segment_pra.go index 0818fce4..8d2ea9f7 100644 --- a/zpa/data_source_zpa_application_segment_pra.go +++ b/zpa/data_source_zpa_application_segment_pra.go @@ -238,17 +238,23 @@ func dataSourceApplicationSegmentPRARead(d *schema.ResourceData, meta interface{ return fmt.Errorf("failed to read sra apps %s", err) } - if err := d.Set("server_groups", flattenSRAAppServerGroups(resp.ServerGroups)); err != nil { - return fmt.Errorf("failed to read app server groups %s", err) + _ = d.Set("server_groups", flattenCommonAppServerGroups(resp.ServerGroups)) + + if err := d.Set("tcp_port_ranges", resp.TCPPortRanges); err != nil { + return err + } + if err := d.Set("udp_port_ranges", resp.UDPPortRanges); err != nil { + return err } if err := d.Set("tcp_port_range", flattenNetworkPorts(resp.TCPAppPortRange)); err != nil { return err } - if err := d.Set("tcp_port_range", flattenNetworkPorts(resp.UDPAppPortRange)); err != nil { + if err := d.Set("udp_port_range", flattenNetworkPorts(resp.UDPAppPortRange)); err != nil { return err } + } else { return fmt.Errorf("couldn't find any browser access application with name '%s' or id '%s'", name, id) } @@ -256,6 +262,7 @@ func dataSourceApplicationSegmentPRARead(d *schema.ResourceData, meta interface{ return nil } +/* func flattenSRAAppServerGroups(appServerGroup []applicationsegmentpra.AppServerGroups) []interface{} { result := make([]interface{}, 1) mapIds := make(map[string]interface{}) @@ -267,6 +274,7 @@ func flattenSRAAppServerGroups(appServerGroup []applicationsegmentpra.AppServerG result[0] = mapIds return result } +*/ func flattenSRAApps(sraApp *applicationsegmentpra.AppSegmentPRA) []interface{} { sraApps := make([]interface{}, len(sraApp.PRAApps)) diff --git a/zpa/data_source_zpa_server_group.go b/zpa/data_source_zpa_server_group.go index 83e96e37..ae48a572 100644 --- a/zpa/data_source_zpa_server_group.go +++ b/zpa/data_source_zpa_server_group.go @@ -5,6 +5,8 @@ import ( "log" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/zscaler/zscaler-sdk-go/v2/zpa/services/appconnectorgroup" + "github.com/zscaler/zscaler-sdk-go/v2/zpa/services/appservercontroller" "github.com/zscaler/zscaler-sdk-go/v2/zpa/services/servergroup" ) @@ -12,193 +14,21 @@ func dataSourceServerGroup() *schema.Resource { return &schema.Resource{ Read: dataSourceServerGroupRead, Schema: map[string]*schema.Schema{ - "applications": { - Type: schema.TypeList, + "id": { + Type: schema.TypeString, + Optional: true, + }, + "name": { + Type: schema.TypeString, + Optional: true, + }, + "description": { + Type: schema.TypeString, Computed: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "id": { - Type: schema.TypeString, - Computed: true, - }, - "name": { - Type: schema.TypeString, - Computed: true, - }, - }, - }, }, - "app_connector_groups": { - Type: schema.TypeList, + "enabled": { + Type: schema.TypeBool, Computed: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "city_country": { - Type: schema.TypeString, - Computed: true, - }, - "country_code": { - Type: schema.TypeString, - Computed: true, - }, - "creation_time": { - Type: schema.TypeString, - Computed: true, - }, - "description": { - Type: schema.TypeString, - Computed: true, - }, - "dns_query_type": { - Type: schema.TypeString, - Computed: true, - }, - "enabled": { - Type: schema.TypeBool, - Computed: true, - }, - "geolocation_id": { - Type: schema.TypeString, - Computed: true, - }, - "id": { - Type: schema.TypeString, - Computed: true, - }, - "latitude": { - Type: schema.TypeString, - Computed: true, - }, - "location": { - Type: schema.TypeString, - Computed: true, - }, - "longitude": { - Type: schema.TypeString, - Computed: true, - }, - "modifiedby": { - Type: schema.TypeString, - Computed: true, - }, - "modified_time": { - Type: schema.TypeString, - Computed: true, - }, - "name": { - Type: schema.TypeString, - Computed: true, - }, - "connectors": { - Type: schema.TypeList, - Computed: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "creation_time": { - Type: schema.TypeString, - Computed: true, - }, - "description": { - Type: schema.TypeString, - Computed: true, - }, - "enabled": { - Type: schema.TypeBool, - Computed: true, - }, - "fingerprint": { - Type: schema.TypeString, - Computed: true, - }, - "id": { - Type: schema.TypeString, - Computed: true, - }, - "issued_cert_id": { - Type: schema.TypeString, - Computed: true, - }, - "modifiedby": { - Type: schema.TypeString, - Computed: true, - }, - "modified_time": { - Type: schema.TypeString, - Computed: true, - }, - "name": { - Type: schema.TypeString, - Optional: true, - }, - "upgrade_attempt": { - Type: schema.TypeString, - Computed: true, - }, - }, - }, - }, - "server_groups": { - Type: schema.TypeList, - Computed: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "config_space": { - Type: schema.TypeString, - Computed: true, - }, - "creation_time": { - Type: schema.TypeString, - Computed: true, - }, - "description": { - Type: schema.TypeString, - Computed: true, - }, - "enabled": { - Type: schema.TypeBool, - Computed: true, - }, - "id": { - Type: schema.TypeString, - Computed: true, - }, - "dynamic_discovery": { - Type: schema.TypeBool, - Computed: true, - }, - "modifiedby": { - Type: schema.TypeString, - Computed: true, - }, - "modified_time": { - Type: schema.TypeString, - Computed: true, - }, - "name": { - Type: schema.TypeString, - Optional: true, - }, - }, - }, - }, - "siem_app_connector_group": { - Type: schema.TypeBool, - Computed: true, - }, - "upgrade_time_in_secs": { - Type: schema.TypeString, - Computed: true, - }, - "upgrade_day": { - Type: schema.TypeString, - Computed: true, - }, - "version_profile_id": { - Type: schema.TypeString, - Computed: true, - }, - }, - }, }, "microtenant_id": { Type: schema.TypeString, @@ -216,18 +46,6 @@ func dataSourceServerGroup() *schema.Resource { Type: schema.TypeString, Computed: true, }, - "description": { - Type: schema.TypeString, - Computed: true, - }, - "enabled": { - Type: schema.TypeBool, - Computed: true, - }, - "id": { - Type: schema.TypeString, - Optional: true, - }, "ip_anchored": { Type: schema.TypeBool, Computed: true, @@ -244,49 +62,44 @@ func dataSourceServerGroup() *schema.Resource { Type: schema.TypeString, Computed: true, }, - "name": { - Type: schema.TypeString, - Optional: true, - }, - "servers": { + "applications": { Type: schema.TypeList, Computed: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ - "address": { - Type: schema.TypeString, - Computed: true, - }, - "app_server_group_ids": { - Type: schema.TypeList, - Computed: true, - Elem: &schema.Schema{Type: schema.TypeString}, - }, - "config_space": { - Type: schema.TypeString, - Computed: true, - }, - "creation_time": { + "id": { Type: schema.TypeString, Computed: true, }, - "description": { + "name": { Type: schema.TypeString, Computed: true, }, - "enabled": { - Type: schema.TypeBool, - Computed: true, - }, + }, + }, + }, + "app_connector_groups": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ "id": { Type: schema.TypeString, Computed: true, }, - "modifiedby": { + "name": { Type: schema.TypeString, Computed: true, }, - "modified_time": { + }, + }, + }, + "servers": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "id": { Type: schema.TypeString, Computed: true, }, @@ -342,7 +155,7 @@ func dataSourceServerGroupRead(d *schema.ResourceData, meta interface{}) error { _ = d.Set("microtenant_id", resp.MicroTenantID) _ = d.Set("microtenant_name", resp.MicroTenantName) - if err := d.Set("applications", flattenServerGroupApplications(resp.Applications)); err != nil { + if err := d.Set("applications", flattenApplicationsSegments(resp.Applications)); err != nil { return err } @@ -360,7 +173,7 @@ func dataSourceServerGroupRead(d *schema.ResourceData, meta interface{}) error { return nil } -func flattenServerGroupApplications(applications []servergroup.Applications) []interface{} { +func flattenApplicationsSegments(applications []servergroup.Applications) []interface{} { serverGroupApplications := make([]interface{}, len(applications)) for i, srvApplication := range applications { serverGroupApplications[i] = map[string]interface{}{ @@ -372,86 +185,24 @@ func flattenServerGroupApplications(applications []servergroup.Applications) []i return serverGroupApplications } -func flattenAppConnectorGroups(appConnectorGroup []servergroup.AppConnectorGroups) []interface{} { +func flattenAppConnectorGroups(appConnectorGroup []appconnectorgroup.AppConnectorGroup) []interface{} { appConnectorGroups := make([]interface{}, len(appConnectorGroup)) for i, appConnectorGroup := range appConnectorGroup { appConnectorGroups[i] = map[string]interface{}{ - "city_country": appConnectorGroup.Citycountry, - "country_code": appConnectorGroup.CountryCode, - "creation_time": appConnectorGroup.CreationTime, - "description": appConnectorGroup.Description, - "dns_query_type": appConnectorGroup.DnsqueryType, - "enabled": appConnectorGroup.Enabled, - "geolocation_id": appConnectorGroup.GeolocationID, - "id": appConnectorGroup.ID, - "latitude": appConnectorGroup.Latitude, - "location": appConnectorGroup.Location, - "longitude": appConnectorGroup.Longitude, - "modifiedby": appConnectorGroup.ModifiedBy, - "modified_time": appConnectorGroup.ModifiedTime, - "name": appConnectorGroup.Name, - "siem_app_connector_group": appConnectorGroup.SiemAppconnectorGroup, - "upgrade_day": appConnectorGroup.UpgradeDay, - "upgrade_time_in_secs": appConnectorGroup.UpgradeTimeinSecs, - "version_profile_id": appConnectorGroup.VersionProfileID, - "server_groups": flattenAppConnectorServerGroups(appConnectorGroup), - "connectors": flattenAppConnectors(appConnectorGroup), + "id": appConnectorGroup.ID, + "name": appConnectorGroup.Name, } } return appConnectorGroups } -func flattenAppConnectorServerGroups(serverGroup servergroup.AppConnectorGroups) []interface{} { - serverGroups := make([]interface{}, len(serverGroup.AppServerGroups)) - for i, serverGroup := range serverGroup.AppServerGroups { - serverGroups[i] = map[string]interface{}{ - "config_space": serverGroup.ConfigSpace, - "creation_time": serverGroup.CreationTime, - "description": serverGroup.Description, - "enabled": serverGroup.Enabled, - "id": serverGroup.ID, - "dynamic_discovery": serverGroup.DynamicDiscovery, - "modifiedby": serverGroup.ModifiedBy, - "modified_time": serverGroup.ModifiedTime, - "name": serverGroup.Name, - } - } - - return serverGroups -} - -func flattenAppConnectors(connector servergroup.AppConnectorGroups) []interface{} { - appConnectors := make([]interface{}, len(connector.Connectors)) - for i, appConnector := range connector.Connectors { - appConnectors[i] = map[string]interface{}{ - "creation_time": appConnector.CreationTime, - "description": appConnector.Description, - "enabled": appConnector.Enabled, - "id": appConnector.ID, - "modifiedby": appConnector.ModifiedBy, - "modified_time": appConnector.ModifiedTime, - "name": appConnector.Name, - } - } - - return appConnectors -} - -func flattenServers(applicationServer []servergroup.ApplicationServer) []interface{} { +func flattenServers(applicationServer []appservercontroller.ApplicationServer) []interface{} { applicationServers := make([]interface{}, len(applicationServer)) for i, appServerItem := range applicationServer { applicationServers[i] = map[string]interface{}{ - "address": appServerItem.Address, - "app_server_group_ids": appServerItem.AppServerGroupIds, - "config_space": appServerItem.ConfigSpace, - "creation_time": appServerItem.CreationTime, - "description": appServerItem.Description, - "enabled": appServerItem.Enabled, - "id": appServerItem.ID, - "modifiedby": appServerItem.ModifiedBy, - "modified_time": appServerItem.ModifiedTime, - "name": appServerItem.Name, + "id": appServerItem.ID, + "name": appServerItem.Name, } } return applicationServers diff --git a/zpa/resource_zpa_app_connector_group.go b/zpa/resource_zpa_app_connector_group.go index e6c33709..c9127070 100644 --- a/zpa/resource_zpa_app_connector_group.go +++ b/zpa/resource_zpa_app_connector_group.go @@ -312,14 +312,14 @@ func detachAppConnectorGroupFromAllAccessPolicyRules(d *schema.ResourceData, pol return } for _, rule := range rules { - ids := []policysetcontroller.AppConnectorGroups{} + ids := []appconnectorgroup.AppConnectorGroup{} changed := false for _, app := range rule.AppConnectorGroups { if app.ID == d.Id() { changed = true continue } - ids = append(ids, policysetcontroller.AppConnectorGroups{ + ids = append(ids, appconnectorgroup.AppConnectorGroup{ ID: app.ID, }) } diff --git a/zpa/resource_zpa_application_segment.go b/zpa/resource_zpa_application_segment.go index 51475477..e0932030 100644 --- a/zpa/resource_zpa_application_segment.go +++ b/zpa/resource_zpa_application_segment.go @@ -1,7 +1,6 @@ package zpa import ( - "context" "fmt" "log" "strconv" @@ -24,29 +23,6 @@ func resourceApplicationSegment() *schema.Resource { Read: resourceApplicationSegmentRead, Update: resourceApplicationSegmentUpdate, Delete: resourceApplicationSegmentDelete, - CustomizeDiff: func(ctx context.Context, d *schema.ResourceDiff, meta interface{}) error { - if selectConnectorCloseToApp, ok := d.GetOk("select_connector_close_to_app"); ok && selectConnectorCloseToApp.(bool) { - udpAppPortRange := d.Get("udp_port_range").(*schema.Set).List() - udpPortRanges := d.Get("udp_port_ranges").([]interface{}) - - if len(udpAppPortRange) > 0 || len(udpPortRanges) > 0 { - return fmt.Errorf("the protocol configuration for the application is invalid. App Connector Closest to App supports only TCP applications") - } - } - - if bypassType, ok := d.GetOk("bypass_type"); ok && bypassType.(string) == "ALWAYS" { - tcpPortRange := d.Get("tcp_port_range").(*schema.Set).List() - tcpPortRanges := d.Get("tcp_port_ranges").(*schema.Set).List() - udpPortRange := d.Get("udp_port_range").(*schema.Set).List() - udpPortRanges := d.Get("udp_port_ranges").(*schema.Set).List() - - if len(tcpPortRange) > 0 || len(tcpPortRanges) > 0 || len(udpPortRange) > 0 || len(udpPortRanges) > 0 { - return fmt.Errorf("TCP and UDP port configuration must be disabled as bypass_type is set to ALWAYS. In order to add ports, please change the bypass_type to NEVER or ON_NET") - } - } - - return nil - }, Importer: &schema.ResourceImporter{ State: func(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { client := meta.(*Client) @@ -80,22 +56,6 @@ func resourceApplicationSegment() *schema.Resource { Type: schema.TypeString, Computed: true, }, - "name": { - Type: schema.TypeString, - Required: true, - Description: "Name of the application.", - ValidateFunc: validation.StringIsNotEmpty, - }, - "description": { - Type: schema.TypeString, - Optional: true, - Description: "Description of the application.", - }, - "enabled": { - Type: schema.TypeBool, - Optional: true, - Description: "Whether this application is enabled or not.", - }, "segment_group_id": { Type: schema.TypeString, Optional: true, @@ -124,16 +84,16 @@ func resourceApplicationSegment() *schema.Resource { }, "tcp_port_range": resourceAppSegmentPortRange("tcp port range"), "udp_port_range": resourceAppSegmentPortRange("udp port range"), + "tcp_port_ranges": { - Type: schema.TypeSet, + Type: schema.TypeList, Optional: true, Computed: true, Description: "TCP port ranges used to access the app.", Elem: &schema.Schema{Type: schema.TypeString}, }, - "udp_port_ranges": { - Type: schema.TypeSet, + Type: schema.TypeList, Optional: true, Computed: true, Description: "UDP port ranges used to access the app.", @@ -148,6 +108,11 @@ func resourceApplicationSegment() *schema.Resource { }, false), Default: "DEFAULT", }, + "description": { + Type: schema.TypeString, + Optional: true, + Description: "Description of the application.", + }, "domain_names": { Type: schema.TypeSet, Required: true, @@ -159,6 +124,11 @@ func resourceApplicationSegment() *schema.Resource { Optional: true, Description: "Whether Double Encryption is enabled or disabled for the app.", }, + "enabled": { + Type: schema.TypeBool, + Optional: true, + Description: "Whether this application is enabled or not.", + }, "health_check_type": { Type: schema.TypeString, Optional: true, @@ -205,6 +175,7 @@ func resourceApplicationSegment() *schema.Resource { "select_connector_close_to_app": { Type: schema.TypeBool, Optional: true, + ForceNew: true, }, "use_in_dr_mode": { Type: schema.TypeBool, @@ -220,6 +191,12 @@ func resourceApplicationSegment() *schema.Resource { Computed: true, Description: "Indicates if the Zscaler Client Connector (formerly Zscaler App or Z App) receives CNAME DNS records from the connectors.", }, + "name": { + Type: schema.TypeString, + Required: true, + Description: "Name of the application.", + ValidateFunc: validation.StringIsNotEmpty, + }, "passive_health_enabled": { Type: schema.TypeBool, Optional: true, @@ -236,7 +213,6 @@ func resourceApplicationSegment() *schema.Resource { "microtenant_id": { Type: schema.TypeString, Optional: true, - Computed: true, }, "server_groups": { Type: schema.TypeSet, @@ -270,9 +246,9 @@ func resourceApplicationSegmentCreate(d *schema.ResourceData, meta interface{}) req := expandApplicationSegmentRequest(d, zClient, "") - // if err := validateAppPorts(req.SelectConnectorCloseToApp, req.UDPAppPortRange, req.UDPPortRanges); err != nil { - // return err - // } + if err := validateAppPorts(req.SelectConnectorCloseToApp, req.UDPAppPortRange, req.UDPPortRanges); err != nil { + return err + } log.Printf("[INFO] Creating application segment request\n%+v\n", req) if req.SegmentGroupID == "" { @@ -313,16 +289,15 @@ func resourceApplicationSegmentRead(d *schema.ResourceData, meta interface{}) er log.Printf("[INFO] Reading application segment and settings states: %+v\n", resp) _ = d.Set("id", resp.ID) - _ = d.Set("name", resp.Name) - _ = d.Set("description", resp.Description) - _ = d.Set("enabled", resp.Enabled) _ = d.Set("segment_group_id", resp.SegmentGroupID) _ = d.Set("segment_group_name", resp.SegmentGroupName) - _ = d.Set("bypass_on_reauth", resp.BypassOnReauth) _ = d.Set("bypass_type", resp.BypassType) + _ = d.Set("bypass_on_reauth", resp.BypassOnReauth) _ = d.Set("config_space", resp.ConfigSpace) + _ = d.Set("description", resp.Description) _ = d.Set("domain_names", resp.DomainNames) _ = d.Set("double_encrypt", resp.DoubleEncrypt) + _ = d.Set("enabled", resp.Enabled) _ = d.Set("health_check_type", resp.HealthCheckType) _ = d.Set("health_reporting", resp.HealthReporting) _ = d.Set("icmp_access_type", resp.IcmpAccessType) @@ -334,11 +309,12 @@ func resourceApplicationSegmentRead(d *schema.ResourceData, meta interface{}) er _ = d.Set("is_incomplete_dr_config", resp.IsIncompleteDRConfig) _ = d.Set("is_cname_enabled", resp.IsCnameEnabled) _ = d.Set("tcp_keep_alive", resp.TCPKeepAlive) + _ = d.Set("name", resp.Name) _ = d.Set("passive_health_enabled", resp.PassiveHealthEnabled) _ = d.Set("ip_anchored", resp.IpAnchored) _ = d.Set("tcp_port_ranges", convertPortsToListString(resp.TCPAppPortRange)) _ = d.Set("udp_port_ranges", convertPortsToListString(resp.UDPAppPortRange)) - _ = d.Set("server_groups", flattenAppServerGroupsSimple(resp.ServerGroups)) + _ = d.Set("server_groups", flattenCommonAppServerGroups(resp.ServerGroups)) if err := d.Set("tcp_port_range", flattenNetworkPorts(resp.TCPAppPortRange)); err != nil { return err @@ -359,9 +335,9 @@ func resourceApplicationSegmentUpdate(d *schema.ResourceData, meta interface{}) log.Printf("[INFO] Updating application segment ID: %v\n", id) req := expandApplicationSegmentRequest(d, zClient, id) - // if err := validateAppPorts(req.SelectConnectorCloseToApp, req.UDPAppPortRange, req.UDPPortRanges); err != nil { - // return err - // } + if err := validateAppPorts(req.SelectConnectorCloseToApp, req.UDPAppPortRange, req.UDPPortRanges); err != nil { + return err + } if d.HasChange("segment_group_id") && req.SegmentGroupID == "" { log.Println("[ERROR] Please provide a valid segment group for the application segment") @@ -446,7 +422,6 @@ func resourceApplicationSegmentDelete(d *schema.ResourceData, meta interface{}) return nil } -/* func expandApplicationSegmentRequest(d *schema.ResourceData, client *Client, id string) applicationsegment.ApplicationSegmentResource { microTenantID := GetString(d.Get("microtenant_id")) service := client.ApplicationSegment @@ -469,6 +444,7 @@ func expandApplicationSegmentRequest(d *schema.ResourceData, client *Client, id MatchStyle: d.Get("match_style").(string), HealthReporting: d.Get("health_reporting").(string), TCPKeepAlive: d.Get("tcp_keep_alive").(string), + MicroTenantID: d.Get("microtenant_id").(string), PassiveHealthEnabled: d.Get("passive_health_enabled").(bool), DoubleEncrypt: d.Get("double_encrypt").(bool), Enabled: d.Get("enabled").(bool), @@ -478,7 +454,7 @@ func expandApplicationSegmentRequest(d *schema.ResourceData, client *Client, id UseInDrMode: d.Get("use_in_dr_mode").(bool), IsIncompleteDRConfig: d.Get("is_incomplete_dr_config").(bool), - ServerGroups: expandAppServerGroups(d), + ServerGroups: expandCommonServerGroups(d), TCPAppPortRange: []common.NetworkPorts{}, UDPAppPortRange: []common.NetworkPorts{}, } @@ -515,111 +491,3 @@ func expandApplicationSegmentRequest(d *schema.ResourceData, client *Client, id } return details } -*/ - -func expandApplicationSegmentRequest(d *schema.ResourceData, client *Client, id string) applicationsegment.ApplicationSegmentResource { - microTenantID := GetString(d.Get("microtenant_id")) - service := client.ApplicationSegment - if microTenantID != "" { - service = service.WithMicroTenant(microTenantID) - } - - details := applicationsegment.ApplicationSegmentResource{ - ID: d.Id(), - Name: d.Get("name").(string), - SegmentGroupID: d.Get("segment_group_id").(string), - SegmentGroupName: d.Get("segment_group_name").(string), - BypassType: d.Get("bypass_type").(string), - BypassOnReauth: d.Get("bypass_on_reauth").(bool), - ConfigSpace: d.Get("config_space").(string), - IcmpAccessType: d.Get("icmp_access_type").(string), - Description: d.Get("description").(string), - DomainNames: SetToStringList(d, "domain_names"), - HealthCheckType: d.Get("health_check_type").(string), - MatchStyle: d.Get("match_style").(string), - HealthReporting: d.Get("health_reporting").(string), - TCPKeepAlive: d.Get("tcp_keep_alive").(string), - PassiveHealthEnabled: d.Get("passive_health_enabled").(bool), - DoubleEncrypt: d.Get("double_encrypt").(bool), - Enabled: d.Get("enabled").(bool), - IpAnchored: d.Get("ip_anchored").(bool), - IsCnameEnabled: d.Get("is_cname_enabled").(bool), - SelectConnectorCloseToApp: d.Get("select_connector_close_to_app").(bool), - UseInDrMode: d.Get("use_in_dr_mode").(bool), - IsIncompleteDRConfig: d.Get("is_incomplete_dr_config").(bool), - - ServerGroups: expandAppServerGroups(d), - TCPAppPortRange: []common.NetworkPorts{}, - UDPAppPortRange: []common.NetworkPorts{}, - } - remoteTCPAppPortRanges := []string{} - remoteUDPAppPortRanges := []string{} - if service != nil && id != "" { - resource, _, err := applicationsegment.Get(service, id) - if err == nil { - remoteTCPAppPortRanges = resource.TCPPortRanges - remoteUDPAppPortRanges = resource.UDPPortRanges - } - } - - // Manually duplicate each entry in the list to represent "From" and "To" values - TCPAppPortRanges := duplicatePortRanges(d.Get("tcp_port_ranges").(*schema.Set).List()) - UDPAppPortRanges := duplicatePortRanges(d.Get("udp_port_ranges").(*schema.Set).List()) - - TCPAppPortRange := expandAppSegmentNetwokPorts(d, "tcp_port_range") - if isSameSlice(TCPAppPortRange, TCPAppPortRanges) || isSameSlice(TCPAppPortRange, remoteTCPAppPortRanges) { - details.TCPPortRanges = TCPAppPortRanges - } else { - details.TCPPortRanges = TCPAppPortRange - } - - UDPAppPortRange := expandAppSegmentNetwokPorts(d, "udp_port_range") - if isSameSlice(UDPAppPortRange, UDPAppPortRanges) || isSameSlice(UDPAppPortRange, remoteUDPAppPortRanges) { - details.UDPPortRanges = UDPAppPortRanges - } else { - details.UDPPortRanges = UDPAppPortRange - } - - if details.TCPPortRanges == nil { - details.TCPPortRanges = []string{} - } - if details.UDPPortRanges == nil { - details.UDPPortRanges = []string{} - } - - return details -} - -func expandAppServerGroups(d *schema.ResourceData) []applicationsegment.AppServerGroups { - serverGroupsInterface, ok := d.GetOk("server_groups") - if ok { - serverGroup := serverGroupsInterface.(*schema.Set) - log.Printf("[INFO] app server groups data: %+v\n", serverGroup) - var serverGroups []applicationsegment.AppServerGroups - for _, appServerGroup := range serverGroup.List() { - appServerGroup, _ := appServerGroup.(map[string]interface{}) - if ok { - for _, id := range appServerGroup["id"].(*schema.Set).List() { - serverGroups = append(serverGroups, applicationsegment.AppServerGroups{ - ID: id.(string), - }) - } - } - } - return serverGroups - } - - return []applicationsegment.AppServerGroups{} -} - -func flattenAppServerGroupsSimple(serverGroups []applicationsegment.AppServerGroups) []interface{} { - result := make([]interface{}, 1) - mapIds := make(map[string]interface{}) - ids := make([]string, len(serverGroups)) - for i, group := range serverGroups { - ids[i] = group.ID - } - mapIds["id"] = ids - result[0] = mapIds - return result -} diff --git a/zpa/resource_zpa_application_segment_browser_access.go b/zpa/resource_zpa_application_segment_browser_access.go index aadd5ef7..06f51f63 100644 --- a/zpa/resource_zpa_application_segment_browser_access.go +++ b/zpa/resource_zpa_application_segment_browser_access.go @@ -87,6 +87,7 @@ func resourceApplicationSegmentBrowserAccess() *schema.Resource { Description: "TCP port ranges used to access the app.", Elem: &schema.Schema{Type: schema.TypeString}, }, + "udp_port_ranges": { Type: schema.TypeList, Optional: true, @@ -357,17 +358,18 @@ func resourceApplicationSegmentBrowserAccessRead(d *schema.ResourceData, meta in _ = d.Set("is_cname_enabled", resp.IsCnameEnabled) _ = d.Set("icmp_access_type", resp.ICMPAccessType) _ = d.Set("health_reporting", resp.HealthReporting) - _ = d.Set("tcp_port_ranges", resp.TCPPortRanges) - _ = d.Set("udp_port_ranges", resp.UDPPortRanges) if err := d.Set("clientless_apps", flattenBaClientlessApps(resp)); err != nil { return fmt.Errorf("failed to read clientless apps %s", err) } - if err := d.Set("server_groups", flattenClientlessAppServerGroups(resp.AppServerGroups)); err != nil { + if err := d.Set("server_groups", flattenCommonAppServerGroups(resp.AppServerGroups)); err != nil { return fmt.Errorf("failed to read app server groups %s", err) } + _ = d.Set("tcp_port_ranges", convertPortsToListString(resp.TCPAppPortRange)) + _ = d.Set("udp_port_ranges", convertPortsToListString(resp.UDPAppPortRange)) + if err := d.Set("tcp_port_range", flattenNetworkPorts(resp.TCPAppPortRange)); err != nil { return err } @@ -417,24 +419,10 @@ func resourceApplicationSegmentBrowserAccessUpdate(d *schema.ResourceData, meta func resourceApplicationSegmentBrowserAccessDelete(d *schema.ResourceData, meta interface{}) error { zClient := meta.(*Client) - service := zClient.BrowserAccess - microTenantID := GetString(d.Get("microtenant_id")) - if microTenantID != "" { - service = service.WithMicroTenant(microTenantID) - } + service := zClient.BrowserAccess.WithMicroTenant(GetString(d.Get("microtenant_id"))) id := d.Id() - segmentGroupID, ok := d.GetOk("segment_group_id") - if ok && segmentGroupID != nil { - gID, ok := segmentGroupID.(string) - if ok && gID != "" { - // detach it from segment group first - if err := detachSegmentGroup(zClient, id, gID); err != nil { - return err - } - } - } log.Printf("[INFO] Deleting browser access application with id %v\n", id) if _, err := browseraccess.Delete(service, id); err != nil { return err @@ -444,6 +432,12 @@ func resourceApplicationSegmentBrowserAccessDelete(d *schema.ResourceData, meta } func expandBrowserAccess(d *schema.ResourceData, zClient *Client, id string) browseraccess.BrowserAccess { + microTenantID := GetString(d.Get("microtenant_id")) + service := zClient.BrowserAccess + if microTenantID != "" { + service = service.WithMicroTenant(microTenantID) + } + details := browseraccess.BrowserAccess{ ID: d.Id(), Name: d.Get("name").(string), @@ -466,19 +460,15 @@ func expandBrowserAccess(d *schema.ResourceData, zClient *Client, id string) bro SelectConnectorCloseToApp: d.Get("select_connector_close_to_app").(bool), UseInDrMode: d.Get("use_in_dr_mode").(bool), IsIncompleteDRConfig: d.Get("is_incomplete_dr_config").(bool), + AppServerGroups: expandCommonServerGroups(d), + ClientlessApps: expandClientlessApps(d), TCPAppPortRange: []common.NetworkPorts{}, UDPAppPortRange: []common.NetworkPorts{}, } remoteTCPAppPortRanges := []string{} remoteUDPAppPortRanges := []string{} - if zClient != nil && id != "" { - microTenantID := GetString(d.Get("microtenant_id")) - service := zClient.ApplicationSegment - if microTenantID != "" { - service = service.WithMicroTenant(microTenantID) - } - + if service != nil && id != "" { resource, _, err := applicationsegment.Get(service, id) if err == nil { remoteTCPAppPortRanges = resource.TCPPortRanges @@ -507,18 +497,15 @@ func expandBrowserAccess(d *schema.ResourceData, zClient *Client, id string) bro if details.UDPPortRanges == nil { details.UDPPortRanges = []string{} } + // Handle specific changes, to be sure we're updating the correct fields if d.HasChange("name") { details.Name = d.Get("name").(string) } - if d.HasChange("segment_group_name") { - details.SegmentGroupName = d.Get("segment_group_name").(string) - } - if d.HasChange("server_groups") { - details.AppServerGroups = expandClientlessAppServerGroups(d) - } + if d.HasChange("clientless_apps") { details.ClientlessApps = expandClientlessApps(d) } + return details } @@ -536,15 +523,12 @@ func expandClientlessApps(d *schema.ResourceData) []browseraccess.ClientlessApps ApplicationPort: clientlessApp["application_port"].(string), ApplicationProtocol: clientlessApp["application_protocol"].(string), CertificateID: clientlessApp["certificate_id"].(string), - // Cname: clientlessApp["cname"].(string), - Description: clientlessApp["description"].(string), - Domain: clientlessApp["domain"].(string), - Enabled: clientlessApp["enabled"].(bool), - // Hidden: clientlessApp["hidden"].(bool), - // LocalDomain: clientlessApp["local_domain"].(string), - Name: clientlessApp["name"].(string), - // Path: clientlessApp["path"].(string), - TrustUntrustedCert: clientlessApp["trust_untrusted_cert"].(bool), + Description: clientlessApp["description"].(string), + Domain: clientlessApp["domain"].(string), + Enabled: clientlessApp["enabled"].(bool), + Name: clientlessApp["name"].(string), + MicroTenantID: clientlessApp["microtenant_id"].(string), + TrustUntrustedCert: clientlessApp["trust_untrusted_cert"].(bool), }) } } @@ -554,28 +538,6 @@ func expandClientlessApps(d *schema.ResourceData) []browseraccess.ClientlessApps return []browseraccess.ClientlessApps{} } -func expandClientlessAppServerGroups(d *schema.ResourceData) []browseraccess.AppServerGroups { - serverGroupsInterface, ok := d.GetOk("server_groups") - if ok { - serverGroup := serverGroupsInterface.(*schema.Set) - log.Printf("[INFO] app server groups data: %+v\n", serverGroup) - var serverGroups []browseraccess.AppServerGroups - for _, appServerGroup := range serverGroup.List() { - appServerGroup, _ := appServerGroup.(map[string]interface{}) - if ok { - for _, id := range appServerGroup["id"].(*schema.Set).List() { - serverGroups = append(serverGroups, browseraccess.AppServerGroups{ - ID: id.(string), - }) - } - } - } - return serverGroups - } - - return []browseraccess.AppServerGroups{} -} - func flattenBaClientlessApps(clientlessApp *browseraccess.BrowserAccess) []interface{} { clientlessApps := make([]interface{}, len(clientlessApp.ClientlessApps)) for i, clientlessApp := range clientlessApp.ClientlessApps { @@ -596,15 +558,3 @@ func flattenBaClientlessApps(clientlessApp *browseraccess.BrowserAccess) []inter return clientlessApps } - -func flattenClientlessAppServerGroups(serverGroups []browseraccess.AppServerGroups) []interface{} { - result := make([]interface{}, 1) - mapIds := make(map[string]interface{}) - ids := make([]string, len(serverGroups)) - for i, serverGroup := range serverGroups { - ids[i] = serverGroup.ID - } - mapIds["id"] = ids - result[0] = mapIds - return result -} diff --git a/zpa/resource_zpa_application_segment_inspection.go b/zpa/resource_zpa_application_segment_inspection.go index 2b36d64a..e7823002 100644 --- a/zpa/resource_zpa_application_segment_inspection.go +++ b/zpa/resource_zpa_application_segment_inspection.go @@ -7,6 +7,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" client "github.com/zscaler/zscaler-sdk-go/v2/zpa" + "github.com/zscaler/zscaler-sdk-go/v2/zpa/services/applicationsegment" "github.com/zscaler/zscaler-sdk-go/v2/zpa/services/applicationsegmentinspection" "github.com/zscaler/zscaler-sdk-go/v2/zpa/services/common" ) @@ -54,14 +55,14 @@ func resourceApplicationSegmentInspection() *schema.Resource { "udp_port_range": resourceAppSegmentPortRange("udp port range"), "tcp_port_ranges": { - Type: schema.TypeSet, + Type: schema.TypeList, Optional: true, Computed: true, Description: "TCP port ranges used to access the app.", Elem: &schema.Schema{Type: schema.TypeString}, }, "udp_port_ranges": { - Type: schema.TypeSet, + Type: schema.TypeList, Optional: true, Computed: true, Description: "UDP port ranges used to access the app.", @@ -362,14 +363,15 @@ func resourceApplicationSegmentInspectionRead(d *schema.ResourceData, meta inter _ = d.Set("tcp_keep_alive", resp.TCPKeepAlive) _ = d.Set("ip_anchored", resp.IPAnchored) _ = d.Set("health_reporting", resp.HealthReporting) - _ = d.Set("tcp_port_ranges", convertPortsToListString(resp.TCPAppPortRange)) - _ = d.Set("udp_port_ranges", convertPortsToListString(resp.UDPAppPortRange)) - _ = d.Set("server_groups", flattenInspectionAppServerGroupsSimple(resp.AppServerGroups)) + _ = d.Set("server_groups", flattenCommonAppServerGroups(resp.AppServerGroups)) if err := d.Set("inspection_apps", flattenInspectionApps(resp.InspectionAppDto)); err != nil { return fmt.Errorf("failed to read inspection apps in application segment %s", err) } + _ = d.Set("tcp_port_ranges", convertPortsToListString(resp.TCPAppPortRange)) + _ = d.Set("udp_port_ranges", convertPortsToListString(resp.UDPAppPortRange)) + if err := d.Set("tcp_port_range", flattenNetworkPorts(resp.TCPAppPortRange)); err != nil { return err } @@ -384,9 +386,14 @@ func resourceApplicationSegmentInspectionUpdate(d *schema.ResourceData, meta int zClient := meta.(*Client) service := zClient.ApplicationSegmentInspection + microTenantID := GetString(d.Get("microtenant_id")) + if microTenantID != "" { + service = service.WithMicroTenant(microTenantID) + } + id := d.Id() log.Printf("[INFO] Updating inspection application segment ID: %v\n", id) - req := expandInspectionApplicationSegment(d, zClient, id) + req := expandInspectionApplicationSegment(d, zClient, "") if err := validateAppPorts(req.SelectConnectorCloseToApp, req.UDPAppPortRange, req.UDPPortRanges); err != nil { return err @@ -437,6 +444,12 @@ func resourceApplicationSegmentInspectionDelete(d *schema.ResourceData, meta int } func expandInspectionApplicationSegment(d *schema.ResourceData, zClient *Client, id string) applicationsegmentinspection.AppSegmentInspection { + microTenantID := GetString(d.Get("microtenant_id")) + service := zClient.ApplicationSegmentInspection + if microTenantID != "" { + service = service.WithMicroTenant(microTenantID) + } + details := applicationsegmentinspection.AppSegmentInspection{ ID: d.Id(), Name: d.Get("name").(string), @@ -458,34 +471,23 @@ func expandInspectionApplicationSegment(d *schema.ResourceData, zClient *Client, TCPKeepAlive: d.Get("tcp_keep_alive").(string), IsIncompleteDRConfig: d.Get("is_incomplete_dr_config").(bool), DomainNames: expandStringInSlice(d, "domain_names"), - TCPAppPortRange: []common.NetworkPorts{}, - UDPAppPortRange: []common.NetworkPorts{}, - AppServerGroups: expandInspectionAppServerGroups(d), + AppServerGroups: expandCommonServerGroups(d), CommonAppsDto: expandInspectionCommonAppsDto(d), - } - if d.HasChange("name") { - details.Name = d.Get("name").(string) - } - if d.HasChange("server_groups") { - details.AppServerGroups = expandInspectionAppServerGroups(d) + + TCPAppPortRange: []common.NetworkPorts{}, + UDPAppPortRange: []common.NetworkPorts{}, } remoteTCPAppPortRanges := []string{} remoteUDPAppPortRanges := []string{} - if zClient != nil && id != "" { - service := zClient.ApplicationSegmentInspection - - resource, _, err := applicationsegmentinspection.Get(service, id) + if service != nil && id != "" { + resource, _, err := applicationsegment.Get(service, id) if err == nil { remoteTCPAppPortRanges = resource.TCPPortRanges remoteUDPAppPortRanges = resource.UDPPortRanges } } - - // Manually duplicate each entry in the list to represent "From" and "To" values - TCPAppPortRanges := duplicatePortRanges(d.Get("tcp_port_ranges").(*schema.Set).List()) - UDPAppPortRanges := duplicatePortRanges(d.Get("udp_port_ranges").(*schema.Set).List()) - TCPAppPortRange := expandAppSegmentNetwokPorts(d, "tcp_port_range") + TCPAppPortRanges := convertToPortRange(d.Get("tcp_port_ranges").([]interface{})) if isSameSlice(TCPAppPortRange, TCPAppPortRanges) || isSameSlice(TCPAppPortRange, remoteTCPAppPortRanges) { details.TCPPortRanges = TCPAppPortRanges } else { @@ -493,6 +495,7 @@ func expandInspectionApplicationSegment(d *schema.ResourceData, zClient *Client, } UDPAppPortRange := expandAppSegmentNetwokPorts(d, "udp_port_range") + UDPAppPortRanges := convertToPortRange(d.Get("udp_port_ranges").([]interface{})) if isSameSlice(UDPAppPortRange, UDPAppPortRanges) || isSameSlice(UDPAppPortRange, remoteUDPAppPortRanges) { details.UDPPortRanges = UDPAppPortRanges } else { @@ -506,6 +509,13 @@ func expandInspectionApplicationSegment(d *schema.ResourceData, zClient *Client, details.UDPPortRanges = []string{} } + if d.HasChange("name") { + details.Name = d.Get("name").(string) + } + if d.HasChange("server_groups") { + details.AppServerGroups = expandCommonServerGroups(d) + } + return details } @@ -551,40 +561,6 @@ func expandInspectionAppsConfig(appsConfigInterface interface{}) []applicationse return commonAppConfigDto } -func expandInspectionAppServerGroups(d *schema.ResourceData) []applicationsegmentinspection.AppServerGroups { - serverGroupsInterface, ok := d.GetOk("server_groups") - if ok { - serverGroup := serverGroupsInterface.(*schema.Set) - log.Printf("[INFO] app server groups data: %+v\n", serverGroup) - var serverGroups []applicationsegmentinspection.AppServerGroups - for _, appServerGroup := range serverGroup.List() { - appServerGroup, _ := appServerGroup.(map[string]interface{}) - if ok { - for _, id := range appServerGroup["id"].(*schema.Set).List() { - serverGroups = append(serverGroups, applicationsegmentinspection.AppServerGroups{ - ID: id.(string), - }) - } - } - } - return serverGroups - } - - return []applicationsegmentinspection.AppServerGroups{} -} - -func flattenInspectionAppServerGroupsSimple(serverGroup []applicationsegmentinspection.AppServerGroups) []interface{} { - result := make([]interface{}, 1) - mapIds := make(map[string]interface{}) - ids := make([]string, len(serverGroup)) - for i, group := range serverGroup { - ids[i] = group.ID - } - mapIds["id"] = ids - result[0] = mapIds - return result -} - func flattenInspectionApps(apps []applicationsegmentinspection.InspectionAppDto) []interface{} { if len(apps) == 0 { return []interface{}{} diff --git a/zpa/resource_zpa_application_segment_inspection_test.go b/zpa/resource_zpa_application_segment_inspection_test.go index 395fdba3..0c218914 100644 --- a/zpa/resource_zpa_application_segment_inspection_test.go +++ b/zpa/resource_zpa_application_segment_inspection_test.go @@ -37,7 +37,7 @@ func TestAccResourceApplicationSegmentInspection_Basic(t *testing.T) { resource.TestCheckResourceAttr(appSegmentTypeAndName, "health_reporting", "ON_ACCESS"), resource.TestCheckResourceAttrSet(appSegmentTypeAndName, "segment_group_id"), resource.TestCheckResourceAttr(appSegmentTypeAndName, "common_apps_dto.#", "1"), - resource.TestCheckResourceAttr(appSegmentTypeAndName, "tcp_port_ranges.#", "1"), + resource.TestCheckResourceAttr(appSegmentTypeAndName, "tcp_port_ranges.#", "2"), ), }, @@ -54,7 +54,7 @@ func TestAccResourceApplicationSegmentInspection_Basic(t *testing.T) { resource.TestCheckResourceAttr(appSegmentTypeAndName, "health_reporting", "ON_ACCESS"), resource.TestCheckResourceAttrSet(appSegmentTypeAndName, "segment_group_id"), resource.TestCheckResourceAttr(appSegmentTypeAndName, "common_apps_dto.#", "1"), - resource.TestCheckResourceAttr(appSegmentTypeAndName, "tcp_port_ranges.#", "1"), + resource.TestCheckResourceAttr(appSegmentTypeAndName, "tcp_port_ranges.#", "2"), ), }, // Import test diff --git a/zpa/resource_zpa_application_segment_pra.go b/zpa/resource_zpa_application_segment_pra.go index 55d15ce8..4dc04b3b 100644 --- a/zpa/resource_zpa_application_segment_pra.go +++ b/zpa/resource_zpa_application_segment_pra.go @@ -13,6 +13,7 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" client "github.com/zscaler/zscaler-sdk-go/v2/zpa" + "github.com/zscaler/zscaler-sdk-go/v2/zpa/services/applicationsegment" "github.com/zscaler/zscaler-sdk-go/v2/zpa/services/applicationsegmentpra" "github.com/zscaler/zscaler-sdk-go/v2/zpa/services/common" ) @@ -65,14 +66,14 @@ func resourceApplicationSegmentPRA() *schema.Resource { "udp_port_range": resourceAppSegmentPortRange("udp port range"), "tcp_port_ranges": { - Type: schema.TypeSet, + Type: schema.TypeList, Optional: true, Computed: true, Description: "TCP port ranges used to access the app.", Elem: &schema.Schema{Type: schema.TypeString}, }, "udp_port_ranges": { - Type: schema.TypeSet, + Type: schema.TypeList, Optional: true, Computed: true, Description: "UDP port ranges used to access the app.", @@ -393,15 +394,15 @@ func resourceApplicationSegmentPRARead(d *schema.ResourceData, meta interface{}) _ = d.Set("tcp_keep_alive", resp.TCPKeepAlive) _ = d.Set("ip_anchored", resp.IpAnchored) _ = d.Set("health_reporting", resp.HealthReporting) - _ = d.Set("tcp_port_ranges", convertPortsToListString(resp.TCPAppPortRange)) - _ = d.Set("udp_port_ranges", convertPortsToListString(resp.UDPAppPortRange)) - _ = d.Set("server_groups", flattenPRAAppServerGroupsSimple(resp.ServerGroups)) + _ = d.Set("server_groups", flattenCommonAppServerGroups(resp.ServerGroups)) - //Use the new flatten function for praApps if err := d.Set("pra_apps", flattenPRAApps(resp.PRAApps)); err != nil { return fmt.Errorf("failed to read common application in application segment %s", err) } + _ = d.Set("tcp_port_ranges", convertPortsToListString(resp.TCPAppPortRange)) + _ = d.Set("udp_port_ranges", convertPortsToListString(resp.UDPAppPortRange)) + if err := d.Set("tcp_port_range", flattenNetworkPorts(resp.TCPAppPortRange)); err != nil { return err } @@ -409,19 +410,8 @@ func resourceApplicationSegmentPRARead(d *schema.ResourceData, meta interface{}) if err := d.Set("udp_port_range", flattenNetworkPorts(resp.UDPAppPortRange)); err != nil { return err } - return nil -} -func flattenPRAAppServerGroupsSimple(serverGroup []applicationsegmentpra.AppServerGroups) []interface{} { - result := make([]interface{}, 1) - mapIds := make(map[string]interface{}) - ids := make([]string, len(serverGroup)) - for i, group := range serverGroup { - ids[i] = group.ID - } - mapIds["id"] = ids - result[0] = mapIds - return result + return nil } func resourceApplicationSegmentPRAUpdate(d *schema.ResourceData, meta interface{}) error { @@ -435,7 +425,7 @@ func resourceApplicationSegmentPRAUpdate(d *schema.ResourceData, meta interface{ id := d.Id() log.Printf("[INFO] Updating pra application segment ID: %v\n", id) - req := expandSRAApplicationSegment(d, zClient, id) + req := expandSRAApplicationSegment(d, zClient, "") if err := checkForPRAPortsOverlap(zClient, req); err != nil { return err @@ -489,7 +479,7 @@ func resourceApplicationSegmentPRADelete(d *schema.ResourceData, meta interface{ func expandSRAApplicationSegment(d *schema.ResourceData, client *Client, id string) applicationsegmentpra.AppSegmentPRA { microTenantID := GetString(d.Get("microtenant_id")) - service := client.ApplicationSegmentPRA + service := client.ApplicationSegment if microTenantID != "" { service = service.WithMicroTenant(microTenantID) } @@ -515,34 +505,23 @@ func expandSRAApplicationSegment(d *schema.ResourceData, client *Client, id stri TCPKeepAlive: d.Get("tcp_keep_alive").(string), IsIncompleteDRConfig: d.Get("is_incomplete_dr_config").(bool), DomainNames: SetToStringList(d, "domain_names"), - TCPAppPortRange: []common.NetworkPorts{}, - UDPAppPortRange: []common.NetworkPorts{}, - ServerGroups: expandPRAAppServerGroups(d), + ServerGroups: expandCommonServerGroups(d), CommonAppsDto: expandCommonAppsDto(d), - } - if d.HasChange("name") { - details.Name = d.Get("name").(string) - } - if d.HasChange("server_groups") { - details.ServerGroups = expandPRAAppServerGroups(d) + TCPAppPortRange: []common.NetworkPorts{}, + UDPAppPortRange: []common.NetworkPorts{}, } - remoteTCPAppPortRanges := []string{} remoteUDPAppPortRanges := []string{} if service != nil && id != "" { - resource, _, err := applicationsegmentpra.Get(service, id) + resource, _, err := applicationsegment.Get(service, id) if err == nil { remoteTCPAppPortRanges = resource.TCPPortRanges remoteUDPAppPortRanges = resource.UDPPortRanges } } - - // Manually duplicate each entry in the list to represent "From" and "To" values - TCPAppPortRanges := duplicatePortRanges(d.Get("tcp_port_ranges").(*schema.Set).List()) - UDPAppPortRanges := duplicatePortRanges(d.Get("udp_port_ranges").(*schema.Set).List()) - TCPAppPortRange := expandAppSegmentNetwokPorts(d, "tcp_port_range") + TCPAppPortRanges := convertToPortRange(d.Get("tcp_port_ranges").([]interface{})) if isSameSlice(TCPAppPortRange, TCPAppPortRanges) || isSameSlice(TCPAppPortRange, remoteTCPAppPortRanges) { details.TCPPortRanges = TCPAppPortRanges } else { @@ -550,6 +529,7 @@ func expandSRAApplicationSegment(d *schema.ResourceData, client *Client, id stri } UDPAppPortRange := expandAppSegmentNetwokPorts(d, "udp_port_range") + UDPAppPortRanges := convertToPortRange(d.Get("udp_port_ranges").([]interface{})) if isSameSlice(UDPAppPortRange, UDPAppPortRanges) || isSameSlice(UDPAppPortRange, remoteUDPAppPortRanges) { details.UDPPortRanges = UDPAppPortRanges } else { @@ -562,6 +542,17 @@ func expandSRAApplicationSegment(d *schema.ResourceData, client *Client, id stri if details.UDPPortRanges == nil { details.UDPPortRanges = []string{} } + if d.HasChange("name") { + details.Name = d.Get("name").(string) + } + if d.HasChange("server_groups") { + details.ServerGroups = expandCommonServerGroups(d) + } + + // Apply microtenant context if available + if microTenantID != "" { + client.ApplicationSegment = client.ApplicationSegment.WithMicroTenant(microTenantID) + } return details } @@ -608,28 +599,6 @@ func expandAppsConfig(appsConfigInterface interface{}) []applicationsegmentpra.A return commonAppConfigDto } -func expandPRAAppServerGroups(d *schema.ResourceData) []applicationsegmentpra.AppServerGroups { - serverGroupsInterface, ok := d.GetOk("server_groups") - if ok { - serverGroup := serverGroupsInterface.(*schema.Set) - log.Printf("[INFO] app server groups data: %+v\n", serverGroup) - var serverGroups []applicationsegmentpra.AppServerGroups - for _, appServerGroup := range serverGroup.List() { - appServerGroup, _ := appServerGroup.(map[string]interface{}) - if ok { - for _, id := range appServerGroup["id"].(*schema.Set).List() { - serverGroups = append(serverGroups, applicationsegmentpra.AppServerGroups{ - ID: id.(string), - }) - } - } - } - return serverGroups - } - - return []applicationsegmentpra.AppServerGroups{} -} - func flattenPRAApps(apps []applicationsegmentpra.PRAApps) []interface{} { if len(apps) == 0 { return []interface{}{} @@ -737,3 +706,41 @@ func customizeDiffApplicationSegmentPRA(ctx context.Context, d *schema.ResourceD } return nil } + +/* +func expandPRAAppServerGroups(d *schema.ResourceData) []applicationsegmentpra.AppServerGroups { + serverGroupsInterface, ok := d.GetOk("server_groups") + if ok { + serverGroup := serverGroupsInterface.(*schema.Set) + log.Printf("[INFO] app server groups data: %+v\n", serverGroup) + var serverGroups []applicationsegmentpra.AppServerGroups + for _, appServerGroup := range serverGroup.List() { + appServerGroup, _ := appServerGroup.(map[string]interface{}) + if ok { + for _, id := range appServerGroup["id"].(*schema.Set).List() { + serverGroups = append(serverGroups, applicationsegmentpra.AppServerGroups{ + ID: id.(string), + }) + } + } + } + return serverGroups + } + + return []applicationsegmentpra.AppServerGroups{} +} +*/ + +/* +func flattenPRAAppServerGroupsSimple(serverGroup []applicationsegmentpra.AppServerGroups) []interface{} { + result := make([]interface{}, 1) + mapIds := make(map[string]interface{}) + ids := make([]string, len(serverGroup)) + for i, group := range serverGroup { + ids[i] = group.ID + } + mapIds["id"] = ids + result[0] = mapIds + return result +} +*/ diff --git a/zpa/resource_zpa_application_segment_pra_test.go b/zpa/resource_zpa_application_segment_pra_test.go index 99cfa85e..e46f1598 100644 --- a/zpa/resource_zpa_application_segment_pra_test.go +++ b/zpa/resource_zpa_application_segment_pra_test.go @@ -37,7 +37,7 @@ func TestAccResourceApplicationSegmentPRA_Basic(t *testing.T) { resource.TestCheckResourceAttr(appSegmentTypeAndName, "health_reporting", "ON_ACCESS"), resource.TestCheckResourceAttrSet(appSegmentTypeAndName, "segment_group_id"), resource.TestCheckResourceAttr(appSegmentTypeAndName, "common_apps_dto.#", "1"), - resource.TestCheckResourceAttr(appSegmentTypeAndName, "tcp_port_ranges.#", "2"), + resource.TestCheckResourceAttr(appSegmentTypeAndName, "tcp_port_ranges.#", "4"), ), }, @@ -54,7 +54,7 @@ func TestAccResourceApplicationSegmentPRA_Basic(t *testing.T) { resource.TestCheckResourceAttr(appSegmentTypeAndName, "health_reporting", "ON_ACCESS"), resource.TestCheckResourceAttrSet(appSegmentTypeAndName, "segment_group_id"), resource.TestCheckResourceAttr(appSegmentTypeAndName, "common_apps_dto.#", "1"), - resource.TestCheckResourceAttr(appSegmentTypeAndName, "tcp_port_ranges.#", "2"), + resource.TestCheckResourceAttr(appSegmentTypeAndName, "tcp_port_ranges.#", "4"), ), }, // Import test diff --git a/zpa/resource_zpa_application_segment_test.go b/zpa/resource_zpa_application_segment_test.go index 7bea59fb..bdc51342 100644 --- a/zpa/resource_zpa_application_segment_test.go +++ b/zpa/resource_zpa_application_segment_test.go @@ -40,8 +40,8 @@ func TestAccResourceApplicationSegment_Basic(t *testing.T) { resource.TestCheckResourceAttr(appSegmentTypeAndName, "bypass_type", "NEVER"), resource.TestCheckResourceAttr(appSegmentTypeAndName, "health_reporting", "ON_ACCESS"), resource.TestCheckResourceAttrSet(appSegmentTypeAndName, "segment_group_id"), - resource.TestCheckResourceAttr(appSegmentTypeAndName, "tcp_port_ranges.#", "1"), - resource.TestCheckResourceAttr(appSegmentTypeAndName, "udp_port_ranges.#", "1"), + resource.TestCheckResourceAttr(appSegmentTypeAndName, "tcp_port_range.#", "1"), + resource.TestCheckResourceAttr(appSegmentTypeAndName, "udp_port_range.#", "1"), ), }, @@ -57,8 +57,8 @@ func TestAccResourceApplicationSegment_Basic(t *testing.T) { resource.TestCheckResourceAttr(appSegmentTypeAndName, "bypass_type", "NEVER"), resource.TestCheckResourceAttr(appSegmentTypeAndName, "health_reporting", "ON_ACCESS"), resource.TestCheckResourceAttrSet(appSegmentTypeAndName, "segment_group_id"), - resource.TestCheckResourceAttr(appSegmentTypeAndName, "tcp_port_ranges.#", "1"), - resource.TestCheckResourceAttr(appSegmentTypeAndName, "udp_port_ranges.#", "1"), + resource.TestCheckResourceAttr(appSegmentTypeAndName, "tcp_port_range.#", "1"), + resource.TestCheckResourceAttr(appSegmentTypeAndName, "udp_port_range.#", "1"), ), }, // Import test @@ -144,8 +144,18 @@ resource "%s" "%s" { is_cname_enabled = "%s" health_reporting = "ON_ACCESS" bypass_type = "NEVER" - tcp_port_ranges = ["%d", "%d"] - udp_port_ranges = ["%d", "%d"] + tcp_port_range = [ + { + from = "%d" + to = "%d" + } + ] + udp_port_range = [ + { + from = "%d" + to = "%d" + } + ] domain_names = ["test.example.com"] segment_group_id = "${%s.id}" tcp_keep_alive = "1" diff --git a/zpa/resource_zpa_policy_access_redirection_rule.go b/zpa/resource_zpa_policy_access_redirection_rule.go index 2d60c8a3..e5dde385 100644 --- a/zpa/resource_zpa_policy_access_redirection_rule.go +++ b/zpa/resource_zpa_policy_access_redirection_rule.go @@ -132,7 +132,7 @@ func resourcePolicyRedictionRuleRead(d *schema.ResourceData, meta interface{}) e _ = d.Set("policy_set_id", resp.PolicySetID) _ = d.Set("policy_type", resp.PolicyType) _ = d.Set("conditions", flattenPolicyConditions(resp.Conditions)) - _ = d.Set("service_edge_groups", flattenPolicyRuleServiceEdgeGroups(resp.ServiceEdgeGroups)) + _ = d.Set("service_edge_groups", flattenCommonServiceEdgeGroups(resp.ServiceEdgeGroups)) return nil } @@ -211,10 +211,11 @@ func expandCreatePolicyRedirectionRule(d *schema.ResourceData) (*policysetcontro Priority: d.Get("priority").(string), MicroTenantID: GetString(d.Get("microtenant_id")), Conditions: conditions, - ServiceEdgeGroups: expandPolicysetControllerServiceEdgeGroups(d), + ServiceEdgeGroups: expandCommonServiceEdgeGroups(d), }, nil } +/* func expandPolicysetControllerServiceEdgeGroups(d *schema.ResourceData) []policysetcontroller.ServiceEdgeGroups { serviceEdgeGroupsInterface, ok := d.GetOk("service_edge_groups") if ok { @@ -248,3 +249,4 @@ func flattenPolicyRuleServiceEdgeGroups(serviceEdgeGroup []policysetcontroller.S result[0] = mapIds return result } +*/ diff --git a/zpa/resource_zpa_policy_access_redirection_rule_test.go b/zpa/resource_zpa_policy_access_redirection_rule_test.go index 04e7daa2..a401a0f9 100644 --- a/zpa/resource_zpa_policy_access_redirection_rule_test.go +++ b/zpa/resource_zpa_policy_access_redirection_rule_test.go @@ -114,7 +114,7 @@ func testAccCheckPolicyRedictionRuleExists(resource string) resource.TestCheckFu func testAccCheckPolicyRedictionRuleConfigure(resourceTypeAndName, rName, generatedName, desc, serviceEdgeGroupHCL, serviceEdgeGroupTypeAndName string) string { return fmt.Sprintf(` -// app connector group resource +// service edge group resource %s // redirection policy access rule resource diff --git a/zpa/resource_zpa_policy_access_rule.go b/zpa/resource_zpa_policy_access_rule.go index 267591bd..b43dbefd 100644 --- a/zpa/resource_zpa_policy_access_rule.go +++ b/zpa/resource_zpa_policy_access_rule.go @@ -81,6 +81,7 @@ func resourcePolicyAccessRule() *schema.Resource { "MACHINE_GRP", "COUNTRY_CODE", "PLATFORM", + "RISK_FACTOR_TYPE", }), }, ), @@ -169,8 +170,8 @@ func resourcePolicyAccessRead(d *schema.ResourceData, meta interface{}) error { _ = d.Set("lss_default_rule", resp.LSSDefaultRule) _ = d.Set("microtenant_id", microTenantID) _ = d.Set("conditions", flattenPolicyConditions(resp.Conditions)) - _ = d.Set("app_server_groups", flattenPolicyRuleServerGroups(resp.AppServerGroups)) - _ = d.Set("app_connector_groups", flattenPolicyRuleAppConnectorGroups(resp.AppConnectorGroups)) + _ = d.Set("app_server_groups", flattenCommonAppServerGroups(resp.AppServerGroups)) + _ = d.Set("app_connector_groups", flattenCommonAppConnectorGroups(resp.AppConnectorGroups)) return nil } @@ -244,7 +245,7 @@ func resourcePolicyAccessDelete(d *schema.ResourceData, meta interface{}) error } func expandCreatePolicyRule(d *schema.ResourceData, policySetID string) (*policysetcontroller.PolicyRule, error) { - log.Printf("[INFO] action_id:%v\n", d.Get("action_id")) + conditions, err := ExpandPolicyConditions(d) if err != nil { return nil, err @@ -265,11 +266,12 @@ func expandCreatePolicyRule(d *schema.ResourceData, policySetID string) (*policy MicroTenantID: d.Get("microtenant_id").(string), LSSDefaultRule: d.Get("lss_default_rule").(bool), Conditions: conditions, - AppServerGroups: expandPolicySetControllerAppServerGroups(d), - AppConnectorGroups: expandPolicysetControllerAppConnectorGroups(d), + AppServerGroups: expandCommonServerGroups(d), + AppConnectorGroups: expandCommonAppConnectorGroups(d), }, nil } +/* func expandPolicySetControllerAppServerGroups(d *schema.ResourceData) []policysetcontroller.AppServerGroups { appServerGroupsInterface, ok := d.GetOk("app_server_groups") if ok { @@ -314,7 +316,7 @@ func expandPolicysetControllerAppConnectorGroups(d *schema.ResourceData) []polic return []policysetcontroller.AppConnectorGroups{} } -func flattenPolicyRuleServerGroups(appServerGroup []policysetcontroller.AppServerGroups) []interface{} { +func flattenPolicyRuleServerGroups(appServerGroup []servergroup.AppServerGroups) []interface{} { result := make([]interface{}, 1) mapIds := make(map[string]interface{}) ids := make([]string, len(appServerGroup)) @@ -337,3 +339,4 @@ func flattenPolicyRuleAppConnectorGroups(appConnectorGroups []policysetcontrolle result[0] = mapIds return result } +*/ diff --git a/zpa/resource_zpa_policy_access_rule_test.go b/zpa/resource_zpa_policy_access_rule_test.go index 29fdb3c5..aa25ef1f 100644 --- a/zpa/resource_zpa_policy_access_rule_test.go +++ b/zpa/resource_zpa_policy_access_rule_test.go @@ -39,7 +39,7 @@ func TestAccResourcePolicyAccessRule_Basic(t *testing.T) { resource.TestCheckResourceAttr(resourceTypeAndName, "action", "ALLOW"), resource.TestCheckResourceAttr(resourceTypeAndName, "operator", "AND"), resource.TestCheckResourceAttr(resourceTypeAndName, "app_connector_groups.#", "1"), - resource.TestCheckResourceAttr(resourceTypeAndName, "conditions.#", "1"), + resource.TestCheckResourceAttr(resourceTypeAndName, "conditions.#", "2"), ), }, @@ -53,7 +53,7 @@ func TestAccResourcePolicyAccessRule_Basic(t *testing.T) { resource.TestCheckResourceAttr(resourceTypeAndName, "action", "ALLOW"), resource.TestCheckResourceAttr(resourceTypeAndName, "operator", "AND"), resource.TestCheckResourceAttr(resourceTypeAndName, "app_connector_groups.#", "1"), - resource.TestCheckResourceAttr(resourceTypeAndName, "conditions.#", "1"), + resource.TestCheckResourceAttr(resourceTypeAndName, "conditions.#", "2"), ), }, // Import test @@ -188,6 +188,34 @@ resource "%s" "%s" { idp_id = data.zpa_scim_attribute_header.familyName.idp_id } } + conditions { + operator = "OR" + operands { + object_type = "RISK_FACTOR_TYPE" + lhs = "ZIA" + rhs = "UNKNOWN" + } + operands { + object_type = "RISK_FACTOR_TYPE" + lhs = "ZIA" + rhs = "LOW" + } + operands { + object_type = "RISK_FACTOR_TYPE" + lhs = "ZIA" + rhs = "MEDIUM" + } + operands { + object_type = "RISK_FACTOR_TYPE" + lhs = "ZIA" + rhs = "HIGH" + } + operands { + object_type = "RISK_FACTOR_TYPE" + lhs = "ZIA" + rhs = "CRITICAL" + } + } depends_on = [ %s, %s ] } `, diff --git a/zpa/resource_zpa_policy_access_rule_v2.go b/zpa/resource_zpa_policy_access_rule_v2.go index b160ad69..dd545997 100755 --- a/zpa/resource_zpa_policy_access_rule_v2.go +++ b/zpa/resource_zpa_policy_access_rule_v2.go @@ -119,6 +119,7 @@ func resourcePolicyAccessRuleV2() *schema.Resource { "MACHINE_GRP", "COUNTRY_CODE", "PLATFORM", + "RISK_FACTOR_TYPE", }, false), }, "entry_values": { @@ -261,11 +262,11 @@ func resourcePolicyAccessV2Read(d *schema.ResourceData, meta interface{}) error _ = d.Set("description", v2PolicyRule.Description) _ = d.Set("action", v2PolicyRule.Action) _ = d.Set("operator", v2PolicyRule.Operator) - _ = d.Set("policy_set_id", policySetID) // Here, you're setting it based on fetched ID + _ = d.Set("policy_set_id", policySetID) _ = d.Set("custom_msg", v2PolicyRule.CustomMsg) _ = d.Set("conditions", flattenConditionsV2(v2PolicyRule.Conditions)) - _ = d.Set("app_server_groups", flattenPolicyRuleServerGroupsV2(resp.AppServerGroups)) - _ = d.Set("app_connector_groups", flattenPolicyRuleAppConnectorGroupsV2(resp.AppConnectorGroups)) + _ = d.Set("app_server_groups", flattenCommonAppServerGroups(resp.AppServerGroups)) + _ = d.Set("app_connector_groups", flattenCommonAppConnectorGroups(resp.AppConnectorGroups)) return nil } @@ -359,11 +360,12 @@ func expandCreatePolicyRuleV2(d *schema.ResourceData, policySetID string) (*poli Operator: d.Get("operator").(string), PolicySetID: policySetID, Conditions: conditions, - AppServerGroups: expandPolicySetControllerAppServerGroupsV2(d), - AppConnectorGroups: expandPolicysetControllerAppConnectorGroupsV2(d), + AppServerGroups: expandCommonServerGroups(d), + AppConnectorGroups: expandCommonAppConnectorGroups(d), }, nil } +/* func expandPolicySetControllerAppServerGroupsV2(d *schema.ResourceData) []policysetcontrollerv2.AppServerGroups { appServerGroupsInterface, ok := d.GetOk("app_server_groups") if ok { @@ -431,3 +433,4 @@ func flattenPolicyRuleAppConnectorGroupsV2(appConnectorGroups []policysetcontrol result[0] = mapIds return result } +*/ diff --git a/zpa/resource_zpa_policy_access_rule_v2_test.go b/zpa/resource_zpa_policy_access_rule_v2_test.go index 2a0ea116..07876feb 100644 --- a/zpa/resource_zpa_policy_access_rule_v2_test.go +++ b/zpa/resource_zpa_policy_access_rule_v2_test.go @@ -19,8 +19,8 @@ func TestAccResourcePolicyAccessRuleV2_Basic(t *testing.T) { // updatedRName := acctest.RandomWithPrefix("tf-updated") // New name for update test randDesc := acctest.RandString(10) - // appConnectorGroupTypeAndName, _, appConnectorGroupGeneratedName := method.GenerateRandomSourcesTypeAndName(resourcetype.ZPAAppConnectorGroup) - // appConnectorGroupHCL := testAccCheckAppConnectorGroupConfigure(appConnectorGroupTypeAndName, appConnectorGroupGeneratedName, variable.AppConnectorDescription, variable.AppConnectorEnabled) + appConnectorGroupTypeAndName, _, appConnectorGroupGeneratedName := method.GenerateRandomSourcesTypeAndName(resourcetype.ZPAAppConnectorGroup) + appConnectorGroupHCL := testAccCheckAppConnectorGroupConfigure(appConnectorGroupTypeAndName, appConnectorGroupGeneratedName, variable.AppConnectorDescription, variable.AppConnectorEnabled) segmentGroupTypeAndName, _, segmentGroupGeneratedName := method.GenerateRandomSourcesTypeAndName(resourcetype.ZPASegmentGroup) segmentGroupHCL := testAccCheckSegmentGroupConfigure(segmentGroupTypeAndName, "tf-acc-test-"+segmentGroupGeneratedName, variable.SegmentGroupDescription, variable.SegmentGroupEnabled) @@ -31,29 +31,29 @@ func TestAccResourcePolicyAccessRuleV2_Basic(t *testing.T) { CheckDestroy: testAccCheckPolicyAccessRuleV2Destroy, Steps: []resource.TestStep{ { - Config: testAccCheckPolicyAccessRuleV2Configure(resourceTypeAndName, generatedName, rName, randDesc, segmentGroupHCL, segmentGroupTypeAndName), + Config: testAccCheckPolicyAccessRuleV2Configure(resourceTypeAndName, generatedName, rName, randDesc, segmentGroupHCL, segmentGroupTypeAndName, appConnectorGroupHCL, appConnectorGroupTypeAndName), Check: resource.ComposeTestCheckFunc( testAccCheckPolicyAccessRuleV2Exists(resourceTypeAndName), resource.TestCheckResourceAttr(resourceTypeAndName, "name", rName), resource.TestCheckResourceAttr(resourceTypeAndName, "description", randDesc), resource.TestCheckResourceAttr(resourceTypeAndName, "action", "ALLOW"), resource.TestCheckResourceAttr(resourceTypeAndName, "operator", "AND"), - // resource.TestCheckResourceAttr(resourceTypeAndName, "app_connector_groups.#", "1"), - resource.TestCheckResourceAttr(resourceTypeAndName, "conditions.#", "4"), + resource.TestCheckResourceAttr(resourceTypeAndName, "app_connector_groups.#", "1"), + resource.TestCheckResourceAttr(resourceTypeAndName, "conditions.#", "5"), ), }, // Update test { - Config: testAccCheckPolicyAccessRuleV2Configure(resourceTypeAndName, generatedName, rName, randDesc, segmentGroupHCL, segmentGroupTypeAndName), + Config: testAccCheckPolicyAccessRuleV2Configure(resourceTypeAndName, generatedName, rName, randDesc, segmentGroupHCL, segmentGroupTypeAndName, appConnectorGroupHCL, appConnectorGroupTypeAndName), Check: resource.ComposeTestCheckFunc( testAccCheckPolicyAccessRuleV2Exists(resourceTypeAndName), resource.TestCheckResourceAttr(resourceTypeAndName, "name", rName), resource.TestCheckResourceAttr(resourceTypeAndName, "description", randDesc), resource.TestCheckResourceAttr(resourceTypeAndName, "action", "ALLOW"), resource.TestCheckResourceAttr(resourceTypeAndName, "operator", "AND"), - // resource.TestCheckResourceAttr(resourceTypeAndName, "app_connector_groups.#", "1"), - resource.TestCheckResourceAttr(resourceTypeAndName, "conditions.#", "4"), + resource.TestCheckResourceAttr(resourceTypeAndName, "app_connector_groups.#", "1"), + resource.TestCheckResourceAttr(resourceTypeAndName, "conditions.#", "5"), ), }, // Import test @@ -114,10 +114,11 @@ func testAccCheckPolicyAccessRuleV2Exists(resource string) resource.TestCheckFun } } -func testAccCheckPolicyAccessRuleV2Configure(resourceTypeAndName, rName, generatedName, desc, segmentGroupHCL, segmentGroupTypeAndName string) string { +func testAccCheckPolicyAccessRuleV2Configure(resourceTypeAndName, rName, generatedName, desc, segmentGroupHCL, segmentGroupTypeAndName, appConnectorGroupHCL, appConnectorGroupTypeAndName string) string { return fmt.Sprintf(` // app connector group resource +%s // segment group resource %s @@ -130,9 +131,9 @@ data "%s" "%s" { } `, // resource variables - // appConnectorGroupHCL, segmentGroupHCL, - getPolicyAccessRuleV2HCL(rName, generatedName, desc, segmentGroupTypeAndName), + appConnectorGroupHCL, + getPolicyAccessRuleV2HCL(rName, generatedName, desc, segmentGroupTypeAndName, appConnectorGroupTypeAndName), // data source variables resourcetype.ZPAPolicyType, @@ -141,7 +142,7 @@ data "%s" "%s" { ) } -func getPolicyAccessRuleV2HCL(rName, generatedName, desc, segmentGroupTypeAndName string) string { +func getPolicyAccessRuleV2HCL(rName, generatedName, desc, segmentGroupTypeAndName, appConnectorGroupTypeAndName string) string { return fmt.Sprintf(` data "zpa_idp_controller" "this" { @@ -173,6 +174,9 @@ resource "%s" "%s" { description = "%s" action = "ALLOW" operator = "AND" + app_connector_groups { + id = ["${%s.id}"] + } conditions { operator = "OR" operands { @@ -222,7 +226,25 @@ resource "%s" "%s" { } } } - depends_on = [ %s ] + conditions { + operator = "OR" + operands { + object_type = "RISK_FACTOR_TYPE" + entry_values { + lhs = "ZIA" + rhs = "UNKNOWN" + } + entry_values { + lhs = "ZIA" + rhs = "LOW" + } + entry_values { + lhs = "ZIA" + rhs = "MEDIUM" + } + } + } + depends_on = [ %s, %s ] } `, // resource variables @@ -230,9 +252,9 @@ resource "%s" "%s" { rName, generatedName, desc, - // appConnectorGroupTypeAndName, + appConnectorGroupTypeAndName, segmentGroupTypeAndName, - // appConnectorGroupTypeAndName, + appConnectorGroupTypeAndName, segmentGroupTypeAndName, ) } diff --git a/zpa/resource_zpa_segment_group.go b/zpa/resource_zpa_segment_group.go index c276ee15..b23fd5f8 100644 --- a/zpa/resource_zpa_segment_group.go +++ b/zpa/resource_zpa_segment_group.go @@ -142,17 +142,6 @@ func resourceSegmentGroupRead(d *schema.ResourceData, meta interface{}) error { return nil } -func flattenSegmentGroupApplicationsSimple(segmentGroup *segmentgroup.SegmentGroup) []interface{} { - segmentGroupApplications := make([]interface{}, len(segmentGroup.Applications)) - for i, segmentGroupApplication := range segmentGroup.Applications { - segmentGroupApplications[i] = map[string]interface{}{ - "id": segmentGroupApplication.ID, - } - } - - return segmentGroupApplications -} - func resourceSegmentGroupUpdate(d *schema.ResourceData, meta interface{}) error { zClient := meta.(*Client) service := zClient.SegmentGroup @@ -180,39 +169,6 @@ func resourceSegmentGroupUpdate(d *schema.ResourceData, meta interface{}) error return resourceSegmentGroupRead(d, meta) } -func detachSegmentGroupFromAllPolicyRules(d *schema.ResourceData, policySetControllerService *services.Service) { - policyRulesDetchLock.Lock() - defer policyRulesDetchLock.Unlock() - accessPolicySet, _, err := policysetcontroller.GetByPolicyType(policySetControllerService, "ACCESS_POLICY") - if err != nil { - return - } - rules, _, err := policysetcontroller.GetAllByType(policySetControllerService, "ACCESS_POLICY") - if err != nil { - return - } - for _, rule := range rules { - ids := []policysetcontroller.AppConnectorGroups{} - changed := false - for _, app := range rule.AppConnectorGroups { - if app.ID == d.Id() { - changed = true - continue - } - ids = append(ids, policysetcontroller.AppConnectorGroups{ - ID: app.ID, - }) - } - rule.AppConnectorGroups = ids - if changed { - microTenantID := GetString(d.Get("microtenant_id")) - if _, err := policysetcontroller.UpdateRule(policySetControllerService.WithMicroTenant(microTenantID), accessPolicySet.ID, rule.ID, &rule); err != nil { - continue - } - } - } -} - func resourceSegmentGroupDelete(d *schema.ResourceData, meta interface{}) error { zClient := meta.(*Client) policySetControllerService := zClient.PolicySetController @@ -230,7 +186,7 @@ func resourceSegmentGroupDelete(d *schema.ResourceData, meta interface{}) error log.Printf("[INFO] Deleting app connector group ID: %v\n", d.Id()) //detach app connector group from all access policy rules - detachSegmentGroupFromAllPolicyRules(d, policySetControllerService) + detachSegmentGroupFromAllPolicyRules(d.Id(), policySetControllerService) if _, err := segmentgroup.Delete(service, d.Id()); err != nil { return err @@ -265,3 +221,59 @@ func expandSegmentGroupApplications(segmentGroupApplication []interface{}) []seg return segmentGroupApplications } + +func detachSegmentGroupFromAllPolicyRules(id string, policySetControllerService *services.Service) { + policyRulesDetchLock.Lock() + defer policyRulesDetchLock.Unlock() + var rules []policysetcontroller.PolicyRule + types := []string{"ACCESS_POLICY", "TIMEOUT_POLICY", "SIEM_POLICY", "CLIENT_FORWARDING_POLICY", "INSPECTION_POLICY"} + for _, t := range types { + policySet, _, err := policysetcontroller.GetByPolicyType(policySetControllerService, t) + if err != nil { + continue + } + r, _, err := policysetcontroller.GetAllByType(policySetControllerService, t) + if err != nil { + continue + } + for _, rule := range r { + rule.PolicySetID = policySet.ID + rules = append(rules, rule) + } + } + log.Printf("[INFO] detaching Segment Groups From All Policy Rules, len:%d \n", len(rules)) + for _, rr := range rules { + rule := rr + changed := false + for i, condition := range rr.Conditions { + operands := []policysetcontroller.Operands{} + for _, op := range condition.Operands { + if op.ObjectType == "APP_GROUP" && op.LHS == "id" && op.RHS == id { + changed = true + continue + } + operands = append(operands, op) + } + rule.Conditions[i].Operands = operands + } + if len(rule.Conditions) == 0 { + rule.Conditions = []policysetcontroller.Conditions{} + } + if changed { + if _, err := policysetcontroller.UpdateRule(policySetControllerService, rule.PolicySetID, rule.ID, &rule); err != nil { + continue + } + } + } +} + +func flattenSegmentGroupApplicationsSimple(segmentGroup *segmentgroup.SegmentGroup) []interface{} { + segmentGroupApplications := make([]interface{}, len(segmentGroup.Applications)) + for i, segmentGroupApplication := range segmentGroup.Applications { + segmentGroupApplications[i] = map[string]interface{}{ + "id": segmentGroupApplication.ID, + } + } + + return segmentGroupApplications +} diff --git a/zpa/resource_zpa_server_group.go b/zpa/resource_zpa_server_group.go index c8d64ab1..cc2015ed 100644 --- a/zpa/resource_zpa_server_group.go +++ b/zpa/resource_zpa_server_group.go @@ -12,6 +12,7 @@ import ( "github.com/zscaler/zscaler-sdk-go/v2/zpa/services" "github.com/zscaler/zscaler-sdk-go/v2/zpa/services/appconnectorgroup" "github.com/zscaler/zscaler-sdk-go/v2/zpa/services/applicationsegment" + "github.com/zscaler/zscaler-sdk-go/v2/zpa/services/appservercontroller" "github.com/zscaler/zscaler-sdk-go/v2/zpa/services/policysetcontroller" "github.com/zscaler/zscaler-sdk-go/v2/zpa/services/servergroup" ) @@ -209,37 +210,13 @@ func resourceServerGroupRead(d *schema.ResourceData, meta interface{}) error { _ = d.Set("enabled", resp.Enabled) _ = d.Set("name", resp.Name) _ = d.Set("microtenant_id", resp.MicroTenantID) - _ = d.Set("app_connector_groups", flattenAppConnectorGroupsSimple(resp.AppConnectorGroups)) + _ = d.Set("app_connector_groups", flattenCommonAppConnectorGroups(resp.AppConnectorGroups)) _ = d.Set("applications", flattenServerGroupApplicationsSimple(resp.Applications)) _ = d.Set("servers", flattenServers(resp.Servers)) return nil } -func flattenAppConnectorGroupsSimple(appConnectorGroups []servergroup.AppConnectorGroups) []interface{} { - result := make([]interface{}, 1) - mapIds := make(map[string]interface{}) - ids := make([]string, len(appConnectorGroups)) - for i, group := range appConnectorGroups { - ids[i] = group.ID - } - mapIds["id"] = ids - result[0] = mapIds - return result -} - -func flattenServerGroupApplicationsSimple(apps []servergroup.Applications) []interface{} { - result := make([]interface{}, 1) - mapIds := make(map[string]interface{}) - ids := make([]string, len(apps)) - for i, app := range apps { - ids[i] = app.ID - } - mapIds["id"] = ids - result[0] = mapIds - return result -} - func resourceServerGroupUpdate(d *schema.ResourceData, meta interface{}) error { zClient := meta.(*Client) service := zClient.ServerGroup @@ -324,14 +301,14 @@ func detachServerGroupFromAllAccessPolicyRules(id string, policySetControllerSer return } for _, accessPolicyRule := range accessPolicyRules { - ids := []policysetcontroller.AppServerGroups{} + ids := []servergroup.ServerGroup{} changed := false for _, app := range accessPolicyRule.AppServerGroups { if app.ID == id { changed = true continue } - ids = append(ids, policysetcontroller.AppServerGroups{ + ids = append(ids, servergroup.ServerGroup{ ID: app.ID, }) } @@ -350,12 +327,12 @@ func detachServerGroupFromAllAppSegments(id string, applicationSegmentService *s return } for _, app := range apps { - ids := []applicationsegment.AppServerGroups{} + ids := []servergroup.ServerGroup{} for _, appServerGroup := range app.ServerGroups { if appServerGroup.ID == id { continue } - ids = append(ids, applicationsegment.AppServerGroups{ + ids = append(ids, servergroup.ServerGroup{ ID: appServerGroup.ID, }) } @@ -407,7 +384,7 @@ func expandServerGroup(d *schema.ResourceData) servergroup.ServerGroup { ConfigSpace: d.Get("config_space").(string), DynamicDiscovery: d.Get("dynamic_discovery").(bool), MicroTenantID: d.Get("microtenant_id").(string), - AppConnectorGroups: expandAppConnectorGroups(d), + AppConnectorGroups: expandCommonAppConnectorGroups(d), Applications: expandServerGroupApplications(d), Servers: expandApplicationServers(d), } @@ -417,6 +394,7 @@ func expandServerGroup(d *schema.ResourceData) servergroup.ServerGroup { return result } +/* func expandAppConnectorGroups(d *schema.ResourceData) []servergroup.AppConnectorGroups { appConnectorGroupsInterface, ok := d.GetOk("app_connector_groups") if ok { @@ -438,6 +416,7 @@ func expandAppConnectorGroups(d *schema.ResourceData) []servergroup.AppConnector return []servergroup.AppConnectorGroups{} } +*/ func expandServerGroupApplications(d *schema.ResourceData) []servergroup.Applications { serverGroupAppsInterface, ok := d.GetOk("applications") @@ -461,17 +440,17 @@ func expandServerGroupApplications(d *schema.ResourceData) []servergroup.Applica return []servergroup.Applications{} } -func expandApplicationServers(d *schema.ResourceData) []servergroup.ApplicationServer { +func expandApplicationServers(d *schema.ResourceData) []appservercontroller.ApplicationServer { applicationServersInterface, ok := d.GetOk("servers") if ok { applicationServer := applicationServersInterface.(*schema.Set) log.Printf("[INFO] server group application data: %+v\n", applicationServer) - var applicationServers []servergroup.ApplicationServer + var applicationServers []appservercontroller.ApplicationServer for _, applicationServer := range applicationServer.List() { applicationServer, _ := applicationServer.(map[string]interface{}) if applicationServer != nil { for _, id := range applicationServer["id"].([]interface{}) { - applicationServers = append(applicationServers, servergroup.ApplicationServer{ + applicationServers = append(applicationServers, appservercontroller.ApplicationServer{ ID: id.(string), }) } @@ -480,5 +459,31 @@ func expandApplicationServers(d *schema.ResourceData) []servergroup.ApplicationS return applicationServers } - return []servergroup.ApplicationServer{} + return []appservercontroller.ApplicationServer{} +} + +func flattenServerGroupApplicationsSimple(apps []servergroup.Applications) []interface{} { + result := make([]interface{}, 1) + mapIds := make(map[string]interface{}) + ids := make([]string, len(apps)) + for i, app := range apps { + ids[i] = app.ID + } + mapIds["id"] = ids + result[0] = mapIds + return result +} + +/* +func flattenAppConnectorGroupsSimple(appConnectorGroups []servergroup.AppConnectorGroups) []interface{} { + result := make([]interface{}, 1) + mapIds := make(map[string]interface{}) + ids := make([]string, len(appConnectorGroups)) + for i, group := range appConnectorGroups { + ids[i] = group.ID + } + mapIds["id"] = ids + result[0] = mapIds + return result } +*/ diff --git a/zpa/utils.go b/zpa/utils.go index 9dbc38f1..e69963a7 100755 --- a/zpa/utils.go +++ b/zpa/utils.go @@ -100,24 +100,38 @@ func convertPortsToListString(portRangeLst []common.NetworkPorts) []string { return portRanges } -// Function to duplicate each port range value in the list -func duplicatePortRanges(portRangeLst []interface{}) []string { - portRanges := make([]string, 0, len(portRangeLst)*2) - for _, v := range portRangeLst { - port := v.(string) - portRanges = append(portRanges, port, port) +func convertToPortRange(portRangeLst []interface{}) []string { + portRanges := make([]string, len(portRangeLst)) + for i := range portRanges { + portRanges[i] = portRangeLst[i].(string) } return portRanges } -func convertToPortRange(portRangeLst []interface{}) []string { +/* +func expandList(portRangeLst []interface{}) []string { portRanges := make([]string, len(portRangeLst)) - for i := range portRanges { - portRanges[i] = portRangeLst[i].(string) + for i, port := range portRangeLst { + portRanges[i] = port.(string) } + return portRanges } +*/ + +func isSameSlice(s1, s2 []string) bool { + if len(s1) != len(s2) { + return false + } + for i := range s1 { + if s1[i] != s2[i] { + return false + } + } + return true +} +/* func expandAppSegmentNetwokPorts(d *schema.ResourceData, key string) []string { var ports []string if portsInterface, ok := d.GetOk(key); ok { @@ -135,6 +149,46 @@ func expandAppSegmentNetwokPorts(d *schema.ResourceData, key string) []string { } return ports } +*/ + +func expandAppSegmentNetwokPorts(d *schema.ResourceData, key string) []string { + var ports []string + if portsInterface, ok := d.GetOk(key); ok { + portList, ok := portsInterface.([]interface{}) + if !ok { + log.Printf("[ERROR] conversion failed, destUdpPortsInterface") + return []string{} + } + ports = make([]string, len(portList)*2) + for i, val := range portList { + portItem := val.(map[string]interface{}) + ports[2*i] = portItem["from"].(string) + ports[2*i+1] = portItem["to"].(string) + } + } + return ports +} + +// Helper function to expand the new format +// func expandNetworkPorts(d *schema.ResourceData, key string) []common.NetworkPorts { +// var ports []common.NetworkPorts +// if portsInterface, ok := d.GetOk(key); ok { +// portSet, ok := portsInterface.(*schema.Set) +// if !ok { +// log.Printf("[ERROR] conversion failed, %s", key) +// return []common.NetworkPorts{} +// } +// ports = make([]common.NetworkPorts, len(portSet.List())) +// for i, val := range portSet.List() { +// portItem := val.(map[string]interface{}) +// ports[i] = common.NetworkPorts{ +// From: portItem["from"].(string), +// To: portItem["to"].(string), +// } +// } +// } +// return ports +// } func sliceHasCommon(s1, s2 []string) (bool, string) { for _, i1 := range s1 { @@ -147,18 +201,6 @@ func sliceHasCommon(s1, s2 []string) (bool, string) { return false, "" } -func isSameSlice(s1, s2 []string) bool { - if len(s1) != len(s2) { - return false - } - for i := range s1 { - if s1[i] != s2[i] { - return false - } - } - return true -} - func expandStringInSlice(d *schema.ResourceData, key string) []string { applicationSegments := d.Get(key).([]interface{}) applicationSegmentList := make([]string, len(applicationSegments))