vsphere: support zone tags at any level in the hierarchy
Rather than just looking for zone tags at the VM's Host level, traverse up the hierarchy. This allows zone tags to be attached at host level, along with cluster, datacenter, root folder and any inventory folders in between. Issue #64021
This commit is contained in:
parent
83030032ad
commit
ec732d8aab
@ -36,6 +36,7 @@ import (
|
|||||||
"github.com/golang/glog"
|
"github.com/golang/glog"
|
||||||
"github.com/vmware/govmomi/vapi/rest"
|
"github.com/vmware/govmomi/vapi/rest"
|
||||||
"github.com/vmware/govmomi/vapi/tags"
|
"github.com/vmware/govmomi/vapi/tags"
|
||||||
|
"github.com/vmware/govmomi/vim25/mo"
|
||||||
"k8s.io/api/core/v1"
|
"k8s.io/api/core/v1"
|
||||||
k8stypes "k8s.io/apimachinery/pkg/types"
|
k8stypes "k8s.io/apimachinery/pkg/types"
|
||||||
"k8s.io/client-go/informers"
|
"k8s.io/client-go/informers"
|
||||||
@ -1352,31 +1353,51 @@ func (vs *VSphere) GetZone(ctx context.Context) (cloudprovider.Zone, error) {
|
|||||||
glog.Errorf("Cannot find VM runtime host. Get zone for node %s error", nodeName)
|
glog.Errorf("Cannot find VM runtime host. Get zone for node %s error", nodeName)
|
||||||
return cloudprovider.Zone{}, err
|
return cloudprovider.Zone{}, err
|
||||||
}
|
}
|
||||||
client := vsi.conn
|
|
||||||
err = withTagsClient(ctx, client, func(c *rest.Client) error {
|
pc := vsi.conn.Client.ServiceContent.PropertyCollector
|
||||||
|
err = withTagsClient(ctx, vsi.conn, func(c *rest.Client) error {
|
||||||
client := tags.NewManager(c)
|
client := tags.NewManager(c)
|
||||||
tags, err := client.ListAttachedTags(ctx, vmHost)
|
// example result: ["Folder", "Datacenter", "Cluster", "Host"]
|
||||||
|
objects, err := mo.Ancestors(ctx, vsi.conn.Client, pc, *vmHost)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Errorf("Cannot list attached tags. Get zone for node %s error", nodeName)
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
for _, value := range tags {
|
|
||||||
tag, err := client.GetTag(ctx, value)
|
|
||||||
if err != nil {
|
|
||||||
glog.Errorf("Get tag %s error", value)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
category, err := client.GetCategory(ctx, tag.CategoryID)
|
|
||||||
if err != nil {
|
|
||||||
glog.Errorf("Get category %s error", value)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
switch {
|
// search the hierarchy, example order: ["Host", "Cluster", "Datacenter", "Folder"]
|
||||||
case category.Name == vs.cfg.Labels.Zone:
|
for i := range objects {
|
||||||
zone.FailureDomain = tag.Name
|
obj := objects[len(objects)-1-i]
|
||||||
case category.Name == vs.cfg.Labels.Region:
|
tags, err := client.ListAttachedTags(ctx, obj)
|
||||||
zone.Region = tag.Name
|
if err != nil {
|
||||||
|
glog.Errorf("Cannot list attached tags. Get zone for node %s: %s", nodeName, err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for _, value := range tags {
|
||||||
|
tag, err := client.GetTag(ctx, value)
|
||||||
|
if err != nil {
|
||||||
|
glog.Errorf("Get tag %s: %s", value, err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
category, err := client.GetCategory(ctx, tag.CategoryID)
|
||||||
|
if err != nil {
|
||||||
|
glog.Errorf("Get category %s error", value)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
found := func() {
|
||||||
|
glog.Errorf("Found %q tag (%s) for %s attached to %s", category.Name, tag.Name, vs.vmUUID, obj.Reference())
|
||||||
|
}
|
||||||
|
switch {
|
||||||
|
case category.Name == vs.cfg.Labels.Zone:
|
||||||
|
zone.FailureDomain = tag.Name
|
||||||
|
found()
|
||||||
|
case category.Name == vs.cfg.Labels.Region:
|
||||||
|
zone.Region = tag.Name
|
||||||
|
found()
|
||||||
|
}
|
||||||
|
|
||||||
|
if zone.FailureDomain != "" && zone.Region != "" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1394,7 +1415,7 @@ func (vs *VSphere) GetZone(ctx context.Context) (cloudprovider.Zone, error) {
|
|||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
glog.Errorf("Get zone for node %s error", nodeName)
|
glog.Errorf("Get zone for node %s: %s", nodeName, err)
|
||||||
return cloudprovider.Zone{}, err
|
return cloudprovider.Zone{}, err
|
||||||
}
|
}
|
||||||
return zone, nil
|
return zone, nil
|
||||||
|
@ -451,7 +451,7 @@ func TestZones(t *testing.T) {
|
|||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
}},
|
}},
|
||||||
{"dc region, cluster zone", true, func() {
|
{"dc region, cluster zone", false, func() {
|
||||||
var h mo.HostSystem
|
var h mo.HostSystem
|
||||||
if err = pc.RetrieveOne(ctx, host.Reference(), []string{"parent"}, &h); err != nil {
|
if err = pc.RetrieveOne(ctx, host.Reference(), []string{"parent"}, &h); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@ -464,8 +464,6 @@ func TestZones(t *testing.T) {
|
|||||||
if err = m.AttachTag(ctx, zoneID, h.Parent); err != nil {
|
if err = m.AttachTag(ctx, zoneID, h.Parent); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: this should pass with Datacenter tagged as the region and Cluster tagged as the zone
|
|
||||||
}},
|
}},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user