-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Bug 86073: validate duplicate vSphere failureDomain topology #10563
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -378,7 +378,7 @@ func TestValidatePlatform(t *testing.T) { | |
|
|
||
| for i := range p.FailureDomains { | ||
| p.FailureDomains[i].Topology.ComputeCluster = "/test-datacenter/host/HostClusterFolder/test-cluster" | ||
| p.FailureDomains[i].Topology.ResourcePool = "/test-datacenter/host/HostClusterFolder/test-cluster/Resources/test-resourcepool" | ||
| p.FailureDomains[i].Topology.ResourcePool = fmt.Sprintf("/test-datacenter/host/HostClusterFolder/test-cluster/Resources/test-resourcepool-%d", i) | ||
| p.FailureDomains[i].Topology.Datastore = "/test-datacenter/datastore/StorageFolder/test-datastore" | ||
| p.FailureDomains[i].Topology.Folder = "/test-datacenter/vm/VMFolder/test-folder" | ||
| } | ||
|
|
@@ -552,6 +552,145 @@ func TestValidatePlatform(t *testing.T) { | |
| }(), | ||
| expectedError: `test-path\.failureDomains\.name\[1\]: Duplicate value: "test-east-1a"`, | ||
| }, | ||
| { | ||
| name: "Multi-zone platform failureDomain duplicate topology", | ||
| platform: func() *vsphere.Platform { | ||
| p := validPlatform() | ||
| p.FailureDomains[1].Topology = p.FailureDomains[0].Topology | ||
| p.FailureDomains[1].Server = p.FailureDomains[0].Server | ||
| return p | ||
| }(), | ||
| expectedError: `test-path\.failureDomains\[1\]: Invalid value: "test-east-2a": failure domain "test-east-2a" has identical topology .* as "test-east-1a"; this provides no additional fault tolerance`, | ||
| }, | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
| { | ||
| name: "Valid HostGroup failure domains with same topology but different HostGroups", | ||
| platform: func() *vsphere.Platform { | ||
| p := validPlatform() | ||
| p.FailureDomains[0].RegionType = vsphere.ComputeClusterFailureDomain | ||
| p.FailureDomains[0].ZoneType = vsphere.HostGroupFailureDomain | ||
| p.FailureDomains[0].Topology.HostGroup = "host-group-a" | ||
| p.FailureDomains[0].Topology.ResourcePool = "/test-datacenter/host/test-cluster/Resources/test-resourcepool" | ||
|
|
||
| p.FailureDomains[1].Server = p.FailureDomains[0].Server | ||
| p.FailureDomains[1].Topology = p.FailureDomains[0].Topology | ||
| p.FailureDomains[1].RegionType = vsphere.ComputeClusterFailureDomain | ||
| p.FailureDomains[1].ZoneType = vsphere.HostGroupFailureDomain | ||
| p.FailureDomains[1].Topology.HostGroup = "host-group-b" | ||
| return p | ||
| }(), | ||
| }, | ||
| { | ||
| name: "Duplicate topology with same networks same order (multi-net)", | ||
| platform: func() *vsphere.Platform { | ||
| p := validPlatform() | ||
| p.FailureDomains[0].Topology.Networks = []string{"net-a", "net-b"} | ||
| p.FailureDomains[1].Topology = p.FailureDomains[0].Topology | ||
| p.FailureDomains[1].Server = p.FailureDomains[0].Server | ||
| return p | ||
| }(), | ||
| expectedError: `test-path\.failureDomains\[1\]: Invalid value: "test-east-2a": failure domain "test-east-2a" has identical topology .* as "test-east-1a"; this provides no additional fault tolerance`, | ||
| }, | ||
| { | ||
| name: "Valid: same networks different order (multi-net, order matters)", | ||
| platform: func() *vsphere.Platform { | ||
| p := validPlatform() | ||
| p.FailureDomains[0].Topology.Networks = []string{"net-a", "net-b"} | ||
| p.FailureDomains[1].Server = p.FailureDomains[0].Server | ||
| p.FailureDomains[1].Topology = p.FailureDomains[0].Topology | ||
| p.FailureDomains[1].Topology.Networks = []string{"net-b", "net-a"} | ||
| return p | ||
| }(), | ||
| }, | ||
| { | ||
| name: "Valid: different networks (multi-net)", | ||
| platform: func() *vsphere.Platform { | ||
| p := validPlatform() | ||
| p.FailureDomains[0].Topology.Networks = []string{"net-a", "net-b"} | ||
| p.FailureDomains[1].Server = p.FailureDomains[0].Server | ||
| p.FailureDomains[1].Topology = p.FailureDomains[0].Topology | ||
| p.FailureDomains[1].Topology.Networks = []string{"net-a", "net-c"} | ||
| return p | ||
| }(), | ||
| }, | ||
| { | ||
| name: "Valid: subset networks (different length)", | ||
| platform: func() *vsphere.Platform { | ||
| p := validPlatform() | ||
| p.FailureDomains[0].Topology.Networks = []string{"net-a"} | ||
| p.FailureDomains[1].Server = p.FailureDomains[0].Server | ||
| p.FailureDomains[1].Topology = p.FailureDomains[0].Topology | ||
| p.FailureDomains[1].Topology.Networks = []string{"net-a", "net-b"} | ||
| return p | ||
| }(), | ||
| }, | ||
| { | ||
| name: "Duplicate topology with path normalization (trailing slash)", | ||
| platform: func() *vsphere.Platform { | ||
| p := validPlatform() | ||
| p.FailureDomains[1].Server = p.FailureDomains[0].Server | ||
| p.FailureDomains[1].Topology = p.FailureDomains[0].Topology | ||
| p.FailureDomains[1].Topology.ComputeCluster = "/test-datacenter/host/test-cluster/" | ||
| return p | ||
| }(), | ||
| expectedError: `test-path\.failureDomains\[1\]: Invalid value: "test-east-2a": failure domain "test-east-2a" has identical topology .* as "test-east-1a"; this provides no additional fault tolerance`, | ||
| }, | ||
| { | ||
| name: "Duplicate topology with path normalization (double slash)", | ||
| platform: func() *vsphere.Platform { | ||
| p := validPlatform() | ||
| p.FailureDomains[1].Server = p.FailureDomains[0].Server | ||
| p.FailureDomains[1].Topology = p.FailureDomains[0].Topology | ||
| p.FailureDomains[1].Topology.Datastore = "/test-datacenter/datastore//test-datastore" | ||
| return p | ||
| }(), | ||
| expectedError: `test-path\.failureDomains\[1\]: Invalid value: "test-east-2a": failure domain "test-east-2a" has identical topology .* as "test-east-1a"; this provides no additional fault tolerance`, | ||
| }, | ||
| { | ||
| name: "Valid: different datastore (not duplicate)", | ||
| platform: func() *vsphere.Platform { | ||
| p := validPlatform() | ||
| p.FailureDomains[1].Server = p.FailureDomains[0].Server | ||
| p.FailureDomains[1].Topology = p.FailureDomains[0].Topology | ||
| p.FailureDomains[1].Topology.Datastore = "/test-datacenter/datastore/other-datastore" | ||
| return p | ||
| }(), | ||
| }, | ||
| { | ||
| name: "Valid: different server (not duplicate)", | ||
| platform: func() *vsphere.Platform { | ||
| p := validPlatform() | ||
| p.FailureDomains[1].Topology = p.FailureDomains[0].Topology | ||
| p.FailureDomains[1].Server = "other-vcenter" | ||
| return p | ||
| }(), | ||
| }, | ||
| { | ||
| name: "Duplicate topology HostGroup zonal same hostGroup", | ||
| platform: func() *vsphere.Platform { | ||
| p := validPlatform() | ||
| p.FailureDomains[0].RegionType = vsphere.ComputeClusterFailureDomain | ||
| p.FailureDomains[0].ZoneType = vsphere.HostGroupFailureDomain | ||
| p.FailureDomains[0].Topology.HostGroup = "host-group-a" | ||
| p.FailureDomains[0].Topology.ResourcePool = "/test-datacenter/host/test-cluster/Resources/test-resourcepool" | ||
|
|
||
| p.FailureDomains[1].Server = p.FailureDomains[0].Server | ||
| p.FailureDomains[1].Topology = p.FailureDomains[0].Topology | ||
| p.FailureDomains[1].RegionType = vsphere.ComputeClusterFailureDomain | ||
| p.FailureDomains[1].ZoneType = vsphere.HostGroupFailureDomain | ||
| return p | ||
| }(), | ||
| expectedError: `test-path\.failureDomains\[1\]: Invalid value: "test-east-2a": failure domain "test-east-2a" has identical topology .* as "test-east-1a"; this provides no additional fault tolerance`, | ||
| }, | ||
| { | ||
| name: "Valid: different resourcePool (not duplicate)", | ||
| platform: func() *vsphere.Platform { | ||
| p := validPlatform() | ||
| p.FailureDomains[1].Server = p.FailureDomains[0].Server | ||
| p.FailureDomains[1].Topology = p.FailureDomains[0].Topology | ||
| p.FailureDomains[1].Topology.ResourcePool = "/test-datacenter/host/test-cluster/Resources/other-pool" | ||
| return p | ||
| }(), | ||
| }, | ||
|
Comment on lines
+582
to
+693
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win Add test coverage for HostGroup evasion on non-HostGroup zones. The test suite comprehensively covers network ordering, path normalization, and HostGroup-zone scenarios. However, there's no test case for two non-HostGroup failure domains (e.g., 🧪 Proposed test case (should expect error after fixing platform.go line 400){
name: "Duplicate topology: non-HostGroup zones with different HostGroup values (evasion attempt)",
platform: func() *vsphere.Platform {
p := validPlatform()
// Both are default ComputeCluster zones (not HostGroup zones)
p.FailureDomains[0].Topology.HostGroup = "should-be-ignored-a"
p.FailureDomains[1].Server = p.FailureDomains[0].Server
p.FailureDomains[1].Topology = p.FailureDomains[0].Topology
p.FailureDomains[1].Topology.HostGroup = "should-be-ignored-b"
return p
}(),
// Should produce an error because HostGroup should not participate in dedup for non-HostGroup zones
expectedError: `test-path\.failureDomains\[1\]: Invalid value: "test-east-2a": failure domain "test-east-2a" has identical topology .* as "test-east-1a"; this provides no additional fault tolerance`,
},Note: This test will fail with the current implementation until the fix suggested in 🤖 Prompt for AI Agents |
||
| { | ||
| name: "Multi-zone platform failureDomain zone missing tag category", | ||
| platform: func() *vsphere.Platform { | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you won't be able to use
hostGroupwhen the topology is for vm-host zonal.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@jcpowermac Could you clarify your comment? I want to make sure I understand correctly.
Currently, hostGroup is unconditionally included in the topology key. Are you suggesting:
It should only be included when ZoneType == HostGroup (for vm-host zonal), OR
There's a different issue with the current implementation?
My understanding from the enhancement doc is that vm-host zonal does use hostGroup to distinguish zones within a stretched cluster.