Skip to content

Commit

Permalink
Implement policy site resource
Browse files Browse the repository at this point in the history
Signed-off-by: Kobi Samoray <[email protected]>
  • Loading branch information
ksamoray committed Feb 13, 2024
1 parent 9e55291 commit bfc60f2
Show file tree
Hide file tree
Showing 3 changed files with 333 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 @@ -470,6 +470,7 @@ func Provider() *schema.Provider {
"nsxt_policy_lb_tcp_monitor_profile": resourceNsxtPolicyLBTcpMonitorProfile(),
"nsxt_policy_lb_udp_monitor_profile": resourceNsxtPolicyLBUdpMonitorProfile(),
"nsxt_policy_tier0_gateway_gre_tunnel": resourceNsxtPolicyTier0GatewayGRETunnel(),
"nsxt_policy_site": resourceNsxtPolicySite(),
},

ConfigureFunc: providerConfigure,
Expand Down
267 changes: 267 additions & 0 deletions nsxt/resource_nsxt_policy_site.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,267 @@
package nsxt

import (
"fmt"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
"github.com/vmware/vsphere-automation-sdk-go/runtime/protocol/client"
"github.com/vmware/vsphere-automation-sdk-go/services/nsxt-gm/global_infra"
gm_model "github.com/vmware/vsphere-automation-sdk-go/services/nsxt-gm/model"
)

var siteTypeValues = []string{
"ONPREM_LM",
"SDDC_LM",
}

func resourceNsxtPolicySite() *schema.Resource {
return &schema.Resource{
Create: resourceNsxtPolicySiteCreate,
Read: resourceNsxtPolicySiteRead,
Update: resourceNsxtPolicySiteUpdate,
Delete: resourceNsxtPolicySiteDelete,
Importer: &schema.ResourceImporter{
State: nsxtPolicyPathResourceImporter,
},

Schema: map[string]*schema.Schema{
"nsx_id": getNsxIDSchema(),
"path": getPathSchema(),
"display_name": getDisplayNameSchema(),
"description": getDescriptionSchema(),
"revision": getRevisionSchema(),
"tag": getTagsSchema(),
"fail_if_rtep_misconfigured": {
Type: schema.TypeBool,
Optional: true,
Description: "Fail onboarding if RTEPs misconfigured",
Default: true,
},
"fail_if_rtt_exceeded": {
Type: schema.TypeBool,
Optional: true,
Description: "Fail onboarding if maximum RTT exceeded",
Default: true,
},
"maximum_rtt": {
Type: schema.TypeInt,
Optional: true,
Description: "Maximum acceptable packet round trip time (RTT)",
Default: 250,
ValidateFunc: validation.IntBetween(0, 1000),
},
"site_connection_info": {
Type: schema.TypeList,
Optional: true,
Description: "Connection information",
MaxItems: 3,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"fqdn": {
Type: schema.TypeString,
Optional: true,
Description: "Fully Qualified Domain Name of the Management Node",
},
"password": {
Type: schema.TypeString,
Optional: true,
Sensitive: true,
Description: "Password",
},
"site_uuid": {
Type: schema.TypeString,
Optional: true,
Description: "id of Site",
},
"thumbprint": {
Type: schema.TypeString,
Optional: true,
Description: "Thumbprint of Enforcement Point",
},
"username": {
Type: schema.TypeString,
Optional: true,
Description: "Username",
},
},
},
},
"site_type": {
Type: schema.TypeString,
Optional: true,
Description: "Persistent Site Type",
ValidateFunc: validation.StringInSlice(siteTypeValues, false),
},
},
}
}

func getSiteFromSchema(d *schema.ResourceData) gm_model.Site {
displayName := d.Get("display_name").(string)
description := d.Get("description").(string)
var tags []gm_model.Tag
tagListIntface := d.Get("tag")
if tagListIntface != nil {
tagList := tagListIntface.(*schema.Set).List()
for _, t := range tagList {
elem := t.(map[string]interface{})
scope := elem["scope"].(string)
tag := elem["tag"].(string)
tags = append(tags, gm_model.Tag{Scope: &scope, Tag: &tag})
}
}
failIfRtepMisconfigured := d.Get("fail_if_rtep_misconfigured").(bool)
failIfRttExceeded := d.Get("fail_if_rtt_exceeded").(bool)
maximumRtt := int64(d.Get("maximum_rtt").(int))

var siteConnectionInfos []gm_model.SiteNodeConnectionInfo
siteConnectionInfoList := d.Get("site_connection_info").([]interface{})
for _, sci := range siteConnectionInfoList {
elem := sci.(map[string]interface{})
fqdn := elem["fqdn"].(string)
password := elem["password"].(string)
siteUUID := elem["site_uuid"].(string)
thumbprint := elem["thumbprint"].(string)
username := elem["username"].(string)

siteConnectionInfo := gm_model.SiteNodeConnectionInfo{
Fqdn: &fqdn,
Password: &password,
SiteUuid: &siteUUID,
Thumbprint: &thumbprint,
Username: &username,
}
siteConnectionInfos = append(siteConnectionInfos, siteConnectionInfo)
}
siteType := d.Get("site_type").(string)

return gm_model.Site{
DisplayName: &displayName,
Description: &description,
Tags: tags,
FailIfRtepMisconfigured: &failIfRtepMisconfigured,
FailIfRttExceeded: &failIfRttExceeded,
MaximumRtt: &maximumRtt,
SiteConnectionInfo: siteConnectionInfos,
SiteType: &siteType,
}
}

func resourceNsxtPolicySiteExists(id string, connector client.Connector, isGlobal bool) (bool, error) {
client := global_infra.NewSitesClient(connector)
_, err := client.Get(id)
if err == nil {
return true, nil
}

if isNotFoundError(err) {
return false, nil
}

return false, logAPIError("Error retrieving resource", err)
}

func resourceNsxtPolicySiteCreate(d *schema.ResourceData, m interface{}) error {
id, err := getOrGenerateID(d, m, resourceNsxtPolicySiteExists)
if err != nil {
return err
}

connector := getPolicyConnector(m)
client := global_infra.NewSitesClient(connector)
site := getSiteFromSchema(d)

err = client.Patch(id, site)
if err != nil {
return handleCreateError("Site", id, err)
}

d.SetId(id)
d.Set("nsx_id", id)

return resourceNsxtPolicySiteRead(d, m)
}

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

id := d.Id()
if id == "" {
return fmt.Errorf("error obtaining Site ID")
}
client := global_infra.NewSitesClient(connector)
obj, err := client.Get(id)
if err != nil {
return handleReadError(d, "Site", id, err)
}
d.Set("display_name", obj.DisplayName)
d.Set("description", obj.Description)
var tags []interface{}
for _, tag := range obj.Tags {
elem := make(map[string]interface{})
elem["scope"] = tag.Scope
elem["tag"] = tag.Tag
tags = append(tags, elem)
}
d.Set("nsx_id", id)
d.Set("path", obj.Path)
d.Set("revision", obj.Revision)
d.Set("realized_id", obj.RealizationId)

d.Set("fail_if_rtep_misconfigured", obj.FailIfRtepMisconfigured)
d.Set("fail_if_rtt_exceeded", obj.FailIfRttExceeded)
d.Set("maximum_rtt", obj.MaximumRtt)

var siteConnectionInfos []interface{}
for _, sci := range obj.SiteConnectionInfo {
elem := make(map[string]interface{})
elem["fqdn"] = sci.Fqdn
elem["password"] = sci.Password
elem["site_uuid"] = sci.SiteUuid
elem["thumbprint"] = sci.Thumbprint
elem["username"] = sci.Username

siteConnectionInfos = append(siteConnectionInfos, elem)
}
d.Set("site_connection_info", siteConnectionInfos)
d.Set("site_type", obj.SiteType)

return nil
}

func resourceNsxtPolicySiteUpdate(d *schema.ResourceData, m interface{}) error {
id := d.Id()
if id == "" {
return fmt.Errorf("Error obtaining Site ID")
}

connector := getPolicyConnector(m)
client := global_infra.NewSitesClient(connector)

obj := getSiteFromSchema(d)
revision := int64(d.Get("revision").(int))
obj.Revision = &revision

_, err := client.Update(id, obj)
if err != nil {
return handleUpdateError("Site", id, err)
}

return nil
}

func resourceNsxtPolicySiteDelete(d *schema.ResourceData, m interface{}) error {
id := d.Id()
if id == "" {
return fmt.Errorf("error obtaining Site ID")
}
connector := getPolicyConnector(m)
client := global_infra.NewSitesClient(connector)
err := client.Delete(id, nil)
if err != nil {
return handleDeleteError("Site", id, err)
}

return nil
}
65 changes: 65 additions & 0 deletions website/docs/r/policy_site.html.markdown
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
---
subcategory: "Beta"
layout: "nsxt"
page_title: "NSXT: nsxt_policy_site"
description: A resource to configure Policy Site.
---

# nsxt_policy_site

This resource provides a method for the management of Policy Site.

This resource is applicable to NSX Global Manager.

## Example Usage

```hcl
resource "nsxt_policy_site" "test" {
display_name = "test"
description = "Terraform provisioned Site"
site_connection_info {
fqdn = "192.168.230.230"
username = "admin"
password = "somepasswd"
thumbprint = "207d65dcb6f17aa5a1ef2365ee6ae0b396867baa92464e5f8a46f6853708b9ef"
}
site_type = "ONPREM_LM"
}
```
## Argument Reference

The following arguments are supported:

* `display_name` - (Required) Display name of the resource.
* `description` - (Optional) Description of the resource.
* `tag` - (Optional) A list of scope + tag pairs to associate with this resource.
* `nsx_id` - (Optional) The NSX ID of this resource. If set, this ID will be used to create the resource.
* `fail_if_rtep_misconfigured` - (Optional) Fail onboarding if RTEPs misconfigured. Default is true.
* `fail_if_rtt_exceeded` - (Optional) Fail onboarding if maximum RTT exceeded. Default is true.
* `maximum_rtt` - (Optional) Maximum acceptable packet round trip time (RTT). Default is 250.
* `site_connection_info` - (Optional) Connection information.
* `fqdn` - (Optional) Fully Qualified Domain Name of the Management Node.
* `password` - (Optional) Password.
* `site_uuid` - (Optional) ID of Site.
* `thumbprint` - (Optional) Thumbprint of Enforcement Point.
* `username` - (Optional) Username.
* `site_type` - (Optional) Persistent Site Type. Allowed values are ONPREM_LM, SDDC_LM. Default is ONPREM_LM.

## Attributes Reference

In addition to arguments listed above, the following attributes are exported:

* `id` - ID of the resource.
* `revision` - Indicates current revision number of the object as seen by NSX-T API server. This attribute can be useful for debugging.
* `path` - The NSX path of the policy resource.

## Importing

An existing object can be [imported][docs-import] into this resource, via the following command:

[docs-import]: https://www.terraform.io/cli/import

```
terraform import nsxt_policy_site.test POLICY_PATH
```
The above command imports Site named `test` with policy path `POLICY_PATH`.

0 comments on commit bfc60f2

Please sign in to comment.