forked from vmware/terraform-provider-nsxt
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request vmware#1145 from ksamoray/md_proxy
Implement MD proxy and use in segment resources
- Loading branch information
Showing
8 changed files
with
466 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,212 @@ | ||
/* Copyright © 2024 Broadcom, 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/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/infra" | ||
"github.com/vmware/vsphere-automation-sdk-go/services/nsxt/model" | ||
) | ||
|
||
var cryptoProtocolsValues = []string{"TLS_V1", "TLS_V1_1", "TLS_V1_2"} | ||
|
||
func resourceNsxtPolicyMetadataProxy() *schema.Resource { | ||
return &schema.Resource{ | ||
Create: resourceNsxtPolicyMetadataProxyCreate, | ||
Read: resourceNsxtPolicyMetadataProxyRead, | ||
Update: resourceNsxtPolicyMetadataProxyUpdate, | ||
Delete: resourceNsxtPolicyMetadataProxyDelete, | ||
Importer: &schema.ResourceImporter{ | ||
State: nsxtPolicyPathResourceImporter, | ||
}, | ||
|
||
Schema: map[string]*schema.Schema{ | ||
"nsx_id": getNsxIDSchema(), | ||
"path": getPathSchema(), | ||
"display_name": getDisplayNameSchema(), | ||
"description": getDescriptionSchema(), | ||
"revision": getRevisionSchema(), | ||
"tag": getTagsSchema(), | ||
"crypto_protocols": { | ||
Type: schema.TypeList, | ||
Computed: true, | ||
Optional: true, | ||
Description: "Metadata proxy supported cryptographic protocols", | ||
Elem: &schema.Schema{ | ||
Type: schema.TypeString, | ||
ValidateFunc: validation.StringInSlice(cryptoProtocolsValues, false), | ||
}, | ||
}, | ||
"edge_cluster_path": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
Description: "Policy path to Edge Cluster", | ||
ValidateFunc: validatePolicyPath(), | ||
}, | ||
"enable_standby_relocation": { | ||
Type: schema.TypeBool, | ||
Optional: true, | ||
Default: false, | ||
Description: "Flag to enable standby relocation", | ||
}, | ||
"preferred_edge_paths": { | ||
Type: schema.TypeList, | ||
Optional: true, | ||
Description: "Preferred Edge Paths", | ||
Elem: &schema.Schema{ | ||
Type: schema.TypeString, | ||
ValidateFunc: validatePolicyPath(), | ||
}, | ||
}, | ||
"secret": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
Sensitive: true, | ||
Description: "Secret", | ||
}, | ||
"server_address": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
Description: "Server Address", | ||
}, | ||
"server_certificates": { | ||
Type: schema.TypeList, | ||
Optional: true, | ||
Description: "Policy paths to Certificate Authority (CA) certificates", | ||
Sensitive: true, | ||
Elem: &schema.Schema{ | ||
Type: schema.TypeString, | ||
Sensitive: true, | ||
}, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func resourceNsxtPolicyMetadataProxyExists(id string, connector client.Connector, isGlobalManager bool) (bool, error) { | ||
client := infra.NewMetadataProxiesClient(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 getMetadataProxyFromSchema(d *schema.ResourceData) model.MetadataProxyConfig { | ||
displayName := d.Get("display_name").(string) | ||
description := d.Get("description").(string) | ||
tags := getPolicyTagsFromSchema(d) | ||
|
||
cryptoProtocols := interfaceListToStringList(d.Get("crypto_protocols").([]interface{})) | ||
edgeClusterPath := d.Get("edge_cluster_path").(string) | ||
enableStandbyRelocation := d.Get("enable_standby_relocation").(bool) | ||
preferredEdgePaths := interfaceListToStringList(d.Get("preferred_edge_paths").([]interface{})) | ||
secret := d.Get("secret").(string) | ||
serverAddress := d.Get("server_address").(string) | ||
serverCertificates := interfaceListToStringList(d.Get("server_certificates").([]interface{})) | ||
return model.MetadataProxyConfig{ | ||
DisplayName: &displayName, | ||
Description: &description, | ||
Tags: tags, | ||
CryptoProtocols: cryptoProtocols, | ||
EdgeClusterPath: &edgeClusterPath, | ||
EnableStandbyRelocation: &enableStandbyRelocation, | ||
PreferredEdgePaths: preferredEdgePaths, | ||
Secret: &secret, | ||
ServerAddress: &serverAddress, | ||
ServerCertificates: serverCertificates, | ||
} | ||
} | ||
|
||
func resourceNsxtPolicyMetadataProxyCreate(d *schema.ResourceData, m interface{}) error { | ||
// Initialize resource Id and verify this ID is not yet used | ||
id, err := getOrGenerateID(d, m, resourceNsxtPolicyMetadataProxyExists) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
connector := getPolicyConnector(m) | ||
client := infra.NewMetadataProxiesClient(connector) | ||
obj := getMetadataProxyFromSchema(d) | ||
err = client.Patch(id, obj) | ||
if err != nil { | ||
return handleCreateError("PolicyMetadataProxy", id, err) | ||
} | ||
|
||
d.SetId(id) | ||
d.Set("nsx_id", id) | ||
|
||
return resourceNsxtPolicyMetadataProxyRead(d, m) | ||
} | ||
|
||
func resourceNsxtPolicyMetadataProxyRead(d *schema.ResourceData, m interface{}) error { | ||
connector := getPolicyConnector(m) | ||
|
||
id := d.Id() | ||
if id == "" { | ||
return fmt.Errorf("Error obtaining PolicyMetadataProxy ID") | ||
} | ||
client := infra.NewMetadataProxiesClient(connector) | ||
obj, err := client.Get(id) | ||
if err != nil { | ||
return handleReadError(d, "PolicyMetadataProxy", id, err) | ||
} | ||
|
||
d.Set("display_name", obj.DisplayName) | ||
d.Set("description", obj.Description) | ||
setPolicyTagsInSchema(d, obj.Tags) | ||
d.Set("nsx_id", id) | ||
d.Set("path", obj.Path) | ||
d.Set("revision", obj.Revision) | ||
d.Set("crypto_protocols", stringList2Interface(obj.CryptoProtocols)) | ||
d.Set("edge_cluster_path", obj.EdgeClusterPath) | ||
d.Set("enable_standby_relocation", obj.EnableStandbyRelocation) | ||
d.Set("preferred_edge_paths", stringList2Interface(obj.PreferredEdgePaths)) | ||
d.Set("server_address", obj.ServerAddress) | ||
|
||
return nil | ||
} | ||
|
||
func resourceNsxtPolicyMetadataProxyUpdate(d *schema.ResourceData, m interface{}) error { | ||
id := d.Id() | ||
if id == "" { | ||
return fmt.Errorf("Error obtaining PolicyMetadataProxy ID") | ||
} | ||
|
||
connector := getPolicyConnector(m) | ||
client := infra.NewMetadataProxiesClient(connector) | ||
|
||
obj := getMetadataProxyFromSchema(d) | ||
revision := int64(d.Get("revision").(int)) | ||
obj.Revision = &revision | ||
_, err := client.Update(id, obj) | ||
if err != nil { | ||
return handleUpdateError("PolicyMetadataProxy", id, err) | ||
} | ||
|
||
return resourceNsxtPolicyMetadataProxyRead(d, m) | ||
} | ||
|
||
func resourceNsxtPolicyMetadataProxyDelete(d *schema.ResourceData, m interface{}) error { | ||
id := d.Id() | ||
if id == "" { | ||
return fmt.Errorf("error obtaining PolicyMetadataProxy ID") | ||
} | ||
connector := getPolicyConnector(m) | ||
client := infra.NewMetadataProxiesClient(connector) | ||
err := client.Delete(id) | ||
if err != nil { | ||
return handleDeleteError("PolicyMetadataProxy", id, err) | ||
} | ||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
/* Copyright © 2024 Broadcom, Inc. All Rights Reserved. | ||
SPDX-License-Identifier: MPL-2.0 */ | ||
|
||
package nsxt | ||
|
||
import ( | ||
"fmt" | ||
"testing" | ||
|
||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" | ||
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform" | ||
) | ||
|
||
var accTestPolicyMetadataProxyCreateAttributes = map[string]string{ | ||
"display_name": getAccTestResourceName(), | ||
"description": "terraform created", | ||
"secret": "topsecret!!", | ||
"server_address": "http://1.1.1.120:6000", | ||
} | ||
|
||
var accTestPolicyMetadataProxyUpdateAttributes = map[string]string{ | ||
"display_name": getAccTestResourceName(), | ||
"description": "terraform updated", | ||
"secret": "donottell:)", | ||
"server_address": "http://1.1.1.123:6000", | ||
} | ||
|
||
func TestAccResourceNsxtPolicyMetadataProxy_basic(t *testing.T) { | ||
testResourceName := "nsxt_policy_metadata_proxy.test" | ||
resource.ParallelTest(t, resource.TestCase{ | ||
PreCheck: func() { | ||
testAccOnlyLocalManager(t) | ||
testAccPreCheck(t) | ||
}, | ||
Providers: testAccProviders, | ||
CheckDestroy: func(state *terraform.State) error { | ||
return testAccNsxtPolicyMetadataProxyCheckDestroy(state, accTestPolicyMetadataProxyUpdateAttributes["display_name"]) | ||
}, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: testAccNsxtPolicyMetadataProxyTemplate(true), | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccNsxtPolicyMetadataProxyExists(accTestPolicyMetadataProxyCreateAttributes["display_name"], testResourceName), | ||
resource.TestCheckResourceAttr(testResourceName, "display_name", accTestPolicyMetadataProxyCreateAttributes["display_name"]), | ||
resource.TestCheckResourceAttr(testResourceName, "description", accTestPolicyMetadataProxyCreateAttributes["description"]), | ||
|
||
resource.TestCheckResourceAttr(testResourceName, "secret", accTestPolicyMetadataProxyCreateAttributes["secret"]), | ||
resource.TestCheckResourceAttr(testResourceName, "server_address", accTestPolicyMetadataProxyCreateAttributes["server_address"]), | ||
|
||
resource.TestCheckResourceAttrSet(testResourceName, "nsx_id"), | ||
resource.TestCheckResourceAttrSet(testResourceName, "path"), | ||
resource.TestCheckResourceAttrSet(testResourceName, "revision"), | ||
resource.TestCheckResourceAttr(testResourceName, "tag.#", "1"), | ||
), | ||
}, | ||
{ | ||
Config: testAccNsxtPolicyMetadataProxyTemplate(false), | ||
Check: resource.ComposeTestCheckFunc( | ||
testAccNsxtPolicyMetadataProxyExists(accTestPolicyMetadataProxyUpdateAttributes["display_name"], testResourceName), | ||
resource.TestCheckResourceAttr(testResourceName, "display_name", accTestPolicyMetadataProxyUpdateAttributes["display_name"]), | ||
resource.TestCheckResourceAttr(testResourceName, "description", accTestPolicyMetadataProxyUpdateAttributes["description"]), | ||
|
||
resource.TestCheckResourceAttr(testResourceName, "secret", accTestPolicyMetadataProxyUpdateAttributes["secret"]), | ||
resource.TestCheckResourceAttr(testResourceName, "server_address", accTestPolicyMetadataProxyUpdateAttributes["server_address"]), | ||
|
||
resource.TestCheckResourceAttrSet(testResourceName, "nsx_id"), | ||
resource.TestCheckResourceAttrSet(testResourceName, "path"), | ||
resource.TestCheckResourceAttrSet(testResourceName, "revision"), | ||
resource.TestCheckResourceAttr(testResourceName, "tag.#", "1"), | ||
), | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func TestAccResourceNsxtPolicyMetadataProxy_importBasic(t *testing.T) { | ||
testResourceName := "nsxt_policy_metadata_proxy.test" | ||
|
||
resource.ParallelTest(t, resource.TestCase{ | ||
PreCheck: func() { | ||
testAccOnlyLocalManager(t) | ||
testAccPreCheck(t) | ||
}, | ||
Providers: testAccProviders, | ||
CheckDestroy: func(state *terraform.State) error { | ||
return testAccNsxtPolicyMetadataProxyCheckDestroy(state, accTestPolicyMetadataProxyUpdateAttributes["display_name"]) | ||
}, | ||
Steps: []resource.TestStep{ | ||
{ | ||
Config: testAccNsxtPolicyMetadataProxyTemplate(true), | ||
}, | ||
{ | ||
ResourceName: testResourceName, | ||
ImportState: true, | ||
ImportStateVerify: true, | ||
ImportStateVerifyIgnore: []string{"secret"}, // Secret isn't returned by NSX as it's a secret... | ||
}, | ||
}, | ||
}) | ||
} | ||
|
||
func testAccNsxtPolicyMetadataProxyExists(displayName string, resourceName string) resource.TestCheckFunc { | ||
return func(state *terraform.State) error { | ||
|
||
connector := getPolicyConnector(testAccProvider.Meta().(nsxtClients)) | ||
|
||
rs, ok := state.RootModule().Resources[resourceName] | ||
if !ok { | ||
return fmt.Errorf("PolicyMetadataProxy resource %s not found in resources", resourceName) | ||
} | ||
|
||
resourceID := rs.Primary.ID | ||
if resourceID == "" { | ||
return fmt.Errorf("PolicyMetadataProxy resource ID not set in resources") | ||
} | ||
|
||
exists, err := resourceNsxtPolicyMetadataProxyExists(resourceID, connector, testAccIsGlobalManager()) | ||
if err != nil { | ||
return err | ||
} | ||
if !exists { | ||
return fmt.Errorf("PolicyMetadataProxy %s does not exist", resourceID) | ||
} | ||
|
||
return nil | ||
} | ||
} | ||
|
||
func testAccNsxtPolicyMetadataProxyCheckDestroy(state *terraform.State, displayName string) error { | ||
connector := getPolicyConnector(testAccProvider.Meta().(nsxtClients)) | ||
for _, rs := range state.RootModule().Resources { | ||
|
||
if rs.Type != "nsxt_policy_metadata_proxy" { | ||
continue | ||
} | ||
|
||
resourceID := rs.Primary.Attributes["id"] | ||
exists, err := resourceNsxtPolicyMetadataProxyExists(resourceID, connector, testAccIsGlobalManager()) | ||
if err == nil { | ||
return err | ||
} | ||
|
||
if exists { | ||
return fmt.Errorf("PolicyMetadataProxy %s still exists", displayName) | ||
} | ||
} | ||
return nil | ||
} | ||
|
||
func testAccNsxtPolicyMetadataProxyTemplate(createFlow bool) string { | ||
var attrMap map[string]string | ||
if createFlow { | ||
attrMap = accTestPolicyMetadataProxyCreateAttributes | ||
} else { | ||
attrMap = accTestPolicyMetadataProxyUpdateAttributes | ||
} | ||
return testAccNsxtPolicyEdgeClusterReadTemplate(getEdgeClusterName()) + fmt.Sprintf(` | ||
resource "nsxt_policy_metadata_proxy" "test" { | ||
display_name = "%s" | ||
description = "%s" | ||
edge_cluster_path = data.nsxt_policy_edge_cluster.test.path | ||
secret = "%s" | ||
server_address = "%s" | ||
tag { | ||
scope = "scope1" | ||
tag = "tag1" | ||
} | ||
} | ||
`, attrMap["display_name"], attrMap["description"], attrMap["secret"], attrMap["server_address"]) | ||
} |
Oops, something went wrong.