Skip to content

Commit

Permalink
Implement edge cluster resource
Browse files Browse the repository at this point in the history
Signed-off-by: Kobi Samoray <[email protected]>
  • Loading branch information
ksamoray committed Jul 13, 2023
1 parent e9d63f8 commit e5a9462
Show file tree
Hide file tree
Showing 110 changed files with 29,308 additions and 0 deletions.
1 change: 1 addition & 0 deletions nsxt/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,7 @@ func Provider() *schema.Provider {
"nsxt_policy_spoof_guard_profile": resourceNsxtPolicySpoofGuardProfile(),
"nsxt_policy_gateway_qos_profile": resourceNsxtPolicyGatewayQosProfile(),
"nsxt_policy_project": resourceNsxtPolicyProject(),
"nsxt_edge_cluster": resourceNsxtEdgeCluster(),
},

ConfigureFunc: providerConfigure,
Expand Down
291 changes: 291 additions & 0 deletions nsxt/resource_nsxt_edge_cluster.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,291 @@
/* Copyright © 2023 VMware, Inc. All Rights Reserved.
SPDX-License-Identifier: MPL-2.0 */

package nsxt

import (
"fmt"
"log"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/vmware/vsphere-automation-sdk-go/services/nsxt-mp/nsx"
"github.com/vmware/vsphere-automation-sdk-go/services/nsxt-mp/nsx/model"
)

var deploymentTypeValues = []string{
model.EdgeCluster_DEPLOYMENT_TYPE_VIRTUAL_MACHINE,
model.EdgeCluster_DEPLOYMENT_TYPE_PHYSICAL_MACHINE,
model.EdgeCluster_DEPLOYMENT_TYPE_UNKNOWN,
}

var memberNodeTypeValues = []string{
model.EdgeCluster_MEMBER_NODE_TYPE_EDGE_NODE,
model.EdgeCluster_MEMBER_NODE_TYPE_PUBLIC_CLOUD_GATEWAY_NODE,
model.EdgeCluster_MEMBER_NODE_TYPE_UNKNOWN,
}

func resourceNsxtEdgeCluster() *schema.Resource {
return &schema.Resource{
Create: resourceNsxtEdgeClusterCreate,
Read: resourceNsxtEdgeClusterRead,
Update: resourceNsxtEdgeClusterUpdate,
Delete: resourceNsxtEdgeClusterDelete,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Schema: map[string]*schema.Schema{
"revision": getRevisionSchema(),
"description": getDescriptionSchema(),
"display_name": getDisplayNameSchema(),
"tag": getTagsSchema(),
"cluster_profile_ids": {
Type: schema.TypeList,
Description: "Edge cluster profile Ids",
Optional: true,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"deployment_type": {
Type: schema.TypeString,
Description: "Edge cluster deployment type",
Computed: true,
},
"enable_inter_site_forwarding": {
Type: schema.TypeBool,
Description: "Flag to enable inter site forwarding",
Optional: true,
Computed: true,
},
"member_node_type": {
Type: schema.TypeString,
Description: "Node type of the cluster members",
Computed: true,
},
"member": {
Type: schema.TypeList,
Description: "Edge cluster members",
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"description": {
Type: schema.TypeString,
Description: "Description of this resource",
Optional: true,
},
"display_name": {
Type: schema.TypeString,
Description: "The display name of this resource. Defaults to ID if not set",
Optional: true,
Computed: true,
},
"member_index": {
Type: schema.TypeInt,
Description: "System generated index for cluster member",
Computed: true,
},
"transport_node_id": {
Type: schema.TypeString,
Description: "UUID of edge transport node",
Required: true,
},
},
},
},
"node_rtep_ips": {
Type: schema.TypeList,
Description: "Remote tunnel endpoint ip address",
Optional: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"member_index": {
Type: schema.TypeInt,
Description: "System generated index for cluster member",
Computed: true,
},
"rtep_ips": {
Type: schema.TypeList,
Description: "Remote tunnel endpoint ip address",
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeString,
ValidateFunc: validateSingleIP(),
},
},
"transport_node_id": {
Type: schema.TypeString,
Description: "UUID of edge transport node",
Computed: true,
},
},
},
},
},
}
}

func resourceNsxtEdgeClusterCreate(d *schema.ResourceData, m interface{}) error {
connector := getPolicyConnector(m)
client := nsx.NewEdgeClustersClient(connector)

description := d.Get("description").(string)
displayName := d.Get("display_name").(string)
tags := getMPTagsFromSchema(d)

clusterProfileBindingList := getStringListFromSchemaList(d, "cluster_profile_ids")
var clusterProfileBindings []model.ClusterProfileTypeIdEntry
for i := range clusterProfileBindingList {
elem := model.ClusterProfileTypeIdEntry{
ProfileId: &clusterProfileBindingList[i],
}
clusterProfileBindings = append(clusterProfileBindings, elem)
}
enableInterSiteForwarding := d.Get("enable_inter_site_forwarding").(bool)
members := getEdgeClusterMembersFromSchema(d)
obj := model.EdgeCluster{
Description: &description,
DisplayName: &displayName,
Tags: tags,
ClusterProfileBindings: clusterProfileBindings,
EnableInterSiteForwarding: &enableInterSiteForwarding,
Members: members,
}

obj, err := client.Create(obj)
if err != nil {
id := ""
if obj.Id != nil {
id = *obj.Id
}
return handleCreateError("Edge Cluster", id, err)
}

log.Printf("[INFO] Creating Edge Cluster with ID %s", *obj.Id)

d.SetId(*obj.Id)
return resourceNsxtEdgeClusterRead(d, m)
}

func getEdgeClusterMembersFromSchema(d *schema.ResourceData) []model.EdgeClusterMember {
memberList := d.Get("member").([]interface{})
var members []model.EdgeClusterMember
for _, member := range memberList {
data := member.(map[string]interface{})
description := data["description"].(string)
displayName := data["display_name"].(string)
memberIndex := data["member_index"].(int64)
transportNodeID := data["transport_node_id"].(string)
elem := model.EdgeClusterMember{
Description: &description,
DisplayName: &displayName,
MemberIndex: &memberIndex,
TransportNodeId: &transportNodeID,
}
members = append(members, elem)
}
return members
}

func resourceNsxtEdgeClusterRead(d *schema.ResourceData, m interface{}) error {
connector := getPolicyConnector(m)
id := d.Id()
if id == "" {
return fmt.Errorf("error obtaining logical object id")
}

client := nsx.NewEdgeClustersClient(connector)
obj, err := client.Get(id)
if err != nil {
return fmt.Errorf("error during Edge Cluster read: %v", err)
}

d.Set("revision", obj.Revision)
d.Set("description", obj.Description)
d.Set("display_name", obj.DisplayName)
setMPTagsInSchema(d, obj.Tags)

var clusterProfileIds []string
for _, cpb := range obj.ClusterProfileBindings {
clusterProfileIds = append(clusterProfileIds, *cpb.ProfileId)
}
d.Set("cluster_profile_ids", clusterProfileIds)
d.Set("deployment_type", obj.DeploymentType)
d.Set("enable_inter_site_forwarding", obj.EnableInterSiteForwarding)
d.Set("member_node_type", obj.MemberNodeType)
setMemberListInSchema(d, obj.Members)
setNodeRtepIPsInSchema(d, obj.NodeRtepIps)
return nil
}

func setNodeRtepIPsInSchema(d *schema.ResourceData, nodeRtepIPs []model.NodeRtepIpsConfig) error {
var expresionList []map[string]interface{}
for _, rtepIP := range nodeRtepIPs {
elem := make(map[string]interface{})
elem["member_index"] = rtepIP.MemberIndex
elem["rtep_ips"] = rtepIP.RtepIps
elem["transport_node_id"] = rtepIP.TransportNodeId
expresionList = append(expresionList, elem)
}
return d.Set("node_rtep_ips", expresionList)
}

func setMemberListInSchema(d *schema.ResourceData, members []model.EdgeClusterMember) error {
var expresionList []map[string]interface{}
for _, member := range members {
elem := make(map[string]interface{})
elem["description"] = member.Description
elem["display_name"] = member.DisplayName
elem["member_index"] = member.MemberIndex
elem["transport_node_id"] = member.TransportNodeId
expresionList = append(expresionList, elem)
}
return d.Set("member", expresionList)
}

func resourceNsxtEdgeClusterUpdate(d *schema.ResourceData, m interface{}) error {
connector := getPolicyConnector(m)
id := d.Id()
if id == "" {
return fmt.Errorf("error obtaining logical object id")
}

client := nsx.NewEdgeClustersClient(connector)

revision := int64(d.Get("revision").(int))
description := d.Get("description").(string)
displayName := d.Get("display_name").(string)
tags := getMPTagsFromSchema(d)
members := getEdgeClusterMembersFromSchema(d)
obj := model.EdgeCluster{
Revision: &revision,
Description: &description,
DisplayName: &displayName,
Tags: tags,
Members: members,
}

_, err := client.Update(id, obj)
if err != nil {
return fmt.Errorf("error during Edge Cluster %s update: %v", id, err)
}

return resourceNsxtEdgeClusterRead(d, m)
}

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

id := d.Id()
if id == "" {
return fmt.Errorf("error obtaining logical object id")
}

client := nsx.NewEdgeClustersClient(connector)

err := client.Delete(id)
if err != nil {
return fmt.Errorf("error during Edge Cluster delete: %v", err)
}
return nil
}
Loading

0 comments on commit e5a9462

Please sign in to comment.