diff --git a/nsxt/data_source_nsxt_transport_node.go b/nsxt/data_source_nsxt_transport_node.go new file mode 100644 index 000000000..5e3fcb6bd --- /dev/null +++ b/nsxt/data_source_nsxt_transport_node.go @@ -0,0 +1,100 @@ +/* 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 dataSourceNsxtTransportNode() *schema.Resource { + return &schema.Resource{ + Read: dataSourceNsxtTransportNodeRead, + + Schema: map[string]*schema.Schema{ + "id": getDataSourceIDSchema(), + "display_name": getDataSourceExtendedDisplayNameSchema(), + "description": getDescriptionSchema(), + "node_type": { + Type: schema.TypeString, + Description: "Type of NSX transport node", + Optional: true, + Computed: true, + }, + }, + } +} + +func dataSourceNsxtTransportNodeRead(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) + } + obj = objGet + } else { + // Get by full name/prefix + objList, err := client.List(nil, nil, nil, nil, nil, nil, 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) + + converter := bindings.NewTypeConverter() + base, errs := converter.ConvertToGolang(obj.NodeDeploymentInfo, model.NodeBindingType()) + if errs != nil { + return errs[0] + } + node := base.(model.Node) + + d.Set("node_type", node.ResourceType) + + return nil +} diff --git a/nsxt/data_source_nsxt_transport_node_test.go b/nsxt/data_source_nsxt_transport_node_test.go new file mode 100644 index 000000000..979de6892 --- /dev/null +++ b/nsxt/data_source_nsxt_transport_node_test.go @@ -0,0 +1,42 @@ +/* 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 TestAccDataSourceNsxtTransportNode_basic(t *testing.T) { + htnName := getHostTransportNodeName() + testResourceName := "data.nsxt_transport_node.test" + + resource.ParallelTest(t, resource.TestCase{ + PreCheck: func() { + testAccOnlyLocalManager(t) + testAccPreCheck(t) + testAccEnvDefined(t, "NSXT_TEST_HOST_TRANSPORT_NODE") + }, + Providers: testAccProviders, + Steps: []resource.TestStep{ + { + Config: testAccNSXTransportNodeReadTemplate(htnName), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr(testResourceName, "display_name", htnName), + resource.TestCheckResourceAttrSet(testResourceName, "id"), + resource.TestCheckResourceAttrSet(testResourceName, "node_type"), + ), + }, + }, + }) +} + +func testAccNSXTransportNodeReadTemplate(name string) string { + return fmt.Sprintf(` +data "nsxt_transport_node" "test" { + display_name = "%s" +}`, name) +} diff --git a/nsxt/provider.go b/nsxt/provider.go index d740a2050..3de94d7cb 100644 --- a/nsxt/provider.go +++ b/nsxt/provider.go @@ -292,6 +292,7 @@ func Provider() *schema.Provider { "nsxt_compute_collection": dataSourceNsxtComputeCollection(), "nsxt_compute_manager_realization": dataSourceNsxtComputeManagerRealization(), "nsxt_policy_host_transport_node": dataSourceNsxtPolicyHostTransportNode(), + "nsxt_transport_node": dataSourceNsxtTransportNode(), }, ResourcesMap: map[string]*schema.Resource{ diff --git a/website/docs/d/transport_node.html.markdown b/website/docs/d/transport_node.html.markdown new file mode 100644 index 000000000..ea91a907a --- /dev/null +++ b/website/docs/d/transport_node.html.markdown @@ -0,0 +1,30 @@ +--- +subcategory: "Beta" +layout: "nsxt" +page_title: "NSXT: transport_node" +description: A Transport Node data source. +--- + +# nsxt_transport_node + +This data source provides information about a Transport Node configured on NSX. + +## Example Usage + +```hcl +data "nsxt_transport_node" "test_node" { + display_name = "edgenode1" +} +``` + +## Argument Reference + +* `id` - (Optional) The ID of Transport Node to retrieve +* `display_name` - (Optional) The Display Name of the Transport Node to retrieve. + +## Attributes Reference + +In addition to arguments listed above, the following attributes are exported: + +* `description` - The description of the resource. +* `node_type` - The type of the transport node. One of: 'HostNode', 'EdgeNode' or 'PublicCloudGatewayNode'. \ No newline at end of file