Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add discover node data source #1084

Merged
merged 1 commit into from
Jan 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions nsxt/data_source_discover_node.go
Original file line number Diff line number Diff line change
@@ -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)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel pagination might be required here for big deployments?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe I misunderstood something. Can multiple Nodes share the same IP address? I expect only one or none(NotFound) Node will be returned.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My bad, I didn't realize the List has IP filter already in the call

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
}
1 change: 1 addition & 0 deletions nsxt/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{
Expand Down
100 changes: 3 additions & 97 deletions nsxt/resource_nsxt_policy_host_transport_node.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
}

Expand Down Expand Up @@ -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)
Expand All @@ -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 {
Expand All @@ -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,
}
Expand Down
23 changes: 23 additions & 0 deletions website/docs/d/discover_node.html.markdown
Original file line number Diff line number Diff line change
@@ -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.
40 changes: 15 additions & 25 deletions website/docs/r/policy_host_transport_node.html.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
}

Expand All @@ -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'.
Expand Down