Skip to content

Commit a09bfcd

Browse files
authored
Merge branch 'main' into ras/virtual-disk-create-directories
2 parents 7a28861 + 9ad0f32 commit a09bfcd

File tree

4 files changed

+127
-18
lines changed

4 files changed

+127
-18
lines changed

vsphere/data_source_vsphere_network.go

Lines changed: 75 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,23 @@ package vsphere
55

66
import (
77
"fmt"
8+
"time"
89

10+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
911
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1012
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
13+
1114
"github.com/hashicorp/terraform-provider-vsphere/vsphere/internal/helper/network"
15+
1216
"github.com/vmware/govmomi/object"
1317
)
1418

19+
const (
20+
waitForNetworkPending = "waitForNetworkPending"
21+
waitForNetworkCompleted = "waitForNetworkCompleted"
22+
waitForNetworkError = "waitForNetworkError"
23+
)
24+
1525
func dataSourceVSphereNetwork() *schema.Resource {
1626
return &schema.Resource{
1727
Read: dataSourceVSphereNetworkRead,
@@ -52,6 +62,18 @@ func dataSourceVSphereNetwork() *schema.Resource {
5262
},
5363
},
5464
},
65+
"retry_timeout": {
66+
Type: schema.TypeInt,
67+
Description: "Timeout (in seconds) if network is not present yet",
68+
Optional: true,
69+
Default: 0,
70+
},
71+
"retry_interval": {
72+
Type: schema.TypeInt,
73+
Description: "Retry interval (in milliseconds) when probing the network",
74+
Optional: true,
75+
Default: 500,
76+
},
5577
},
5678
}
5779
}
@@ -69,8 +91,6 @@ func dataSourceVSphereNetworkRead(d *schema.ResourceData, meta interface{}) erro
6991
return fmt.Errorf("cannot locate datacenter: %s", err)
7092
}
7193
}
72-
var net object.NetworkReference
73-
var err error
7494

7595
vimClient := client.Client
7696

@@ -85,19 +105,65 @@ func dataSourceVSphereNetworkRead(d *schema.ResourceData, meta interface{}) erro
85105
}
86106
}
87107

88-
if dvSwitchUUID != "" {
89-
// Handle distributed virtual switch port group
90-
net, err = network.FromNameAndDVSUuid(client, name, dc, dvSwitchUUID)
91-
if err != nil {
92-
return fmt.Errorf("error fetching DVS network: %s", err)
108+
readRetryFunc := func() (interface{}, string, error) {
109+
var net interface{}
110+
var err error
111+
if dvSwitchUUID != "" {
112+
// Handle distributed virtual switch port group
113+
net, err = network.FromNameAndDVSUuid(client, name, dc, dvSwitchUUID)
114+
if err != nil {
115+
if _, ok := err.(network.NetworkNotFoundError); ok {
116+
return struct{}{}, waitForNetworkPending, nil
117+
}
118+
119+
return struct{}{}, waitForNetworkError, err
120+
}
121+
return net, waitForNetworkCompleted, nil
93122
}
94-
} else {
95123
// Handle standard switch port group
96124
net, err = network.FromName(vimClient, name, dc, filters) // Pass the *vim25.Client
97125
if err != nil {
98-
return fmt.Errorf("error fetching network: %s", err)
126+
if _, ok := err.(network.NetworkNotFoundError); ok {
127+
return struct{}{}, waitForNetworkPending, nil
128+
}
129+
return struct{}{}, waitForNetworkError, err
99130
}
131+
return net, waitForNetworkCompleted, nil
132+
133+
}
134+
135+
var net object.NetworkReference
136+
var netObj interface{}
137+
var err error
138+
var state string
139+
140+
retryTimeout := d.Get("retry_timeout").(int)
141+
retryInterval := d.Get("retry_interval").(int)
142+
143+
if retryTimeout == 0 {
144+
// no retry
145+
netObj, state, err = readRetryFunc()
146+
} else {
147+
148+
deleteRetry := &resource.StateChangeConf{
149+
Pending: []string{waitForNetworkPending},
150+
Target: []string{waitForNetworkCompleted},
151+
Refresh: readRetryFunc,
152+
Timeout: time.Duration(retryTimeout) * time.Second,
153+
MinTimeout: time.Duration(retryInterval) * time.Millisecond,
154+
}
155+
156+
netObj, err = deleteRetry.WaitForState()
157+
}
158+
159+
if state == waitForNetworkPending {
160+
err = fmt.Errorf("network %s not found", name)
161+
}
162+
163+
if err != nil {
164+
return err
100165
}
166+
net = netObj.(object.NetworkReference)
101167

102168
d.SetId(net.Reference().Value)
103169
_ = d.Set("type", net.Reference().Type)

vsphere/data_source_vsphere_network_test.go

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,31 @@ func TestAccDataSourceVSphereNetwork_dvsPortgroup(t *testing.T) {
2424
Providers: testAccProviders,
2525
Steps: []resource.TestStep{
2626
{
27-
Config: testAccDataSourceVSphereNetworkConfigDVSPortgroup(),
27+
Config: testAccDataSourceVSphereNetworkConfigDVSPortgroup(false),
28+
Check: resource.ComposeTestCheckFunc(
29+
resource.TestCheckResourceAttr("data.vsphere_network.net", "type", "DistributedVirtualPortgroup"),
30+
resource.TestCheckResourceAttrPair(
31+
"data.vsphere_network.net", "id",
32+
"vsphere_distributed_port_group.pg", "id",
33+
),
34+
),
35+
},
36+
},
37+
})
38+
}
39+
40+
func TestAccDataSourceVSphereNetwork_withTimeout(t *testing.T) {
41+
resource.Test(t, resource.TestCase{
42+
PreCheck: func() {
43+
RunSweepers()
44+
testAccPreCheck(t)
45+
testAccDataSourceVSphereNetworkPreCheck(t)
46+
testAccSkipIfEsxi(t)
47+
},
48+
Providers: testAccProviders,
49+
Steps: []resource.TestStep{
50+
{
51+
Config: testAccDataSourceVSphereNetworkConfigDVSPortgroup(true),
2852
Check: resource.ComposeTestCheckFunc(
2953
resource.TestCheckResourceAttr("data.vsphere_network.net", "type", "DistributedVirtualPortgroup"),
3054
resource.TestCheckResourceAttrPair(
@@ -86,7 +110,11 @@ func testAccDataSourceVSphereNetworkPreCheck(t *testing.T) {
86110
}
87111
}
88112

89-
func testAccDataSourceVSphereNetworkConfigDVSPortgroup() string {
113+
func testAccDataSourceVSphereNetworkConfigDVSPortgroup(withTimeout bool) string {
114+
additionalConfig := ""
115+
if withTimeout {
116+
additionalConfig = `retry_timeout = 180`
117+
}
90118
return fmt.Sprintf(`
91119
%s
92120
@@ -104,10 +132,10 @@ data "vsphere_network" "net" {
104132
name = "${vsphere_distributed_port_group.pg.name}"
105133
datacenter_id = "${data.vsphere_datacenter.rootdc1.id}"
106134
distributed_virtual_switch_uuid = "${vsphere_distributed_virtual_switch.dvs.id}"
135+
%s
107136
}
108137
`,
109-
testhelper.CombineConfigs(testhelper.ConfigDataRootDC1(), testhelper.ConfigDataRootPortGroup1()),
110-
)
138+
testhelper.CombineConfigs(testhelper.ConfigDataRootDC1(), testhelper.ConfigDataRootPortGroup1()), additionalConfig)
111139
}
112140

113141
func testAccDataSourceVSphereNetworkConfigDVSPortgroupAbsolute() string {

vsphere/internal/helper/network/network_helper.go

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,19 @@ var NetworkType = []string{
2424
"OpaqueNetwork",
2525
}
2626

27+
type NetworkNotFoundError struct {
28+
Name string
29+
ID string
30+
}
31+
32+
func (e NetworkNotFoundError) Error() string {
33+
if len(e.ID) > 0 {
34+
return fmt.Sprintf("Network with ID %s not found", e.ID)
35+
}
36+
37+
return fmt.Sprintf("Network %s not found", e.Name)
38+
}
39+
2740
// FromPath loads a network via its path.
2841
//
2942
// A network is a usually one of three kinds of networks: a DVS port group, a
@@ -57,7 +70,7 @@ func FromNameAndDVSUuid(client *govmomi.Client, name string, dc *object.Datacent
5770
return nil, err
5871
}
5972
if len(networks) == 0 {
60-
return nil, fmt.Errorf("%s %s not found", "Network", name)
73+
return nil, NetworkNotFoundError{Name: name}
6174
}
6275

6376
switch {
@@ -90,7 +103,7 @@ func FromNameAndDVSUuid(client *govmomi.Client, name string, dc *object.Datacent
90103
}
91104
return nil, fmt.Errorf("error while getting Network with name %s and Distributed virtual switch %s", name, dvsUUID)
92105
}
93-
return nil, fmt.Errorf("%s %s not found", "Network", name)
106+
return nil, NetworkNotFoundError{Name: name}
94107
}
95108

96109
func List(client *govmomi.Client) ([]*object.VmwareDistributedVirtualSwitch, error) {
@@ -169,7 +182,7 @@ func FromID(client *govmomi.Client, id string) (object.NetworkReference, error)
169182
return nref.(object.NetworkReference), nil
170183
}
171184
}
172-
return nil, fmt.Errorf("could not find network with ID %q", id)
185+
return nil, NetworkNotFoundError{ID: id}
173186
}
174187

175188
func dvsFromMOID(client *govmomi.Client, id string) (*object.VmwareDistributedVirtualSwitch, error) {
@@ -218,7 +231,7 @@ func FromName(client *vim25.Client, name string, dc *object.Datacenter, filters
218231
// Find the network by name
219232
networks, err := finder.NetworkList(ctx, name)
220233
if err != nil {
221-
return nil, fmt.Errorf("error finding network %s: %v", name, err)
234+
return nil, NetworkNotFoundError{Name: name}
222235
}
223236

224237
// If multiple networks are found and no filters are specified, return an error
@@ -255,5 +268,5 @@ func FromName(client *vim25.Client, name string, dc *object.Datacenter, filters
255268
}
256269
}
257270

258-
return nil, fmt.Errorf("no network found matching the specified criteria")
271+
return nil, NetworkNotFoundError{Name: name}
259272
}

website/docs/d/network.html.markdown

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ The following arguments are supported:
6262
the distributed virtual switch ID.
6363
* `filter` - (Optional) Apply a filter for the discovered network.
6464
* `network_type`: This is required if you have multiple port groups with the same name. This will be one of `DistributedVirtualPortgroup` for distributed port groups, `Network` for standard (host-based) port groups, or `OpaqueNetwork` for networks managed externally, such as those managed by NSX.
65+
* `retry_timeout` - (Optional) The timeout duration in seconds for the data source to retry read operations.
66+
* `retry_interval` - (Optional) The interval in milliseconds to retry the read operation if `retry_timeout` is set. Default: 500.
6567
[docs-about-morefs]: /docs/providers/vsphere/index.html#use-of-managed-object-references-by-the-vsphere-provider
6668

6769
## Attribute Reference

0 commit comments

Comments
 (0)