From 14c6effae8d94ba74a132f350a0a39133e8edbac Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 25 Oct 2023 10:40:02 -0700 Subject: [PATCH 1/3] Bump github.com/hashicorp/terraform-plugin-framework from 1.4.1 to 1.4.2 (#417) Bumps [github.com/hashicorp/terraform-plugin-framework](https://github.com/hashicorp/terraform-plugin-framework) from 1.4.1 to 1.4.2. - [Release notes](https://github.com/hashicorp/terraform-plugin-framework/releases) - [Changelog](https://github.com/hashicorp/terraform-plugin-framework/blob/main/CHANGELOG.md) - [Commits](https://github.com/hashicorp/terraform-plugin-framework/compare/v1.4.1...v1.4.2) --- updated-dependencies: - dependency-name: github.com/hashicorp/terraform-plugin-framework dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 6ccf0001..689eaa23 100644 --- a/go.mod +++ b/go.mod @@ -8,7 +8,7 @@ require ( github.com/hashicorp/go-retryablehttp v0.7.4 github.com/hashicorp/go-uuid v1.0.3 github.com/hashicorp/terraform-plugin-docs v0.16.0 - github.com/hashicorp/terraform-plugin-framework v1.4.1 + github.com/hashicorp/terraform-plugin-framework v1.4.2 github.com/hashicorp/terraform-plugin-framework-validators v0.12.0 github.com/hashicorp/terraform-plugin-go v0.19.0 github.com/hashicorp/terraform-plugin-mux v0.12.0 diff --git a/go.sum b/go.sum index 728cfeed..ed3c34ff 100644 --- a/go.sum +++ b/go.sum @@ -148,8 +148,8 @@ github.com/hashicorp/terraform-json v0.17.1 h1:eMfvh/uWggKmY7Pmb3T85u86E2EQg6EQH github.com/hashicorp/terraform-json v0.17.1/go.mod h1:Huy6zt6euxaY9knPAFKjUITn8QxUFIe9VuSzb4zn/0o= github.com/hashicorp/terraform-plugin-docs v0.16.0 h1:UmxFr3AScl6Wged84jndJIfFccGyBZn52KtMNsS12dI= github.com/hashicorp/terraform-plugin-docs v0.16.0/go.mod h1:M3ZrlKBJAbPMtNOPwHicGi1c+hZUh7/g0ifT/z7TVfA= -github.com/hashicorp/terraform-plugin-framework v1.4.1 h1:ZC29MoB3Nbov6axHdgPbMz7799pT5H8kIrM8YAsaVrs= -github.com/hashicorp/terraform-plugin-framework v1.4.1/go.mod h1:XC0hPcQbBvlbxwmjxuV/8sn8SbZRg4XwGMs22f+kqV0= +github.com/hashicorp/terraform-plugin-framework v1.4.2 h1:P7a7VP1GZbjc4rv921Xy5OckzhoiO3ig6SGxwelD2sI= +github.com/hashicorp/terraform-plugin-framework v1.4.2/go.mod h1:GWl3InPFZi2wVQmdVnINPKys09s9mLmTZr95/ngLnbY= github.com/hashicorp/terraform-plugin-framework-validators v0.12.0 h1:HOjBuMbOEzl7snOdOoUfE2Jgeto6JOjLVQ39Ls2nksc= github.com/hashicorp/terraform-plugin-framework-validators v0.12.0/go.mod h1:jfHGE/gzjxYz6XoUwi/aYiiKrJDeutQNUtGQXkaHklg= github.com/hashicorp/terraform-plugin-go v0.19.0 h1:BuZx/6Cp+lkmiG0cOBk6Zps0Cb2tmqQpDM3iAtnhDQU= From b90258726376235cb28fceb7f4c7e11358ae7173 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 25 Oct 2023 15:00:00 -0700 Subject: [PATCH 2/3] Bump google.golang.org/grpc from 1.57.0 to 1.57.1 (#419) Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.57.0 to 1.57.1. - [Release notes](https://github.com/grpc/grpc-go/releases) - [Commits](https://github.com/grpc/grpc-go/compare/v1.57.0...v1.57.1) --- updated-dependencies: - dependency-name: google.golang.org/grpc dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 689eaa23..ca45cb5c 100644 --- a/go.mod +++ b/go.mod @@ -93,7 +93,7 @@ require ( golang.org/x/tools v0.14.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19 // indirect - google.golang.org/grpc v1.57.0 // indirect + google.golang.org/grpc v1.57.1 // indirect google.golang.org/protobuf v1.31.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect diff --git a/go.sum b/go.sum index ed3c34ff..7b84e27a 100644 --- a/go.sum +++ b/go.sum @@ -401,8 +401,8 @@ google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6 google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19 h1:0nDDozoAU19Qb2HwhXadU8OcsiO/09cnTqhUtq2MEOM= google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= -google.golang.org/grpc v1.57.0 h1:kfzNeI/klCGD2YPMUlaGNT3pxvYfga7smW3Vth8Zsiw= -google.golang.org/grpc v1.57.0/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo= +google.golang.org/grpc v1.57.1 h1:upNTNqv0ES+2ZOOqACwVtS3Il8M12/+Hz41RCPzAjQg= +google.golang.org/grpc v1.57.1/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= From 6001536fe39296bb5d20b6cec27c21c14671af1d Mon Sep 17 00:00:00 2001 From: Volodymyr Manilo <35466116+vmanilo@users.noreply.github.com> Date: Fri, 27 Oct 2023 21:03:23 +0200 Subject: [PATCH 3/3] Fix: added Resource validation for wildcard address and enabled browser shortcut (#418) * wip * added validation for wildcard address and enabled browser shortcut * fix checking if attribute present in TF config * added wildcard address validation --- .../internal/provider/resource/helper_test.go | 34 +++++ .../internal/provider/resource/resource.go | 27 +++- .../test/acctests/resource/resource_test.go | 121 ++++++++++++++++++ 3 files changed, 178 insertions(+), 4 deletions(-) diff --git a/twingate/internal/provider/resource/helper_test.go b/twingate/internal/provider/resource/helper_test.go index d0a5b1f8..37bc74f1 100644 --- a/twingate/internal/provider/resource/helper_test.go +++ b/twingate/internal/provider/resource/helper_test.go @@ -153,3 +153,37 @@ func stringPtr(s string) *string { func boolPtr(b bool) *bool { return &b } + +func TestIsWildcardAddress(t *testing.T) { + cases := []struct { + address string + expected bool + }{ + { + address: "hello.com", + expected: false, + }, + { + address: "*.hello.com", + expected: true, + }, + { + address: "redis-?-blah.internal", + expected: true, + }, + { + address: "redis-*-blah.internal", + expected: true, + }, + { + address: "10.0.0.0/16", + expected: true, + }, + } + + for n, c := range cases { + t.Run(fmt.Sprintf("case_%d", n), func(t *testing.T) { + assert.Equal(t, c.expected, isWildcardAddress(c.address)) + }) + } +} diff --git a/twingate/internal/provider/resource/resource.go b/twingate/internal/provider/resource/resource.go index d851ef39..82ba876b 100644 --- a/twingate/internal/provider/resource/resource.go +++ b/twingate/internal/provider/resource/resource.go @@ -6,6 +6,7 @@ import ( "fmt" "log" "reflect" + "regexp" "strings" "github.com/Twingate/terraform-provider-twingate/twingate/internal/attr" @@ -17,9 +18,10 @@ import ( ) var ( - ErrPortsWithPolicyAllowAll = errors.New(model.PolicyAllowAll + " policy does not allow specifying ports.") - ErrPortsWithPolicyDenyAll = errors.New(model.PolicyDenyAll + " policy does not allow specifying ports.") - ErrPolicyRestrictedWithoutPorts = errors.New(model.PolicyRestricted + " policy requires specifying ports.") + ErrPortsWithPolicyAllowAll = errors.New(model.PolicyAllowAll + " policy does not allow specifying ports.") + ErrPortsWithPolicyDenyAll = errors.New(model.PolicyDenyAll + " policy does not allow specifying ports.") + ErrPolicyRestrictedWithoutPorts = errors.New(model.PolicyRestricted + " policy requires specifying ports.") + ErrWildcardAddressWithEnabledShortcut = errors.New("Resources with a CIDR range or wildcard can't have the browser shortcut enabled.") ) func Resource() *schema.Resource { //nolint:funlen @@ -497,13 +499,30 @@ func convertResource(data *schema.ResourceData) (*model.Resource, error) { } isBrowserShortcutEnabled, ok := data.GetOkExists(attr.IsBrowserShortcutEnabled) //nolint - if val := isBrowserShortcutEnabled.(bool); ok { + if val := isBrowserShortcutEnabled.(bool); ok && isAttrKnown(data, attr.IsBrowserShortcutEnabled) { res.IsBrowserShortcutEnabled = &val } + if res.IsBrowserShortcutEnabled != nil && *res.IsBrowserShortcutEnabled && isWildcardAddress(res.Address) { + return nil, ErrWildcardAddressWithEnabledShortcut + } + return res, nil } +var cidrRgxp = regexp.MustCompile(`(\d{1,3}\.){3}\d{1,3}(/\d+)?`) + +func isWildcardAddress(address string) bool { + return strings.ContainsAny(address, "*?") || cidrRgxp.MatchString(address) +} + +func isAttrKnown(data *schema.ResourceData, attr string) bool { + cfg := data.GetRawConfig() + val := cfg.GetAttr(attr) + + return !val.IsNull() && val.IsKnown() +} + func getOptionalString(data *schema.ResourceData, attr string) *string { var result *string diff --git a/twingate/internal/test/acctests/resource/resource_test.go b/twingate/internal/test/acctests/resource/resource_test.go index 7e5efcf4..a5a97811 100644 --- a/twingate/internal/test/acctests/resource/resource_test.go +++ b/twingate/internal/test/acctests/resource/resource_test.go @@ -2421,3 +2421,124 @@ func TestAccTwingateResourcePolicyTransitionAllowAllToDenyAll(t *testing.T) { }, }) } + +func TestAccTwingateResourceWithBrowserOption(t *testing.T) { + const terraformResourceName = "test40" + theResource := acctests.TerraformResource(terraformResourceName) + remoteNetworkName := test.RandomName() + resourceName := test.RandomResourceName() + wildcardAddress := "*.acc-test.com" + + sdk.Test(t, sdk.TestCase{ + ProtoV6ProviderFactories: acctests.ProviderFactories, + PreCheck: func() { acctests.PreCheck(t) }, + CheckDestroy: acctests.CheckTwingateResourceDestroy, + Steps: []sdk.TestStep{ + { + Config: createResourceWithoutBrowserOption(terraformResourceName, remoteNetworkName, resourceName, wildcardAddress), + Check: acctests.ComposeTestCheckFunc( + acctests.CheckTwingateResourceExists(theResource), + ), + }, + { + Config: createResourceWithBrowserOption(terraformResourceName, remoteNetworkName, resourceName, wildcardAddress, false), + Check: acctests.ComposeTestCheckFunc( + acctests.CheckTwingateResourceExists(theResource), + ), + }, + { + Config: createResourceWithBrowserOption(terraformResourceName, remoteNetworkName, resourceName, wildcardAddress, true), + ExpectError: regexp.MustCompile(resource.ErrWildcardAddressWithEnabledShortcut.Error()), + }, + }, + }) +} + +func TestAccTwingateResourceWithBrowserOptionFailOnUpdate(t *testing.T) { + const terraformResourceName = "test41" + theResource := acctests.TerraformResource(terraformResourceName) + remoteNetworkName := test.RandomName() + resourceName := test.RandomResourceName() + wildcardAddress := "*.acc-test.com" + simpleAddress := "acc-test.com" + + sdk.Test(t, sdk.TestCase{ + ProtoV6ProviderFactories: acctests.ProviderFactories, + PreCheck: func() { acctests.PreCheck(t) }, + CheckDestroy: acctests.CheckTwingateResourceDestroy, + Steps: []sdk.TestStep{ + { + Config: createResourceWithoutBrowserOption(terraformResourceName, remoteNetworkName, resourceName, simpleAddress), + Check: acctests.ComposeTestCheckFunc( + acctests.CheckTwingateResourceExists(theResource), + ), + }, + { + Config: createResourceWithBrowserOption(terraformResourceName, remoteNetworkName, resourceName, simpleAddress, true), + Check: acctests.ComposeTestCheckFunc( + acctests.CheckTwingateResourceExists(theResource), + ), + }, + { + Config: createResourceWithBrowserOption(terraformResourceName, remoteNetworkName, resourceName, wildcardAddress, true), + ExpectError: regexp.MustCompile(resource.ErrWildcardAddressWithEnabledShortcut.Error()), + }, + }, + }) +} + +func TestAccTwingateResourceWithBrowserOptionRecovered(t *testing.T) { + const terraformResourceName = "test42" + theResource := acctests.TerraformResource(terraformResourceName) + remoteNetworkName := test.RandomName() + resourceName := test.RandomResourceName() + wildcardAddress := "*.acc-test.com" + simpleAddress := "acc-test.com" + + sdk.Test(t, sdk.TestCase{ + ProtoV6ProviderFactories: acctests.ProviderFactories, + PreCheck: func() { acctests.PreCheck(t) }, + CheckDestroy: acctests.CheckTwingateResourceDestroy, + Steps: []sdk.TestStep{ + { + Config: createResourceWithBrowserOption(terraformResourceName, remoteNetworkName, resourceName, simpleAddress, true), + Check: acctests.ComposeTestCheckFunc( + acctests.CheckTwingateResourceExists(theResource), + ), + }, + { + Config: createResourceWithoutBrowserOption(terraformResourceName, remoteNetworkName, resourceName, wildcardAddress), + Check: acctests.ComposeTestCheckFunc( + acctests.CheckTwingateResourceExists(theResource), + ), + }, + }, + }) +} + +func createResourceWithoutBrowserOption(name, networkName, resourceName, address string) string { + return fmt.Sprintf(` + resource "twingate_remote_network" "%[1]s" { + name = "%[2]s" + } + resource "twingate_resource" "%[1]s" { + name = "%[3]s" + address = "%[4]s" + remote_network_id = twingate_remote_network.%[1]s.id + } + `, name, networkName, resourceName, address) +} + +func createResourceWithBrowserOption(name, networkName, resourceName, address string, browserOption bool) string { + return fmt.Sprintf(` + resource "twingate_remote_network" "%[1]s" { + name = "%[2]s" + } + resource "twingate_resource" "%[1]s" { + name = "%[3]s" + address = "%[4]s" + remote_network_id = twingate_remote_network.%[1]s.id + is_browser_shortcut_enabled = %[5]v + } + `, name, networkName, resourceName, address, browserOption) +}