Skip to content

Commit

Permalink
API Refactoring for VPN resources
Browse files Browse the repository at this point in the history
NSX API that uses locale service path of VPN resources will be
deprecated, this PR adds support for the new API that uses gateway
path.

The change in this PR includes:
(1) Support for configuring VPN Resource with gateway path.
(2) change data_source_nsxt_policy_ipsec_vpn_local_endpoint to
use regex-based search API.
(3) For VPN Sessions, if only specify the direction of Tcp Mss
Clampling, the provider will use the auto-assigned value for
the Maximum Segment Size.

Signed-off-by: Shizhao Liu <[email protected]>
  • Loading branch information
Shizhao Liu committed Apr 21, 2023
1 parent 0fe633a commit 515cf3e
Show file tree
Hide file tree
Showing 19 changed files with 2,268 additions and 178 deletions.
44 changes: 10 additions & 34 deletions nsxt/data_source_nsxt_policy_ipsec_vpn_local_endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ package nsxt

import (
"fmt"
"strings"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/vmware/vsphere-automation-sdk-go/runtime/bindings"
Expand Down Expand Up @@ -36,42 +37,17 @@ func dataSourceNsxtPolicyIPSecVpnLocalEndpointRead(d *schema.ResourceData, m int
servicePath := d.Get("service_path").(string)
query := make(map[string]string)
if len(servicePath) > 0 {
// 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
s := strings.Split(servicePath, "/")
if len(s) != 8 && len(s) != 6 {
// The policy path of IPSec VPN Service should be like /infra/tier-0s/aaa/locale-services/bbb/ipsec-vpn-services/ccc
// or /infra/tier-0s/aaa/ipsec-vpn-services/bbb
return fmt.Errorf("Invalid IPSec Vpn Service path: %s", servicePath)
}
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
if len(s) == 8 {
// search API does not recognized the locale-services part in the VPN service path
servicePath = strings.Join(append(s[:4], s[6:]...), "/")
}

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)
query["parent_path"] = fmt.Sprintf("%s*", servicePath)
}
objInt, err := policyDataSourceResourceReadWithValidation(d, connector, isPolicyGlobalManager(m), "IPSecVpnLocalEndpoint", query, false)
if err != nil {
Expand Down
119 changes: 101 additions & 18 deletions nsxt/resource_nsxt_policy_ipsec_vpn_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
"github.com/vmware/vsphere-automation-sdk-go/runtime/protocol/client"
"github.com/vmware/vsphere-automation-sdk-go/services/nsxt/infra/tier_0s"
t0_locale_service "github.com/vmware/vsphere-automation-sdk-go/services/nsxt/infra/tier_0s/locale_services"
"github.com/vmware/vsphere-automation-sdk-go/services/nsxt/infra/tier_1s"
t1_locale_service "github.com/vmware/vsphere-automation-sdk-go/services/nsxt/infra/tier_1s/locale_services"
"github.com/vmware/vsphere-automation-sdk-go/services/nsxt/model"
)
Expand All @@ -35,13 +37,21 @@ func resourceNsxtPolicyIPSecVpnService() *schema.Resource {
},

Schema: map[string]*schema.Schema{
"nsx_id": getNsxIDSchema(),
"path": getPathSchema(),
"display_name": getDisplayNameSchema(),
"description": getDescriptionSchema(),
"revision": getRevisionSchema(),
"tag": getTagsSchema(),
"locale_service_path": getPolicyPathSchema(true, false, "Polciy path for the locale service."),
"nsx_id": getNsxIDSchema(),
"path": getPathSchema(),
"display_name": getDisplayNameSchema(),
"description": getDescriptionSchema(),
"revision": getRevisionSchema(),
"tag": getTagsSchema(),
"gateway_path": getPolicyPathSchema(false, true, "Policy path for the gateway."),
"locale_service_path": {
Type: schema.TypeString,
Description: "Polciy path for the locale service.",
Optional: true,
ForceNew: true,
Deprecated: "Use gateway_path instead.",
ValidateFunc: validatePolicyPath(),
},
"enabled": {
Type: schema.TypeBool,
Description: "Enable/Disable IPSec VPN service.",
Expand All @@ -67,6 +77,14 @@ func resourceNsxtPolicyIPSecVpnService() *schema.Resource {
}

func getNsxtPolicyIPSecVpnServiceByID(connector client.Connector, gwID string, isT0 bool, localeServiceID string, serviceID string, isGlobalManager bool) (model.IPSecVpnService, error) {
if localeServiceID == "" {
if isT0 {
client := tier_0s.NewIpsecVpnServicesClient(connector)
return client.Get(gwID, serviceID)
}
client := tier_1s.NewIpsecVpnServicesClient(connector)
return client.Get(gwID, serviceID)
}
if isT0 {
client := t0_locale_service.NewIpsecVpnServicesClient(connector)
return client.Get(gwID, localeServiceID, serviceID)
Expand All @@ -77,6 +95,14 @@ func getNsxtPolicyIPSecVpnServiceByID(connector client.Connector, gwID string, i

func patchNsxtPolicyIPSecVpnService(connector client.Connector, gwID string, localeServiceID string, ipSecVpnService model.IPSecVpnService, isT0 bool) error {
id := *ipSecVpnService.Id
if localeServiceID == "" {
if isT0 {
client := tier_0s.NewIpsecVpnServicesClient(connector)
return client.Patch(gwID, id, ipSecVpnService)
}
client := tier_1s.NewIpsecVpnServicesClient(connector)
return client.Patch(gwID, id, ipSecVpnService)
}
if isT0 {
client := t0_locale_service.NewIpsecVpnServicesClient(connector)
return client.Patch(gwID, localeServiceID, id, ipSecVpnService)
Expand All @@ -87,6 +113,16 @@ func patchNsxtPolicyIPSecVpnService(connector client.Connector, gwID string, loc

func updateNsxtPolicyIPSecVpnService(connector client.Connector, gwID string, localeServiceID string, ipSecVpnService model.IPSecVpnService, isT0 bool) error {
id := *ipSecVpnService.Id
if localeServiceID == "" {
if isT0 {
client := tier_0s.NewIpsecVpnServicesClient(connector)
_, err := client.Update(gwID, id, ipSecVpnService)
return err
}
client := tier_1s.NewIpsecVpnServicesClient(connector)
_, err := client.Update(gwID, id, ipSecVpnService)
return err
}
if isT0 {
client := t0_locale_service.NewIpsecVpnServicesClient(connector)
_, err := client.Update(gwID, localeServiceID, id, ipSecVpnService)
Expand All @@ -102,19 +138,33 @@ func resourceNsxtPolicyIPSecVpnServiceImport(d *schema.ResourceData, m interface
s := strings.Split(importID, "/")
err := fmt.Errorf("Expected policy path for the IPSec VPN Service, got %s", importID)
// The policy path of IPSec VPN Service should be like /infra/tier-0s/aaa/locale-services/bbb/ipsec-vpn-services/ccc
if len(s) != 8 {
// or /infra/tier-0s/aaa/ipsec-vpn-services/bbb
if len(s) != 8 && len(s) != 6 {
return nil, err
}
d.SetId(s[7])
useLocaleService := len(s) == 8
d.SetId(s[len(s)-1])
s = strings.Split(importID, "/ipsec-vpn-services/")
if len(s) != 2 {
return []*schema.ResourceData{d}, err
}
d.Set("locale_service_path", s[0])
if useLocaleService {
d.Set("locale_service_path", s[0])
} else {
d.Set("gateway_path", s[0])
}
return []*schema.ResourceData{d}, nil
}

func deleteNsxtPolicyIPSecVpnService(connector client.Connector, gwID string, localeServiceID string, isT0 bool, id string) error {
if localeServiceID == "" {
if isT0 {
client := tier_0s.NewIpsecVpnServicesClient(connector)
return client.Delete(gwID, id)
}
client := tier_1s.NewIpsecVpnServicesClient(connector)
return client.Delete(gwID, id)
}
if isT0 {
client := t0_locale_service.NewIpsecVpnServicesClient(connector)
return client.Delete(gwID, localeServiceID, id)
Expand Down Expand Up @@ -196,18 +246,33 @@ func getIPSecVPNBypassRulesFromSchema(d *schema.ResourceData) []model.IPSecVpnRu
return nil
}

func getLocaleServiceAndGatewayPath(d *schema.ResourceData) (string, string, error) {
gatewayPath := d.Get("gateway_path").(string)
localeServicePath := d.Get("locale_service_path").(string)
if gatewayPath == "" && localeServicePath == "" {
return "", "", fmt.Errorf("At least one of gateway path and locale service path should be provided for VPN resources")
}
return gatewayPath, localeServicePath, nil
}

func resourceNsxtPolicyIPSecVpnServiceRead(d *schema.ResourceData, m interface{}) error {
connector := getPolicyConnector(m)

id := d.Id()
if id == "" {
return fmt.Errorf("Error obtaining IPSecVpnService ID")
}
localeServicePath := d.Get("locale_service_path").(string)
isT0, gwID, localeServiceID, err := parseLocaleServicePolicyPath(localeServicePath)
gatewayPath, localeServicePath, err := getLocaleServiceAndGatewayPath(d)
if err != nil {
return nil
}
isT0, gwID, localeServiceID, err := parseLocaleServicePolicyPath(localeServicePath)
if err != nil && gatewayPath == "" {
return err
}
if localeServiceID == "" {
isT0, gwID = parseGatewayPolicyPath(gatewayPath)
}
obj, err := getNsxtPolicyIPSecVpnServiceByID(connector, gwID, isT0, localeServiceID, id, isPolicyGlobalManager(m))
if err != nil {
return handleReadError(d, "IPSecVpnService", id, err)
Expand All @@ -229,11 +294,17 @@ func resourceNsxtPolicyIPSecVpnServiceRead(d *schema.ResourceData, m interface{}

func resourceNsxtPolicyIPSecVpnServiceCreate(d *schema.ResourceData, m interface{}) error {
connector := getPolicyConnector(m)
localeServicePath := d.Get("locale_service_path").(string)
isT0, gwID, localeServiceID, err := parseLocaleServicePolicyPath(localeServicePath)
gatewayPath, localeServicePath, err := getLocaleServiceAndGatewayPath(d)
if err != nil {
return nil
}
isT0, gwID, localeServiceID, err := parseLocaleServicePolicyPath(localeServicePath)
if err != nil && gatewayPath == "" {
return err
}
if localeServiceID == "" {
isT0, gwID = parseGatewayPolicyPath(gatewayPath)
}
isGlobalManager := isPolicyGlobalManager(m)
id := d.Get("nsx_id").(string)
if id == "" {
Expand Down Expand Up @@ -285,11 +356,17 @@ func resourceNsxtPolicyIPSecVpnServiceUpdate(d *schema.ResourceData, m interface
if id == "" {
return fmt.Errorf("Error obtaining IPSec VPN Service ID")
}
localeServicePath := d.Get("locale_service_path").(string)
isT0, gwID, localeServiceID, err := parseLocaleServicePolicyPath(localeServicePath)
gatewayPath, localeServicePath, err := getLocaleServiceAndGatewayPath(d)
if err != nil {
return nil
}
isT0, gwID, localeServiceID, err := parseLocaleServicePolicyPath(localeServicePath)
if err != nil && gatewayPath == "" {
return err
}
if localeServiceID == "" {
isT0, gwID = parseGatewayPolicyPath(gatewayPath)
}

displayName := d.Get("display_name").(string)
description := d.Get("description").(string)
Expand Down Expand Up @@ -329,11 +406,17 @@ func resourceNsxtPolicyIPSecVpnServiceDelete(d *schema.ResourceData, m interface
return fmt.Errorf("Error obtaining IPSec VPN Service ID")
}

localeServicePath := d.Get("locale_service_path").(string)
isT0, gwID, localeServiceID, err := parseLocaleServicePolicyPath(localeServicePath)
gatewayPath, localeServicePath, err := getLocaleServiceAndGatewayPath(d)
if err != nil {
return nil
}
isT0, gwID, localeServiceID, err := parseLocaleServicePolicyPath(localeServicePath)
if err != nil && gatewayPath == "" {
return err
}
if localeServiceID == "" {
isT0, gwID = parseGatewayPolicyPath(gatewayPath)
}

err = deleteNsxtPolicyIPSecVpnService(getPolicyConnector(m), gwID, localeServiceID, isT0, id)
if err != nil {
Expand Down
Loading

0 comments on commit 515cf3e

Please sign in to comment.