Skip to content

Commit

Permalink
Fix VPN data sources for newer NSX version
Browse files Browse the repository at this point in the history
With latest NSX, search API result omits locale-service
component, which data sources use in filtering.
This breaks vpn local endpoint data source when used with
service_path. This change switches from search API to List
API for such cases.
In addition, expose local_address in local enpoint data
source.

Signed-off-by: Anna Khmelnitsky <[email protected]>
  • Loading branch information
annakhm committed Feb 16, 2023
1 parent e686f0a commit 8ecfdfe
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 14 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/website-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v3
with:
go-version: 1.18
go-version: 1.19

- name: Install tools
run: make tools
Expand Down
56 changes: 54 additions & 2 deletions nsxt/data_source_nsxt_policy_ipsec_vpn_local_endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@
package nsxt

import (
"fmt"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/vmware/vsphere-automation-sdk-go/runtime/bindings"
"github.com/vmware/vsphere-automation-sdk-go/services/nsxt/model"
)

func dataSourceNsxtPolicyIPSecVpnLocalEndpoint() *schema.Resource {
Expand All @@ -17,6 +21,11 @@ func dataSourceNsxtPolicyIPSecVpnLocalEndpoint() *schema.Resource {
"display_name": getDataSourceDisplayNameSchema(),
"description": getDataSourceDescriptionSchema(),
"path": getPathSchema(),
"local_address": {
Type: schema.TypeString,
Description: "Local IPv4 IP address",
Computed: true,
},
},
}
}
Expand All @@ -27,12 +36,55 @@ func dataSourceNsxtPolicyIPSecVpnLocalEndpointRead(d *schema.ResourceData, m int
servicePath := d.Get("service_path").(string)
query := make(map[string]string)
if len(servicePath) > 0 {
query["parent_path"] = servicePath
// In newer NSX versions, NSX removes locale service from the parent path when search API is concerned
objID := d.Get("id").(string)
objName := d.Get("display_name").(string)
client, err := newLocalEndpointClient(servicePath)
if err != nil {
return err
}
if objID != "" {
obj, err := client.Get(connector, objID)
if err != nil {
return fmt.Errorf("Failed to locate Local Endpoint %s/%s: %v", servicePath, objID, err)
}
d.SetId(*obj.Id)
d.Set("display_name", obj.DisplayName)
d.Set("description", obj.Description)
d.Set("path", obj.Path)
d.Set("local_address", obj.LocalAddress)
return nil
}

objList, err := client.List(connector)
if err != nil {
return fmt.Errorf("Failed to list local endpoints: %v", err)
}

for _, obj := range objList {
if *obj.DisplayName == objName {
d.SetId(*obj.Id)
d.Set("display_name", obj.DisplayName)
d.Set("description", obj.Description)
d.Set("path", obj.Path)
d.Set("local_address", obj.LocalAddress)
return nil
}
}
return fmt.Errorf("Failed to locate Local Endpoint under %s named %s", servicePath, objName)
}
_, err := policyDataSourceResourceReadWithValidation(d, connector, isPolicyGlobalManager(m), "IPSecVpnLocalEndpoint", query, false)
objInt, err := policyDataSourceResourceReadWithValidation(d, connector, isPolicyGlobalManager(m), "IPSecVpnLocalEndpoint", query, false)
if err != nil {
return err
}

converter := bindings.NewTypeConverter()
converter.SetMode(bindings.REST)
dataValue, errors := converter.ConvertToGolang(objInt, model.IPSecVpnLocalEndpointBindingType())
if len(errors) > 0 {
return fmt.Errorf("Failed to convert type for Local Endpoint: %v", errors[0])
}
obj := dataValue.(model.IPSecVpnLocalEndpoint)
d.Set("local_address", obj.LocalAddress)
return nil
}
13 changes: 5 additions & 8 deletions nsxt/data_source_nsxt_policy_ipsec_vpn_local_endpoint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ import (
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
)

var dataSourceNsxtPolicyTestAddress = "20.20.0.2"

func TestAccDataSourceNsxtPolicyIPSecVpnLocalEndpoint(t *testing.T) {
name := getAccTestResourceName()
testResourceName := "data.nsxt_policy_ipsec_vpn_local_endpoint.test"
Expand All @@ -21,14 +22,12 @@ func TestAccDataSourceNsxtPolicyIPSecVpnLocalEndpoint(t *testing.T) {
testAccOnlyLocalManager(t)
},
Providers: testAccProviders,
CheckDestroy: func(state *terraform.State) error {
return testAccNsxtPolicyIPSecVpnLocalEndpointCheckDestroy(state, name)
},
Steps: []resource.TestStep{
{
Config: testAccNsxtPolicyIPSecVpnLocalEndpointDataSourceTemplate(name),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(testResourceName, "display_name", name),
resource.TestCheckResourceAttr(testResourceName, "local_address", dataSourceNsxtPolicyTestAddress),
resource.TestCheckResourceAttrSet(testResourceName, "path"),
),
},
Expand All @@ -46,14 +45,12 @@ func TestAccDataSourceNsxtPolicyIPSecVpnLocalEndpoint_withService(t *testing.T)
testAccOnlyLocalManager(t)
},
Providers: testAccProviders,
CheckDestroy: func(state *terraform.State) error {
return testAccNsxtPolicyIPSecVpnLocalEndpointCheckDestroy(state, name)
},
Steps: []resource.TestStep{
{
Config: testAccNsxtPolicyIPSecVpnLocalEndpointDataSourceTemplateWithService(name),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr(testResourceName, "display_name", name),
resource.TestCheckResourceAttr(testResourceName, "local_address", dataSourceNsxtPolicyTestAddress),
resource.TestCheckResourceAttrSet(testResourceName, "path"),
),
},
Expand Down Expand Up @@ -88,5 +85,5 @@ resource "nsxt_policy_ipsec_vpn_local_endpoint" "test" {
service_path = nsxt_policy_ipsec_vpn_service.test.path
display_name = "%s"
local_address = "%s"
}`, name, name, "20.20.0.10")
}`, name, name, dataSourceNsxtPolicyTestAddress)
}
2 changes: 1 addition & 1 deletion nsxt/data_source_nsxt_policy_ipsec_vpn_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func dataSourceNsxtPolicyIPSecVpnServiceRead(d *schema.ResourceData, m interface
gwPath := d.Get("gateway_path").(string)
query := make(map[string]string)
if len(gwPath) > 0 {
query["parent_path"] = fmt.Sprintf("%s/*", gwPath)
query["parent_path"] = fmt.Sprintf("%s*", gwPath)
}
_, err := policyDataSourceResourceReadWithValidation(d, connector, isPolicyGlobalManager(m), "IPSecVpnService", query, false)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion nsxt/data_source_nsxt_policy_l2_vpn_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ func dataSourceNsxtPolicyL2VpnServiceRead(d *schema.ResourceData, m interface{})
gwPath := d.Get("gateway_path").(string)
query := make(map[string]string)
if len(gwPath) > 0 {
query["parent_path"] = fmt.Sprintf("%s/*", gwPath)
query["parent_path"] = fmt.Sprintf("%s*", gwPath)
}
_, err := policyDataSourceResourceReadWithValidation(d, connector, isPolicyGlobalManager(m), "L2VPNService", query, false)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion nsxt/data_source_nsxt_policy_qos_profile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ func TestAccDataSourceNsxtPolicyQosProfile_basic(t *testing.T) {
name := getAccTestDataSourceName()
testResourceName := "data.nsxt_policy_qos_profile.test"

resource.ParallelTest(t, resource.TestCase{
resource.Test(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t) },
Providers: testAccProviders,
CheckDestroy: func(state *terraform.State) error {
Expand Down
28 changes: 28 additions & 0 deletions nsxt/resource_nsxt_policy_ipsec_vpn_local_endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,34 @@ func (c *localEndpointClient) Get(connector *client.RestConnector, id string) (m
return client.Get(c.gwID, c.serviceID, id)
}

// Note: we don't expect pagination to be relevant here
func (c *localEndpointClient) List(connector *client.RestConnector) ([]model.IPSecVpnLocalEndpoint, error) {
boolFalse := false
var cursor string
var result model.IPSecVpnLocalEndpointListResult
var err error
if c.isT0 {
if len(c.localeServiceID) > 0 {
client := t0_nested_service.NewLocalEndpointsClient(connector)
result, err = client.List(c.gwID, c.localeServiceID, c.serviceID, &cursor, &boolFalse, nil, nil, nil, nil)
} else {
client := t0_service.NewLocalEndpointsClient(connector)
result, err = client.List(c.gwID, c.serviceID, &cursor, &boolFalse, nil, nil, nil, nil)
}

} else {
if len(c.localeServiceID) > 0 {
client := t1_nested_service.NewLocalEndpointsClient(connector)
result, err = client.List(c.gwID, c.localeServiceID, c.serviceID, &cursor, &boolFalse, nil, nil, nil, nil)
} else {
client := t1_service.NewLocalEndpointsClient(connector)
result, err = client.List(c.gwID, c.serviceID, &cursor, &boolFalse, nil, nil, nil, nil)
}
}

return result.Results, err
}

func (c *localEndpointClient) Patch(connector *client.RestConnector, id string, obj model.IPSecVpnLocalEndpoint) error {
if c.isT0 {
if len(c.localeServiceID) > 0 {
Expand Down

0 comments on commit 8ecfdfe

Please sign in to comment.