diff --git a/nsxt/data_source_nsxt_edge_transport_node.go b/nsxt/data_source_nsxt_edge_transport_node.go new file mode 100644 index 000000000..75d364976 --- /dev/null +++ b/nsxt/data_source_nsxt_edge_transport_node.go @@ -0,0 +1,97 @@ +/* Copyright © 2023 VMware, Inc. All Rights Reserved. + SPDX-License-Identifier: MPL-2.0 */ + +package nsxt + +import ( + "fmt" + "strings" + + "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-mp/nsx" + "github.com/vmware/vsphere-automation-sdk-go/services/nsxt-mp/nsx/model" +) + +func dataSourceNsxtEdgeTransportNode() *schema.Resource { + return &schema.Resource{ + Read: dataSourceNsxtEdgeTransportNodeRead, + + Schema: map[string]*schema.Schema{ + "id": getDataSourceIDSchema(), + "display_name": getDataSourceExtendedDisplayNameSchema(), + "description": getDescriptionSchema(), + }, + } +} + +func dataSourceNsxtEdgeTransportNodeRead(d *schema.ResourceData, m interface{}) error { + connector := getPolicyConnector(m) + client := nsx.NewTransportNodesClient(connector) + + objID := d.Get("id").(string) + objName := d.Get("display_name").(string) + + var obj model.TransportNode + + if objID != "" { + // Get by id + objGet, err := client.Get(objID) + if err != nil { + return fmt.Errorf("failed to read TransportNode %s: %v", objID, err) + } + + // Make sure that found obj is an EdgeNode + converter := bindings.NewTypeConverter() + base, errs := converter.ConvertToGolang(obj.NodeDeploymentInfo, model.NodeBindingType()) + if errs != nil { + return fmt.Errorf("failed to convert NodeDeploymentInfo for node %s %v", objID, errs[0]) + } + node := base.(model.Node) + if node.ResourceType != model.EdgeNode__TYPE_IDENTIFIER { + return fmt.Errorf("no Transport Node matches the criteria") + } + obj = objGet + } else { + // Get by full name/prefix - filter out anything except EdgeNodes + objType := model.EdgeNode__TYPE_IDENTIFIER + objList, err := client.List(nil, nil, nil, nil, nil, &objType, nil, nil, nil, nil) + if err != nil { + return fmt.Errorf("failed to read Transport Nodes: %v", err) + } + // go over the list to find the correct one (prefer a perfect match. If not - prefix match) + var perfectMatch []model.TransportNode + var prefixMatch []model.TransportNode + for _, objInList := range objList.Results { + if len(objName) == 0 { + // We want to grab single Transport Node + perfectMatch = append(perfectMatch, objInList) + continue + } + if strings.HasPrefix(*objInList.DisplayName, objName) { + prefixMatch = append(prefixMatch, objInList) + } + if *objInList.DisplayName == objName { + perfectMatch = append(perfectMatch, objInList) + } + } + if len(perfectMatch) > 0 { + if len(perfectMatch) > 1 { + return fmt.Errorf("found multiple Transport Nodes matching the criteria") + } + obj = perfectMatch[0] + } else if len(prefixMatch) > 0 { + if len(prefixMatch) > 1 { + return fmt.Errorf("found multiple Transport Nodes matching the criteria") + } + obj = prefixMatch[0] + } else { + return fmt.Errorf("no Transport Node matches the criteria") + } + } + d.SetId(*obj.Id) + d.Set("display_name", obj.DisplayName) + d.Set("description", obj.Description) + + return nil +} diff --git a/nsxt/data_source_nsxt_edge_transport_node_test.go b/nsxt/data_source_nsxt_edge_transport_node_test.go new file mode 100644 index 000000000..558069dd9 --- /dev/null +++ b/nsxt/data_source_nsxt_edge_transport_node_test.go @@ -0,0 +1,41 @@ +/* Copyright © 2023 VMware, Inc. All Rights Reserved. + SPDX-License-Identifier: MPL-2.0 */ + +package nsxt + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" +) + +func TestAccDataSourceNsxtEdgeTransportNode_basic(t *testing.T) { + htnName := getEdgeTransportNodeName() + testResourceName := "data.nsxt_edge_transport_node.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + testAccOnlyLocalManager(t) + testAccPreCheck(t) + testAccEnvDefined(t, "NSXT_TEST_EDGE_TRANSPORT_NODE") + }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccNSXEdgeTransportNodeReadTemplate(htnName), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(testResourceName, "display_name", htnName), + resource.TestCheckResourceAttrSet(testResourceName, "id"), + ), + }, + }, + }) +} + +func testAccNSXEdgeTransportNodeReadTemplate(name string) string { + return fmt.Sprintf(` +data "nsxt_edge_transport_node" "test" { + display_name = "%s" +}`, name) +} diff --git a/nsxt/provider.go b/nsxt/provider.go index 2200d860f..a762a42a6 100644 --- a/nsxt/provider.go +++ b/nsxt/provider.go @@ -294,6 +294,7 @@ func Provider() *schema.Provider { "nsxt_policy_host_transport_node": dataSourceNsxtPolicyHostTransportNode(), "nsxt_manager_cluster_node": dataSourceNsxtManagerClusterNode(), "nsxt_policy_host_transport_node_profile": dataSourceNsxtPolicyHostTransportNodeProfile(), + "nsxt_transport_node": dataSourceNsxtEdgeTransportNode(), }, ResourcesMap: map[string]*schema.Resource{ diff --git a/nsxt/utils_test.go b/nsxt/utils_test.go index ec2558be3..e3f6977eb 100644 --- a/nsxt/utils_test.go +++ b/nsxt/utils_test.go @@ -143,6 +143,10 @@ func getHostTransportNodeProfileName() string { return os.Getenv("NSXT_TEST_HOST_TRANSPORT_NODE_PROFILE") } +func getEdgeTransportNodeName() string { + return os.Getenv("NSXT_TEST_EDGE_TRANSPORT_NODE") +} + func getVlanTransportZoneName() string { name := os.Getenv("NSXT_TEST_VLAN_TRANSPORT_ZONE") if name == "" { diff --git a/website/docs/d/edge_transport_node.html.markdown b/website/docs/d/edge_transport_node.html.markdown new file mode 100644 index 000000000..20dd6b922 --- /dev/null +++ b/website/docs/d/edge_transport_node.html.markdown @@ -0,0 +1,29 @@ +--- +subcategory: "Beta" +layout: "nsxt" +page_title: "NSXT: edge_transport_node" +description: An Edge Transport Node data source. +--- + +# nsxt_edge_transport_node + +This data source provides information about an Edge Transport Node configured on NSX. + +## Example Usage + +```hcl +data "nsxt_edge_transport_node" "test_node" { + display_name = "edgenode1" +} +``` + +## Argument Reference + +* `id` - (Optional) The ID of Edge Transport Node to retrieve +* `display_name` - (Optional) The Display Name of the Edge Transport Node to retrieve. + +## Attributes Reference + +In addition to arguments listed above, the following attributes are exported: + +* `description` - The description of the resource.