Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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
2 changes: 2 additions & 0 deletions .changes/v1.0.0/15-features.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- **New Resource:** `vcfa_org_networking` to manage Org Networking Settings [GH-15]
- **New Data Source:** `vcfa_org_networking` to read Org Networking Settings [GH-15]
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,5 @@ require (
google.golang.org/protobuf v1.35.1 // indirect
sigs.k8s.io/yaml v1.4.0 // indirect
)

replace github.com/vmware/go-vcloud-director/v3 => github.com/Didainius/go-vcloud-director/v3 v3.0.0-alpha.4.0.20250127110854-6e2af1ae07dd
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk=
dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk=
github.com/Didainius/go-vcloud-director/v3 v3.0.0-alpha.4.0.20250127110854-6e2af1ae07dd h1:9wVAkMLkU3cR01evLuNuwdB7bJp3I9FltPTtoj33eUU=
github.com/Didainius/go-vcloud-director/v3 v3.0.0-alpha.4.0.20250127110854-6e2af1ae07dd/go.mod h1:68KHsVns52dsq/w5JQYzauaU/+NAi1FmCxhBrFc/VoQ=
github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
github.com/ProtonMail/go-crypto v1.1.0-alpha.2 h1:bkyFVUP+ROOARdgCiJzNQo2V2kiB97LyUpzH9P6Hrlg=
Expand Down Expand Up @@ -149,8 +151,6 @@ github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IU
github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok=
github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
github.com/vmware/go-vcloud-director/v3 v3.0.0-alpha.19 h1:NHrxpeebuqKYvIac/cynOhSzoK0iI9RowF0b2g00ypg=
github.com/vmware/go-vcloud-director/v3 v3.0.0-alpha.19/go.mod h1:68KHsVns52dsq/w5JQYzauaU/+NAi1FmCxhBrFc/VoQ=
github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
Expand Down
57 changes: 57 additions & 0 deletions vcfa/datasource_vcfa_org_networking.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package vcfa

import (
"context"
"fmt"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

func datasourceVcfaOrgNetworking() *schema.Resource {
return &schema.Resource{
ReadContext: datasourceVcfaOrgNetworkingRead,

Schema: map[string]*schema.Schema{
"org_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Description: fmt.Sprintf("Parent %s for %s", labelVcfaOrg, labelVcfaOrgNetworking),
},
"log_name": {
Type: schema.TypeString,
Computed: true,
Description: fmt.Sprintf("A globally unique identifier (max 8 char) for this %s in the logs of the backing network provider", labelVcfaOrg),
},
"networking_tenancy_enabled": {
Type: schema.TypeBool,
Computed: true,
Description: "Whether this Organization has tenancy for the network domain in the backing network provider",
},
},
}
}

func datasourceVcfaOrgNetworkingRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
vcfaClient := meta.(*VCDClient)
org, err := vcfaClient.GetTmOrgById(d.Get("org_id").(string))
if err != nil {
return diag.Errorf("error retrieving %s: %s", labelVcfaOrg, err)
}

d.SetId(org.TmOrg.ID)
dSet(d, "org_id", org.TmOrg.ID)

orgNetworkingSettings, err := org.GetOrgNetworkingSettings()
if err != nil {
return diag.Errorf("error retrieving %s for %s:%s", labelVcfaOrgNetworking, labelVcfaOrg, err)
}

err = setTmOrgNetworkingSettingsData(vcfaClient, d, orgNetworkingSettings)
if err != nil {
return diag.Errorf("error storing read %s: %s", labelVcfaOrgNetworking, err)
}

return nil
}
2 changes: 2 additions & 0 deletions vcfa/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ var globalDataSourceMap = map[string]*schema.Resource{
"vcfa_provider_gateway": datasourceVcfaProviderGateway(), // 1.0
"vcfa_edge_cluster": datasourceVcfaEdgeCluster(), // 1.0
"vcfa_edge_cluster_qos": datasourceVcfaEdgeClusterQos(), // 1.0
"vcfa_org_networking": datasourceVcfaOrgNetworking(), // 1.0
}

var globalResourceMap = map[string]*schema.Resource{
Expand All @@ -63,6 +64,7 @@ var globalResourceMap = map[string]*schema.Resource{
"vcfa_content_library_item": resourceVcfaContentLibraryItem(), // 1.0
"vcfa_provider_gateway": resourceVcfaProviderGateway(), // 1.0
"vcfa_edge_cluster_qos": resourceVcfaEdgeClusterQos(), // 1.0
"vcfa_org_networking": resourceVcfaOrgNetworking(), // 1.0
}

// Provider returns a terraform.ResourceProvider.
Expand Down
148 changes: 148 additions & 0 deletions vcfa/resource_vcfa_org_networking.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
package vcfa

import (
"context"
"fmt"

"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
"github.com/vmware/go-vcloud-director/v3/govcd"
"github.com/vmware/go-vcloud-director/v3/types/v56"
)

const labelVcfaOrgNetworking = "Organization Networking Settings"

func resourceVcfaOrgNetworking() *schema.Resource {
return &schema.Resource{
CreateContext: resourceVcfaOrgNetworkingCreateUpdate,
ReadContext: resourceVcfaOrgNetworkingRead,
UpdateContext: resourceVcfaOrgNetworkingCreateUpdate,
DeleteContext: resourceVcfaOrgNetworkingDelete,
Importer: &schema.ResourceImporter{
StateContext: resourceVcfaOrgNetworkingImport, // The same as importing the Org
},

Schema: map[string]*schema.Schema{
"org_id": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Description: fmt.Sprintf("Parent %s for %s", labelVcfaOrg, labelVcfaOrgNetworking),
},
"log_name": {
Type: schema.TypeString,
Required: true,
Description: fmt.Sprintf("A globally unique identifier (max 8 char) for this %s in the logs of the backing network provider", labelVcfaOrg),
ValidateDiagFunc: validation.ToDiagFunc(validation.StringLenBetween(0, 8)),
},
"networking_tenancy_enabled": {
Type: schema.TypeBool,
Computed: true,
Description: "Whether this Organization has tenancy for the network domain in the backing network provider",
},
},
}
}

func resourceVcfaOrgNetworkingCreateUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
vcfaClient := meta.(*VCDClient)

org, err := vcfaClient.GetTmOrgById(d.Get("org_id").(string))
if err != nil {
return diag.Errorf("error retrieving %s: %s", labelVcfaOrg, err)
}

d.SetId(org.TmOrg.ID)
dSet(d, "org_id", org.TmOrg.ID)

orgNetworkingSettings, err := getTmOrgNetworkingSettingsType(vcfaClient, d)
if err != nil {
return diag.FromErr(err)
}

_, err = org.UpdateOrgNetworkingSettings(orgNetworkingSettings)
if err != nil {
return diag.Errorf("error updating %s for %s:%s", labelVcfaOrgNetworking, labelVcfaOrg, err)
}

return resourceVcfaOrgNetworkingRead(ctx, d, meta)
}

func resourceVcfaOrgNetworkingRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
vcfaClient := meta.(*VCDClient)
org, err := vcfaClient.GetTmOrgById(d.Get("org_id").(string))
if err != nil {
return diag.Errorf("error retrieving %s: %s", labelVcfaOrg, err)
}

d.SetId(org.TmOrg.ID)
dSet(d, "org_id", org.TmOrg.ID)

orgNetworkingSettings, err := org.GetOrgNetworkingSettings()
if err != nil {
if govcd.ContainsNotFound(err) { // Org no longer present, removing from state
d.SetId("")
return nil
}
return diag.Errorf("error retrieving %s for %s:%s", labelVcfaOrgNetworking, labelVcfaOrg, err)
}

err = setTmOrgNetworkingSettingsData(vcfaClient, d, orgNetworkingSettings)
if err != nil {
return diag.Errorf("error storing read %s: %s", labelVcfaOrgNetworking, err)
}

return nil
}

func resourceVcfaOrgNetworkingDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
vcfaClient := meta.(*VCDClient)
org, err := vcfaClient.GetTmOrgById(d.Get("org_id").(string))
if err != nil {
return diag.Errorf("error retrieving %s: %s", labelVcfaOrg, err)
}

// reset settings
resetSettings := &types.TmOrgNetworkingSettings{
OrgNameForLogs: "",
}

_, err = org.UpdateOrgNetworkingSettings(resetSettings)
if err != nil {
return diag.Errorf("error removing Org Network Settings: %s", err)
}

return nil
}

func resourceVcfaOrgNetworkingImport(ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
vcdClient := meta.(*VCDClient)

o, err := vcdClient.GetTmOrgByName(d.Id())
if err != nil {
return nil, fmt.Errorf("error getting Org: %s", err)
}

dSet(d, "org_id", o.TmOrg.ID)
d.SetId(o.TmOrg.ID)
return []*schema.ResourceData{d}, nil
}

func getTmOrgNetworkingSettingsType(_ *VCDClient, d *schema.ResourceData) (*types.TmOrgNetworkingSettings, error) {
t := &types.TmOrgNetworkingSettings{
OrgNameForLogs: d.Get("log_name").(string),
// No setting for it in UI
// NetworkingTenancyEnabled: addrOf(d.Get("networking_tenancy_enabled").(bool)),
}

return t, nil
}

func setTmOrgNetworkingSettingsData(_ *VCDClient, d *schema.ResourceData, orgNetConfig *types.TmOrgNetworkingSettings) error {
dSet(d, "log_name", orgNetConfig.OrgNameForLogs)
if orgNetConfig.NetworkingTenancyEnabled != nil {
dSet(d, "networking_tenancy_enabled", *orgNetConfig.NetworkingTenancyEnabled)
}
return nil
}
128 changes: 128 additions & 0 deletions vcfa/resource_vcfa_org_networking_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
//go:build org || tm || ALL || functional

package vcfa

import (
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
)

func TestAccVcfaOrgNetworking(t *testing.T) {
preTestChecks(t)
skipIfNotSysAdmin(t)

var params = StringMap{
"Testname": t.Name(),
"Tags": "tm org",
}
testParamsNotEmpty(t, params)

configText1 := templateFill(testAccVcfaOrgNetworkingStep1, params)
params["FuncName"] = t.Name() + "-step2"
configText2 := templateFill(testAccVcfaOrgNetworkingStep2, params)
params["FuncName"] = t.Name() + "-step3"
configText3 := templateFill(testAccVcfaOrgNetworkingStep3, params)
params["FuncName"] = t.Name() + "-step4"
configText4 := templateFill(testAccVcfaOrgNetworkingStep4DS, params)

debugPrintf("#[DEBUG] CONFIGURATION step1: %s\n", configText1)
debugPrintf("#[DEBUG] CONFIGURATION step2: %s\n", configText3)
debugPrintf("#[DEBUG] CONFIGURATION step3: %s\n", configText4)
if vcfaShortTest {
t.Skip(acceptanceTestsSkipped)
return
}

resource.Test(t, resource.TestCase{
ProviderFactories: testAccProviders,
Steps: []resource.TestStep{
{
Config: configText1,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("vcfa_org.test", "name", t.Name()),
resource.TestCheckResourceAttrPair("vcfa_org.test", "id", "vcfa_org_networking.test", "id"),
resource.TestCheckResourceAttr("vcfa_org_networking.test", "log_name", "l-one"),
),
},
{
Config: configText2,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("vcfa_org.test", "name", t.Name()),
resource.TestCheckResourceAttrPair("vcfa_org.test", "id", "vcfa_org_networking.test", "id"),
resource.TestCheckResourceAttr("vcfa_org_networking.test", "log_name", ""),
),
},
{
Config: configText3,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttr("vcfa_org.test", "name", t.Name()+""),
resource.TestCheckResourceAttrPair("vcfa_org.test", "id", "vcfa_org_networking.test", "id"),
resource.TestCheckResourceAttr("vcfa_org_networking.test", "log_name", "l-one-u"),
),
},
{
ResourceName: "vcfa_org_networking.test",
ImportState: true,
ImportStateVerify: true,
ImportStateId: params["Testname"].(string), // Org name
},
{
Config: configText4,
Check: resource.ComposeTestCheckFunc(
resourceFieldsEqual("vcfa_org_networking.test", "data.vcfa_org_networking.test", nil),
),
},
},
})

postTestChecks(t)
}

const testAccVcfaOrgNetworkingStep1 = `
resource "vcfa_org" "test" {
name = "{{.Testname}}"
display_name = "terraform-test"
description = "terraform test"
is_enabled = true
}

resource "vcfa_org_networking" "test" {
org_id = vcfa_org.test.id
log_name = "l-one"
}
`

const testAccVcfaOrgNetworkingStep2 = `
resource "vcfa_org" "test" {
name = "{{.Testname}}"
display_name = "terraform-test"
description = ""
is_enabled = true
}

resource "vcfa_org_networking" "test" {
org_id = vcfa_org.test.id
log_name = ""
}
`

const testAccVcfaOrgNetworkingStep3 = `
resource "vcfa_org" "test" {
name = "{{.Testname}}"
display_name = "terraform-test"
description = ""
is_enabled = true
}

resource "vcfa_org_networking" "test" {
org_id = vcfa_org.test.id
log_name = "l-one-u"
}
`

const testAccVcfaOrgNetworkingStep4DS = testAccVcfaOrgNetworkingStep3 + `
data "vcfa_org_networking" "test" {
org_id = vcfa_org.test.id
}
`
Loading