Skip to content

Commit d255fda

Browse files
authored
Merge pull request #1145 from ksamoray/md_proxy
Implement MD proxy and use in segment resources
2 parents fb06307 + 014dd61 commit d255fda

8 files changed

+466
-0
lines changed

nsxt/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,7 @@ func Provider() *schema.Provider {
482482
"nsxt_policy_vtep_ha_host_switch_profile": resourceNsxtVtepHAHostSwitchProfile(),
483483
"nsxt_policy_site": resourceNsxtPolicySite(),
484484
"nsxt_policy_global_manager": resourceNsxtPolicyGlobalManager(),
485+
"nsxt_policy_metadata_proxy": resourceNsxtPolicyMetadataProxy(),
485486
},
486487

487488
ConfigureFunc: providerConfigure,
Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
/* Copyright © 2024 Broadcom, Inc. All Rights Reserved.
2+
SPDX-License-Identifier: MPL-2.0 */
3+
4+
package nsxt
5+
6+
import (
7+
"fmt"
8+
9+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
10+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
11+
"github.com/vmware/vsphere-automation-sdk-go/runtime/protocol/client"
12+
"github.com/vmware/vsphere-automation-sdk-go/services/nsxt/infra"
13+
"github.com/vmware/vsphere-automation-sdk-go/services/nsxt/model"
14+
)
15+
16+
var cryptoProtocolsValues = []string{"TLS_V1", "TLS_V1_1", "TLS_V1_2"}
17+
18+
func resourceNsxtPolicyMetadataProxy() *schema.Resource {
19+
return &schema.Resource{
20+
Create: resourceNsxtPolicyMetadataProxyCreate,
21+
Read: resourceNsxtPolicyMetadataProxyRead,
22+
Update: resourceNsxtPolicyMetadataProxyUpdate,
23+
Delete: resourceNsxtPolicyMetadataProxyDelete,
24+
Importer: &schema.ResourceImporter{
25+
State: nsxtPolicyPathResourceImporter,
26+
},
27+
28+
Schema: map[string]*schema.Schema{
29+
"nsx_id": getNsxIDSchema(),
30+
"path": getPathSchema(),
31+
"display_name": getDisplayNameSchema(),
32+
"description": getDescriptionSchema(),
33+
"revision": getRevisionSchema(),
34+
"tag": getTagsSchema(),
35+
"crypto_protocols": {
36+
Type: schema.TypeList,
37+
Computed: true,
38+
Optional: true,
39+
Description: "Metadata proxy supported cryptographic protocols",
40+
Elem: &schema.Schema{
41+
Type: schema.TypeString,
42+
ValidateFunc: validation.StringInSlice(cryptoProtocolsValues, false),
43+
},
44+
},
45+
"edge_cluster_path": {
46+
Type: schema.TypeString,
47+
Required: true,
48+
Description: "Policy path to Edge Cluster",
49+
ValidateFunc: validatePolicyPath(),
50+
},
51+
"enable_standby_relocation": {
52+
Type: schema.TypeBool,
53+
Optional: true,
54+
Default: false,
55+
Description: "Flag to enable standby relocation",
56+
},
57+
"preferred_edge_paths": {
58+
Type: schema.TypeList,
59+
Optional: true,
60+
Description: "Preferred Edge Paths",
61+
Elem: &schema.Schema{
62+
Type: schema.TypeString,
63+
ValidateFunc: validatePolicyPath(),
64+
},
65+
},
66+
"secret": {
67+
Type: schema.TypeString,
68+
Required: true,
69+
Sensitive: true,
70+
Description: "Secret",
71+
},
72+
"server_address": {
73+
Type: schema.TypeString,
74+
Required: true,
75+
Description: "Server Address",
76+
},
77+
"server_certificates": {
78+
Type: schema.TypeList,
79+
Optional: true,
80+
Description: "Policy paths to Certificate Authority (CA) certificates",
81+
Sensitive: true,
82+
Elem: &schema.Schema{
83+
Type: schema.TypeString,
84+
Sensitive: true,
85+
},
86+
},
87+
},
88+
}
89+
}
90+
91+
func resourceNsxtPolicyMetadataProxyExists(id string, connector client.Connector, isGlobalManager bool) (bool, error) {
92+
client := infra.NewMetadataProxiesClient(connector)
93+
_, err := client.Get(id)
94+
if err == nil {
95+
return true, nil
96+
}
97+
98+
if isNotFoundError(err) {
99+
return false, nil
100+
}
101+
102+
return false, logAPIError("Error retrieving resource", err)
103+
}
104+
105+
func getMetadataProxyFromSchema(d *schema.ResourceData) model.MetadataProxyConfig {
106+
displayName := d.Get("display_name").(string)
107+
description := d.Get("description").(string)
108+
tags := getPolicyTagsFromSchema(d)
109+
110+
cryptoProtocols := interfaceListToStringList(d.Get("crypto_protocols").([]interface{}))
111+
edgeClusterPath := d.Get("edge_cluster_path").(string)
112+
enableStandbyRelocation := d.Get("enable_standby_relocation").(bool)
113+
preferredEdgePaths := interfaceListToStringList(d.Get("preferred_edge_paths").([]interface{}))
114+
secret := d.Get("secret").(string)
115+
serverAddress := d.Get("server_address").(string)
116+
serverCertificates := interfaceListToStringList(d.Get("server_certificates").([]interface{}))
117+
return model.MetadataProxyConfig{
118+
DisplayName: &displayName,
119+
Description: &description,
120+
Tags: tags,
121+
CryptoProtocols: cryptoProtocols,
122+
EdgeClusterPath: &edgeClusterPath,
123+
EnableStandbyRelocation: &enableStandbyRelocation,
124+
PreferredEdgePaths: preferredEdgePaths,
125+
Secret: &secret,
126+
ServerAddress: &serverAddress,
127+
ServerCertificates: serverCertificates,
128+
}
129+
}
130+
131+
func resourceNsxtPolicyMetadataProxyCreate(d *schema.ResourceData, m interface{}) error {
132+
// Initialize resource Id and verify this ID is not yet used
133+
id, err := getOrGenerateID(d, m, resourceNsxtPolicyMetadataProxyExists)
134+
if err != nil {
135+
return err
136+
}
137+
138+
connector := getPolicyConnector(m)
139+
client := infra.NewMetadataProxiesClient(connector)
140+
obj := getMetadataProxyFromSchema(d)
141+
err = client.Patch(id, obj)
142+
if err != nil {
143+
return handleCreateError("PolicyMetadataProxy", id, err)
144+
}
145+
146+
d.SetId(id)
147+
d.Set("nsx_id", id)
148+
149+
return resourceNsxtPolicyMetadataProxyRead(d, m)
150+
}
151+
152+
func resourceNsxtPolicyMetadataProxyRead(d *schema.ResourceData, m interface{}) error {
153+
connector := getPolicyConnector(m)
154+
155+
id := d.Id()
156+
if id == "" {
157+
return fmt.Errorf("Error obtaining PolicyMetadataProxy ID")
158+
}
159+
client := infra.NewMetadataProxiesClient(connector)
160+
obj, err := client.Get(id)
161+
if err != nil {
162+
return handleReadError(d, "PolicyMetadataProxy", id, err)
163+
}
164+
165+
d.Set("display_name", obj.DisplayName)
166+
d.Set("description", obj.Description)
167+
setPolicyTagsInSchema(d, obj.Tags)
168+
d.Set("nsx_id", id)
169+
d.Set("path", obj.Path)
170+
d.Set("revision", obj.Revision)
171+
d.Set("crypto_protocols", stringList2Interface(obj.CryptoProtocols))
172+
d.Set("edge_cluster_path", obj.EdgeClusterPath)
173+
d.Set("enable_standby_relocation", obj.EnableStandbyRelocation)
174+
d.Set("preferred_edge_paths", stringList2Interface(obj.PreferredEdgePaths))
175+
d.Set("server_address", obj.ServerAddress)
176+
177+
return nil
178+
}
179+
180+
func resourceNsxtPolicyMetadataProxyUpdate(d *schema.ResourceData, m interface{}) error {
181+
id := d.Id()
182+
if id == "" {
183+
return fmt.Errorf("Error obtaining PolicyMetadataProxy ID")
184+
}
185+
186+
connector := getPolicyConnector(m)
187+
client := infra.NewMetadataProxiesClient(connector)
188+
189+
obj := getMetadataProxyFromSchema(d)
190+
revision := int64(d.Get("revision").(int))
191+
obj.Revision = &revision
192+
_, err := client.Update(id, obj)
193+
if err != nil {
194+
return handleUpdateError("PolicyMetadataProxy", id, err)
195+
}
196+
197+
return resourceNsxtPolicyMetadataProxyRead(d, m)
198+
}
199+
200+
func resourceNsxtPolicyMetadataProxyDelete(d *schema.ResourceData, m interface{}) error {
201+
id := d.Id()
202+
if id == "" {
203+
return fmt.Errorf("error obtaining PolicyMetadataProxy ID")
204+
}
205+
connector := getPolicyConnector(m)
206+
client := infra.NewMetadataProxiesClient(connector)
207+
err := client.Delete(id)
208+
if err != nil {
209+
return handleDeleteError("PolicyMetadataProxy", id, err)
210+
}
211+
return nil
212+
}
Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
/* Copyright © 2024 Broadcom, Inc. All Rights Reserved.
2+
SPDX-License-Identifier: MPL-2.0 */
3+
4+
package nsxt
5+
6+
import (
7+
"fmt"
8+
"testing"
9+
10+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
11+
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
12+
)
13+
14+
var accTestPolicyMetadataProxyCreateAttributes = map[string]string{
15+
"display_name": getAccTestResourceName(),
16+
"description": "terraform created",
17+
"secret": "topsecret!!",
18+
"server_address": "http://1.1.1.120:6000",
19+
}
20+
21+
var accTestPolicyMetadataProxyUpdateAttributes = map[string]string{
22+
"display_name": getAccTestResourceName(),
23+
"description": "terraform updated",
24+
"secret": "donottell:)",
25+
"server_address": "http://1.1.1.123:6000",
26+
}
27+
28+
func TestAccResourceNsxtPolicyMetadataProxy_basic(t *testing.T) {
29+
testResourceName := "nsxt_policy_metadata_proxy.test"
30+
resource.ParallelTest(t, resource.TestCase{
31+
PreCheck: func() {
32+
testAccOnlyLocalManager(t)
33+
testAccPreCheck(t)
34+
},
35+
Providers: testAccProviders,
36+
CheckDestroy: func(state *terraform.State) error {
37+
return testAccNsxtPolicyMetadataProxyCheckDestroy(state, accTestPolicyMetadataProxyUpdateAttributes["display_name"])
38+
},
39+
Steps: []resource.TestStep{
40+
{
41+
Config: testAccNsxtPolicyMetadataProxyTemplate(true),
42+
Check: resource.ComposeTestCheckFunc(
43+
testAccNsxtPolicyMetadataProxyExists(accTestPolicyMetadataProxyCreateAttributes["display_name"], testResourceName),
44+
resource.TestCheckResourceAttr(testResourceName, "display_name", accTestPolicyMetadataProxyCreateAttributes["display_name"]),
45+
resource.TestCheckResourceAttr(testResourceName, "description", accTestPolicyMetadataProxyCreateAttributes["description"]),
46+
47+
resource.TestCheckResourceAttr(testResourceName, "secret", accTestPolicyMetadataProxyCreateAttributes["secret"]),
48+
resource.TestCheckResourceAttr(testResourceName, "server_address", accTestPolicyMetadataProxyCreateAttributes["server_address"]),
49+
50+
resource.TestCheckResourceAttrSet(testResourceName, "nsx_id"),
51+
resource.TestCheckResourceAttrSet(testResourceName, "path"),
52+
resource.TestCheckResourceAttrSet(testResourceName, "revision"),
53+
resource.TestCheckResourceAttr(testResourceName, "tag.#", "1"),
54+
),
55+
},
56+
{
57+
Config: testAccNsxtPolicyMetadataProxyTemplate(false),
58+
Check: resource.ComposeTestCheckFunc(
59+
testAccNsxtPolicyMetadataProxyExists(accTestPolicyMetadataProxyUpdateAttributes["display_name"], testResourceName),
60+
resource.TestCheckResourceAttr(testResourceName, "display_name", accTestPolicyMetadataProxyUpdateAttributes["display_name"]),
61+
resource.TestCheckResourceAttr(testResourceName, "description", accTestPolicyMetadataProxyUpdateAttributes["description"]),
62+
63+
resource.TestCheckResourceAttr(testResourceName, "secret", accTestPolicyMetadataProxyUpdateAttributes["secret"]),
64+
resource.TestCheckResourceAttr(testResourceName, "server_address", accTestPolicyMetadataProxyUpdateAttributes["server_address"]),
65+
66+
resource.TestCheckResourceAttrSet(testResourceName, "nsx_id"),
67+
resource.TestCheckResourceAttrSet(testResourceName, "path"),
68+
resource.TestCheckResourceAttrSet(testResourceName, "revision"),
69+
resource.TestCheckResourceAttr(testResourceName, "tag.#", "1"),
70+
),
71+
},
72+
},
73+
})
74+
}
75+
76+
func TestAccResourceNsxtPolicyMetadataProxy_importBasic(t *testing.T) {
77+
testResourceName := "nsxt_policy_metadata_proxy.test"
78+
79+
resource.ParallelTest(t, resource.TestCase{
80+
PreCheck: func() {
81+
testAccOnlyLocalManager(t)
82+
testAccPreCheck(t)
83+
},
84+
Providers: testAccProviders,
85+
CheckDestroy: func(state *terraform.State) error {
86+
return testAccNsxtPolicyMetadataProxyCheckDestroy(state, accTestPolicyMetadataProxyUpdateAttributes["display_name"])
87+
},
88+
Steps: []resource.TestStep{
89+
{
90+
Config: testAccNsxtPolicyMetadataProxyTemplate(true),
91+
},
92+
{
93+
ResourceName: testResourceName,
94+
ImportState: true,
95+
ImportStateVerify: true,
96+
ImportStateVerifyIgnore: []string{"secret"}, // Secret isn't returned by NSX as it's a secret...
97+
},
98+
},
99+
})
100+
}
101+
102+
func testAccNsxtPolicyMetadataProxyExists(displayName string, resourceName string) resource.TestCheckFunc {
103+
return func(state *terraform.State) error {
104+
105+
connector := getPolicyConnector(testAccProvider.Meta().(nsxtClients))
106+
107+
rs, ok := state.RootModule().Resources[resourceName]
108+
if !ok {
109+
return fmt.Errorf("PolicyMetadataProxy resource %s not found in resources", resourceName)
110+
}
111+
112+
resourceID := rs.Primary.ID
113+
if resourceID == "" {
114+
return fmt.Errorf("PolicyMetadataProxy resource ID not set in resources")
115+
}
116+
117+
exists, err := resourceNsxtPolicyMetadataProxyExists(resourceID, connector, testAccIsGlobalManager())
118+
if err != nil {
119+
return err
120+
}
121+
if !exists {
122+
return fmt.Errorf("PolicyMetadataProxy %s does not exist", resourceID)
123+
}
124+
125+
return nil
126+
}
127+
}
128+
129+
func testAccNsxtPolicyMetadataProxyCheckDestroy(state *terraform.State, displayName string) error {
130+
connector := getPolicyConnector(testAccProvider.Meta().(nsxtClients))
131+
for _, rs := range state.RootModule().Resources {
132+
133+
if rs.Type != "nsxt_policy_metadata_proxy" {
134+
continue
135+
}
136+
137+
resourceID := rs.Primary.Attributes["id"]
138+
exists, err := resourceNsxtPolicyMetadataProxyExists(resourceID, connector, testAccIsGlobalManager())
139+
if err == nil {
140+
return err
141+
}
142+
143+
if exists {
144+
return fmt.Errorf("PolicyMetadataProxy %s still exists", displayName)
145+
}
146+
}
147+
return nil
148+
}
149+
150+
func testAccNsxtPolicyMetadataProxyTemplate(createFlow bool) string {
151+
var attrMap map[string]string
152+
if createFlow {
153+
attrMap = accTestPolicyMetadataProxyCreateAttributes
154+
} else {
155+
attrMap = accTestPolicyMetadataProxyUpdateAttributes
156+
}
157+
return testAccNsxtPolicyEdgeClusterReadTemplate(getEdgeClusterName()) + fmt.Sprintf(`
158+
resource "nsxt_policy_metadata_proxy" "test" {
159+
display_name = "%s"
160+
description = "%s"
161+
edge_cluster_path = data.nsxt_policy_edge_cluster.test.path
162+
secret = "%s"
163+
server_address = "%s"
164+
tag {
165+
scope = "scope1"
166+
tag = "tag1"
167+
}
168+
}
169+
`, attrMap["display_name"], attrMap["description"], attrMap["secret"], attrMap["server_address"])
170+
}

0 commit comments

Comments
 (0)