Skip to content

Commit

Permalink
Update zone placement under WCP_Workload_Domain_Isolation (vmware-tan…
Browse files Browse the repository at this point in the history
  • Loading branch information
zyiyi11 authored Jul 30, 2024
1 parent 6b22719 commit 8a4b4c0
Show file tree
Hide file tree
Showing 11 changed files with 503 additions and 85 deletions.
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,9 @@ generate-go: ## Generate golang sources
$(CONTROLLER_GEN) \
paths=github.com/vmware-tanzu/vm-operator/external/storage-policy-quota/... \
object:headerFile=./hack/boilerplate/boilerplate.generatego.txt
$(CONTROLLER_GEN) \
paths=github.com/vmware-tanzu/vm-operator/external/tanzu-topology/... \
object:headerFile=./hack/boilerplate/boilerplate.generatego.txt
$(MAKE) -C ./pkg/util/cloudinit/schema $@

.PHONY: generate-manifests
Expand Down
65 changes: 54 additions & 11 deletions config/crd/external-crds/topology.tanzu.vmware.com_zones.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -67,19 +67,62 @@ spec:
- apiVersion
- name
type: object
folderMoID:
managedVMs:
description: |-
FolderMoID is the managed object ID of the vSphere Folder for a
Namespace.
type: string
poolMoIDs:
ManagedVMs contains ResourcePool and folder moIDs to represent managedVMs
entity within the namespace
properties:
folderMoID:
description: |-
FolderMoID is the managed object ID of the vSphere Folder for a
Namespace.
type: string
poolMoIDs:
description: |-
PoolMoIDs are the managed object ID of the vSphere ResourcePools
in an individual vSphere Zone. A zone may be comprised of
multiple ResourcePools.
items:
type: string
type: array
type: object
namespace:
description: Namespace contains ResourcePool and folder moIDs to represent
the namespace
properties:
folderMoID:
description: |-
FolderMoID is the managed object ID of the vSphere Folder for a
Namespace.
type: string
poolMoIDs:
description: |-
PoolMoIDs are the managed object ID of the vSphere ResourcePools
in an individual vSphere Zone. A zone may be comprised of
multiple ResourcePools.
items:
type: string
type: array
type: object
vSpherePods:
description: |-
PoolMoIDs are the managed object ID of the vSphere ResourcePools for a
Namespace in an individual vSphere Zone. A zone may be comprised of
multiple ResourcePools.
items:
type: string
type: array
VSpherePods contains ResourcePool and folder moIDs to represent vSpherePods
entity within the namespace
properties:
folderMoID:
description: |-
FolderMoID is the managed object ID of the vSphere Folder for a
Namespace.
type: string
poolMoIDs:
description: |-
PoolMoIDs are the managed object ID of the vSphere ResourcePools
in an individual vSphere Zone. A zone may be comprised of
multiple ResourcePools.
items:
type: string
type: array
type: object
required:
- availabilityZoneReference
type: object
Expand Down
16 changes: 16 additions & 0 deletions config/rbac/role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,22 @@ rules:
- get
- list
- watch
- apiGroups:
- topology.tanzu.vmware.com
resources:
- zones
verbs:
- get
- list
- watch
- apiGroups:
- topology.tanzu.vmware.com
resources:
- zones/status
verbs:
- get
- list
- watch
- apiGroups:
- vmoperator.vmware.com
resources:
Expand Down
27 changes: 21 additions & 6 deletions external/tanzu-topology/api/v1alpha1/zone.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,35 @@ type AvailabilityZoneReference struct {
Name string `json:"name"`
}

// ZoneSpec contains identifying information about the
// vSphere resources used to represent a Kubernetes namespace on individual
// vSphere Zones.
type ZoneSpec struct {
// VSphereEntityInfo contains the managed object IDs associated with
// a vSphere entity
type VSphereEntityInfo struct {
// +optional
// PoolMoIDs are the managed object ID of the vSphere ResourcePools for a
// Namespace in an individual vSphere Zone. A zone may be comprised of
// PoolMoIDs are the managed object ID of the vSphere ResourcePools
// in an individual vSphere Zone. A zone may be comprised of
// multiple ResourcePools.
PoolMoIDs []string `json:"poolMoIDs,omitempty"`

// +optional
// FolderMoID is the managed object ID of the vSphere Folder for a
// Namespace.
FolderMoID string `json:"folderMoID,omitempty"`
}

// ZoneSpec contains identifying information about the
// vSphere resources used to represent a Kubernetes namespace on individual
// vSphere Zones.
type ZoneSpec struct {
// Namespace contains ResourcePool and folder moIDs to represent the namespace
Namespace VSphereEntityInfo `json:"namespace,omitempty"`

// VSpherePods contains ResourcePool and folder moIDs to represent vSpherePods
// entity within the namespace
VSpherePods VSphereEntityInfo `json:"vSpherePods,omitempty"`

// ManagedVMs contains ResourcePool and folder moIDs to represent managedVMs
// entity within the namespace
ManagedVMs VSphereEntityInfo `json:"managedVMs,omitempty"`

// Zone is a reference to the cluster scoped AvailabilityZone this
// Zone is derived from.
Expand Down
28 changes: 23 additions & 5 deletions external/tanzu-topology/api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

61 changes: 47 additions & 14 deletions pkg/providers/vsphere/placement/zone_placement.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,30 +93,63 @@ func getPlacementCandidates(
zonePlacement bool,
childRPName string) (map[string][]string, error) {

var zones []topologyv1.AvailabilityZone
candidates := map[string][]string{}

// When FSS_WCP_WORKLOAD_DOMAIN_ISOLATION is enabled, use namespaced Zone CR to get candidate resource pools.
if pkgcfg.FromContext(vmCtx).Features.WorkloadDomainIsolation {
var zones []topologyv1.Zone
if zonePlacement {
z, err := topology.GetZones(vmCtx, client, vmCtx.VM.Namespace)
if err != nil {
return nil, err
}
zones = z
} else {
zone, err := topology.GetZone(vmCtx, client, vmCtx.VM.Labels[topology.KubernetesTopologyZoneLabelKey], vmCtx.VM.Namespace)
if err != nil {
return nil, err
}
zones = append(zones, zone)
}
for _, zone := range zones {
rpMoIDs := zone.Spec.ManagedVMs.PoolMoIDs
if childRPName != "" {
childRPMoIDs := lookupChildRPs(vmCtx, vcClient, rpMoIDs, zone.Name, childRPName)
if len(childRPMoIDs) == 0 {
vmCtx.Logger.Info("Zone had no candidates after looking up children ResourcePools",
"zone", zone.Name, "rpMoIDs", rpMoIDs, "childRPName", childRPName)
continue
}
rpMoIDs = childRPMoIDs
}

candidates[zone.Name] = rpMoIDs
}
return candidates, nil
}

// When FSS_WCP_WORKLOAD_DOMAIN_ISOLATION is disabled, use cluster scoped AvailabilityZone CR to get candidate resource pools.
var azs []topologyv1.AvailabilityZone
if zonePlacement {
z, err := topology.GetAvailabilityZones(vmCtx, client)
az, err := topology.GetAvailabilityZones(vmCtx, client)
if err != nil {
return nil, err
}

zones = z
azs = az
} else {
// Consider candidates only within the already assigned zone.
// NOTE: GetAvailabilityZone() will return a "default" AZ when the FSS is not enabled.
zone, err := topology.GetAvailabilityZone(vmCtx, client, vmCtx.VM.Labels[topology.KubernetesTopologyZoneLabelKey])
// NOTE: GetAvailabilityZone() will return a "default" AZ when WCP_FaultDomains FSS is not enabled.
az, err := topology.GetAvailabilityZone(vmCtx, client, vmCtx.VM.Labels[topology.KubernetesTopologyZoneLabelKey])
if err != nil {
return nil, err
}

zones = append(zones, zone)
azs = append(azs, az)
}

candidates := map[string][]string{}

for _, zone := range zones {
nsInfo, ok := zone.Spec.Namespaces[vmCtx.VM.Namespace]
for _, az := range azs {
nsInfo, ok := az.Spec.Namespaces[vmCtx.VM.Namespace]
if !ok {
continue
}
Expand All @@ -129,16 +162,16 @@ func getPlacementCandidates(
}

if childRPName != "" {
childRPMoIDs := lookupChildRPs(vmCtx, vcClient, rpMoIDs, zone.Name, childRPName)
childRPMoIDs := lookupChildRPs(vmCtx, vcClient, rpMoIDs, az.Name, childRPName)
if len(childRPMoIDs) == 0 {
vmCtx.Logger.Info("Zone had no candidates after looking up children ResourcePools",
"zone", zone.Name, "rpMoIDs", rpMoIDs, "childRPName", childRPName)
vmCtx.Logger.Info("AvailabilityZone had no candidates after looking up children ResourcePools",
"az", az.Name, "rpMoIDs", rpMoIDs, "childRPName", childRPName)
continue
}
rpMoIDs = childRPMoIDs
}

candidates[zone.Name] = rpMoIDs
candidates[az.Name] = rpMoIDs
}

return candidates, nil
Expand Down
Loading

0 comments on commit 8a4b4c0

Please sign in to comment.