From 1c614866be071350aa07f3de8f6563e69e26fdf7 Mon Sep 17 00:00:00 2001 From: GraysonWu Date: Fri, 19 Jan 2024 13:32:04 -0800 Subject: [PATCH] Add discover node data source (#1084) 1. Add Discover Node data source. 2. Remove node_deployment_info from Host Transport Node. Considering we only support Host Transport Node create from vCenter server managing the ESXi type HostNode and in this case, discovered_node_id is required, so no need to provide node_deployment_info. Additionally, this could fix the issue that using node_deployment_info with VDS type host switch, which is the only host switch type supported, will receive error from NSX: ``` Failed to create HostTransportNode 9756979d-0165-4cc6-93dc-0c30bb6da065: VDS Configuration is specified for host 9756979d-0165-4cc6-93dc-0c30bb6da065 and its not managed by a vCenter. Please correct TransportNode configuration or connect the host to a VCenter. (code 9549) ``` Signed-off-by: graysonwu --- nsxt/data_source_discover_node.go | 70 ++++++++++++ nsxt/provider.go | 1 + ...esource_nsxt_policy_host_transport_node.go | 100 +----------------- website/docs/d/discover_node.html.markdown | 23 ++++ .../policy_host_transport_node.html.markdown | 40 +++---- 5 files changed, 112 insertions(+), 122 deletions(-) create mode 100644 nsxt/data_source_discover_node.go create mode 100644 website/docs/d/discover_node.html.markdown diff --git a/nsxt/data_source_discover_node.go b/nsxt/data_source_discover_node.go new file mode 100644 index 000000000..996de0080 --- /dev/null +++ b/nsxt/data_source_discover_node.go @@ -0,0 +1,70 @@ +/* Copyright © 2024 VMware, Inc. All Rights Reserved. + SPDX-License-Identifier: MPL-2.0 */ + +package nsxt + +import ( + "fmt" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/vmware/vsphere-automation-sdk-go/services/nsxt-mp/nsx/fabric" + "github.com/vmware/vsphere-automation-sdk-go/services/nsxt-mp/nsx/model" +) + +func dataSourceNsxtDiscoverNode() *schema.Resource { + return &schema.Resource{ + Read: dataSourceNsxtDiscoverNodeRead, + Schema: map[string]*schema.Schema{ + "id": { + Type: schema.TypeString, + Description: "External id of the discovered node, ex. a mo-ref from VC", + Optional: true, + Computed: true, + }, + "ip_address": { + Type: schema.TypeString, + Description: "IP Address of the the discovered node.", + Optional: true, + Computed: true, + ValidateFunc: validateCidrOrIPOrRange(), + }, + }, + } +} + +func dataSourceNsxtDiscoverNodeRead(d *schema.ResourceData, m interface{}) error { + connector := getPolicyConnector(m) + discoverNodeClient := fabric.NewDiscoveredNodesClient(connector) + + objID := d.Get("id").(string) + ipAddress := d.Get("ip_address").(string) + + var obj model.DiscoveredNode + if objID != "" { + // Get by ID + objGet, err := discoverNodeClient.Get(objID) + if isNotFoundError(err) { + return fmt.Errorf("Discover Node %s was not found", objID) + } + if err != nil { + return fmt.Errorf("Error while reading Discover Node %s: %v", objID, err) + } + obj = objGet + } else if ipAddress == "" { + return fmt.Errorf("Error obtaining Discover Node external ID or IP address during read") + } else { + // Get by IP address + objList, err := discoverNodeClient.List(nil, nil, nil, nil, nil, nil, &ipAddress, nil, nil, nil, nil, nil, nil, nil) + if isNotFoundError(err) { + return fmt.Errorf("Discover Node with IP %s was not found", ipAddress) + } + if err != nil { + return fmt.Errorf("Error while reading Discover Node: %v", err) + } + obj = objList.Results[0] + } + + d.SetId(*obj.ExternalId) + d.Set("ip_address", obj.IpAddresses[0]) + return nil +} diff --git a/nsxt/provider.go b/nsxt/provider.go index d4bc77bf9..a85bdb6b0 100644 --- a/nsxt/provider.go +++ b/nsxt/provider.go @@ -295,6 +295,7 @@ func Provider() *schema.Provider { "nsxt_manager_cluster_node": dataSourceNsxtManagerClusterNode(), "nsxt_policy_host_transport_node_profile": dataSourceNsxtPolicyHostTransportNodeProfile(), "nsxt_transport_node": dataSourceNsxtEdgeTransportNode(), + "nsxt_discover_node": dataSourceNsxtDiscoverNode(), }, ResourcesMap: map[string]*schema.Resource{ diff --git a/nsxt/resource_nsxt_policy_host_transport_node.go b/nsxt/resource_nsxt_policy_host_transport_node.go index a9169f4f6..519a4b461 100644 --- a/nsxt/resource_nsxt_policy_host_transport_node.go +++ b/nsxt/resource_nsxt_policy_host_transport_node.go @@ -9,7 +9,6 @@ import ( "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" "github.com/vmware/vsphere-automation-sdk-go/runtime/protocol/client" - "github.com/vmware/vsphere-automation-sdk-go/services/nsxt-mp/nsx/model" "github.com/vmware/vsphere-automation-sdk-go/services/nsxt/infra" "github.com/vmware/vsphere-automation-sdk-go/services/nsxt/infra/sites/enforcement_points" model2 "github.com/vmware/vsphere-automation-sdk-go/services/nsxt/model" @@ -48,71 +47,16 @@ func resourceNsxtPolicyHostTransportNode() *schema.Resource { Default: "default", }, "discovered_node_id": { - Type: schema.TypeString, - Optional: true, - Description: "Discovered node id to create Host Transport Node", - ConflictsWith: []string{"node_deployment_info"}, + Type: schema.TypeString, + Required: true, + Description: "Discovered node id to create Host Transport Node", }, - "node_deployment_info": getFabricHostNodeSchema(), // host_switch_spec "standard_host_switch": getStandardHostSwitchSchema(nodeTypeHost), }, } } -func getFabricHostNodeSchema() *schema.Schema { - return &schema.Schema{ - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "fqdn": { - Type: schema.TypeString, - Computed: true, - Description: "Fully qualified domain name of the fabric node", - }, - "ip_addresses": { - Type: schema.TypeList, - Optional: true, - Computed: true, - Description: "IP Addresses of the Node, version 4 or 6", - Elem: &schema.Schema{ - Type: schema.TypeString, - ValidateFunc: validateSingleIP(), - }, - }, - "host_credential": { - Type: schema.TypeList, - MaxItems: 1, - Description: "Host login credentials", - Optional: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "password": { - Type: schema.TypeString, - Sensitive: true, - Required: true, - Description: "The authentication password of the host node", - }, - "thumbprint": { - Type: schema.TypeString, - Required: true, - Description: "ESXi thumbprint or SSH key fingerprint of the host node", - }, - "username": { - Type: schema.TypeString, - Required: true, - Description: "The username of the account on the host node", - }, - }, - }, - }, - }, - }, - } -} - func resourceNsxtPolicyHostTransportNodeRead(d *schema.ResourceData, m interface{}) error { connector := getPolicyConnector(m) htnClient := enforcement_points.NewHostTransportNodesClient(connector) @@ -145,13 +89,6 @@ func resourceNsxtPolicyHostTransportNodeRead(d *schema.ResourceData, m interface return err } - fabricHostNode := obj.NodeDeploymentInfo - elem := make(map[string]interface{}) - elem["fqdn"] = fabricHostNode.Fqdn - elem["ip_addresses"] = fabricHostNode.IpAddresses - - d.Set("node_deployment_info", []map[string]interface{}{elem}) - return nil } @@ -180,35 +117,6 @@ func resourceNsxtPolicyHostTransportNodeExists(siteID, epID, tzID string, connec return false, logAPIError("Error retrieving resource", err) } -func getFabricHostNodeFromSchema(d *schema.ResourceData) *model2.FabricHostNode { - for _, ni := range d.Get("node_deployment_info").([]interface{}) { - nodeInfo := ni.(map[string]interface{}) - ipAddresses := interfaceListToStringList(nodeInfo["ip_addresses"].([]interface{})) - - var hostCredential *model2.HostNodeLoginCredential - for _, hci := range nodeInfo["host_credential"].([]interface{}) { - hc := hci.(map[string]interface{}) - password := hc["password"].(string) - thumbprint := hc["thumbprint"].(string) - username := hc["username"].(string) - hostCredential = &model2.HostNodeLoginCredential{ - Password: &password, - Thumbprint: &thumbprint, - Username: &username, - } - } - osType := model.HostNode_OS_TYPE_ESXI - - fabricHostNode := model2.FabricHostNode{ - IpAddresses: ipAddresses, - HostCredential: hostCredential, - OsType: &osType, - } - return &fabricHostNode - } - return nil -} - func policyHostTransportNodePatch(siteID, epID, htnID string, d *schema.ResourceData, m interface{}) error { connector := getPolicyConnector(m) htnClient := enforcement_points.NewHostTransportNodesClient(connector) @@ -217,7 +125,6 @@ func policyHostTransportNodePatch(siteID, epID, htnID string, d *schema.Resource displayName := d.Get("display_name").(string) tags := getPolicyTagsFromSchema(d) discoveredNodeID := d.Get("discovered_node_id").(string) - nodeDeploymentInfo := getFabricHostNodeFromSchema(d) hostSwitchSpec, err := getHostSwitchSpecFromSchema(d, nodeTypeHost) revision := int64(d.Get("revision").(int)) if err != nil { @@ -229,7 +136,6 @@ func policyHostTransportNodePatch(siteID, epID, htnID string, d *schema.Resource DisplayName: &displayName, Tags: tags, HostSwitchSpec: hostSwitchSpec, - NodeDeploymentInfo: nodeDeploymentInfo, DiscoveredNodeIdForCreate: &discoveredNodeID, Revision: &revision, } diff --git a/website/docs/d/discover_node.html.markdown b/website/docs/d/discover_node.html.markdown new file mode 100644 index 000000000..460cc366e --- /dev/null +++ b/website/docs/d/discover_node.html.markdown @@ -0,0 +1,23 @@ +--- +subcategory: "Fabric" +layout: "nsxt" +page_title: "NSXT: discover_node" +description: An Discover Node data source. +--- + +# nsxt_discover_node + +This data source provides information about Discover Node configured in NSX. A Discover Node can be used to create a Host Transport Node. + +## Example Usage + +```hcl +data "nsxt_discover_node" "test" { + ip_address = "10.43.251.142" +} +``` + +## Argument Reference + +* `id` - (Optional) External id of the discovered node, ex. a mo-ref from VC. +* `ip_address` - (Optional) IP Address of the discovered node. diff --git a/website/docs/r/policy_host_transport_node.html.markdown b/website/docs/r/policy_host_transport_node.html.markdown index 9de14aeed..55ea584a7 100644 --- a/website/docs/r/policy_host_transport_node.html.markdown +++ b/website/docs/r/policy_host_transport_node.html.markdown @@ -14,33 +14,30 @@ This resource is supported with NSX 4.1.0 onwards. ```hcl resource "nsxt_policy_host_transport_node" "test" { - description = "Terraform-deployed host transport node" - display_name = "tf_host_transport_node" - - node_deployment_info { - ip_addresses = ["10.168.186.150"] - - host_credential { - username = "user1" - password = "password1" - thumbprint = "thumbprint1" - } - } + description = "Terraform-deployed host transport node" + display_name = "tf_host_transport_node" + discovered_node_id = data.nsxt_discover_node.dn.id standard_host_switch { - host_switch_profile = [data.nsxt_policy_uplink_host_switch_profile.hsw_profile1.path] + host_switch_id = "50 0b 31 a4 b8 af 35 df-40 56 b6 f9 aa d3 ee 12" + host_switch_profile = [data.nsxt_policy_uplink_host_switch_profile.uplink_host_switch_profile.path] ip_assignment { assigned_by_dhcp = true } transport_zone_endpoint { - transport_zone = data.nsxt_transport_zone.tz1.path + transport_zone = data.nsxt_policy_transport_zone.overlay_transport_zone.path + } + + uplink { + uplink_name = "uplink-1" + vds_uplink_name = "uplink1" } - pnic { - device_name = "fp-eth0" - uplink_name = "uplink1" + uplink { + uplink_name = "uplink-2" + vds_uplink_name = "uplink2" } } @@ -60,14 +57,7 @@ The following arguments are supported: * `tag` - (Optional) A list of scope + tag pairs to associate with this resource. * `site_path` - (Optional) The path of the site which the Host Transport Node belongs to. `path` field of the existing `nsxt_policy_site` can be used here. Defaults to default site path. * `enforcement_point` - (Optional) The ID of enforcement point under given `site_path` to manage the Host Transport Node. Defaults to default enforcement point. -* `discovered_node_id` - (Optional) Discovered node id to create Host Transport Node. Specify discovered node id to create Host Transport Node for Discovered Node. This field is required during Host Transport Node create from vCenter server managing the ESXi type HostNode. -* `node_deployment_info` - (Optional) - * `fqdn` - (Optional) Fully qualified domain name of the fabric node. - * `ip_addresses` - (Required) IP Addresses of the Node, version 4 or 6. - * `host_credential` - (Optional) Host login credentials. - * `password` - (Required) The authentication password of the host node. - * `thumbprint` - (Required) ESXi thumbprint or SSH key fingerprint of the host node. - * `username` - (Required) The username of the account on the host node. +* `discovered_node_id` - (Required) Discovered node id to create Host Transport Node. Specify discovered node id to create Host Transport Node for Discovered Node. This field is required during Host Transport Node create from vCenter server managing the ESXi type HostNode. * `standard_host_switch` - (Required) Standard host switch specification. * `host_switch_id` - (Optional) The host switch id. This ID will be used to reference a host switch. * `host_switch_mode` - (Optional) Operational mode of a HostSwitch. Accepted values - 'STANDARD', 'ENS', 'ENS_INTERRUPT' or 'LEGACY'. The default value is 'STANDARD'.