mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-24 12:15:52 +00:00
Add zones support for vSphere cloud provider (in-tree)
This commit is contained in:
parent
0c8fe56ea4
commit
99abd4bc79
@ -82,6 +82,21 @@ func (dc *Datacenter) GetVMByUUID(ctx context.Context, vmUUID string) (*VirtualM
|
||||
return &virtualMachine, nil
|
||||
}
|
||||
|
||||
// GetHostByVMUUID gets the host object from the given vmUUID
|
||||
func (dc *Datacenter) GetHostByVMUUID(ctx context.Context, vmUUID string) (*types.ManagedObjectReference, error) {
|
||||
virtualMachine, err := dc.GetVMByUUID(ctx, vmUUID)
|
||||
var vmMo mo.VirtualMachine
|
||||
pc := property.DefaultCollector(virtualMachine.Client())
|
||||
err = pc.RetrieveOne(ctx, virtualMachine.Reference(), []string{"summary.runtime.host"}, &vmMo)
|
||||
if err != nil {
|
||||
glog.Errorf("Failed to retrive VM runtime host, err: %v", err)
|
||||
return nil, err
|
||||
}
|
||||
host := vmMo.Summary.Runtime.Host
|
||||
glog.Infof("%s host is %s", virtualMachine.Reference(), vmMo.Summary.Runtime.Host)
|
||||
return host, nil
|
||||
}
|
||||
|
||||
// GetVMByPath gets the VM object from the given vmPath
|
||||
// vmPath should be the full path to VM and not just the name
|
||||
func (dc *Datacenter) GetVMByPath(ctx context.Context, vmPath string) (*VirtualMachine, error) {
|
||||
|
@ -22,6 +22,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"net"
|
||||
"net/url"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
@ -33,6 +34,7 @@ import (
|
||||
"gopkg.in/gcfg.v1"
|
||||
|
||||
"github.com/golang/glog"
|
||||
"github.com/vmware/govmomi/vapi/tags"
|
||||
"k8s.io/api/core/v1"
|
||||
k8stypes "k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/client-go/informers"
|
||||
@ -177,6 +179,12 @@ type VSphereConfig struct {
|
||||
DefaultDatastore string `gcfg:"default-datastore"`
|
||||
ResourcePoolPath string `gcfg:"resourcepool-path"`
|
||||
}
|
||||
|
||||
// Tag categories and tags which correspond to "built-in node labels: zones and region"
|
||||
Labels struct {
|
||||
Zone string `gcfg:"zone"`
|
||||
Region string `gcfg:"region"`
|
||||
}
|
||||
}
|
||||
|
||||
type Volumes interface {
|
||||
@ -808,8 +816,11 @@ func (vs *VSphere) LoadBalancer() (cloudprovider.LoadBalancer, bool) {
|
||||
|
||||
// Zones returns an implementation of Zones for vSphere.
|
||||
func (vs *VSphere) Zones() (cloudprovider.Zones, bool) {
|
||||
glog.V(1).Info("The vSphere cloud provider does not support zones")
|
||||
return nil, false
|
||||
if vs.cfg == nil {
|
||||
glog.V(1).Info("The vSphere cloud provider does not support zones")
|
||||
return nil, false
|
||||
}
|
||||
return vs, true
|
||||
}
|
||||
|
||||
// Routes returns a false since the interface is not supported for vSphere.
|
||||
@ -1306,3 +1317,99 @@ func (vs *VSphere) NodeManager() (nodeManager *NodeManager) {
|
||||
}
|
||||
return vs.nodeManager
|
||||
}
|
||||
|
||||
func withTagsClient(ctx context.Context, connection *vclib.VSphereConnection, f func(c *tags.RestClient) error) error {
|
||||
vsURL := connection.Client.URL()
|
||||
vsURL.User = url.UserPassword(connection.Username, connection.Password)
|
||||
c := tags.NewClient(vsURL, connection.Insecure, "")
|
||||
if err := c.Login(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
defer c.Logout(ctx)
|
||||
return f(c)
|
||||
}
|
||||
|
||||
// GetZone implements Zones.GetZone
|
||||
func (vs *VSphere) GetZone(ctx context.Context) (cloudprovider.Zone, error) {
|
||||
nodeName, err := vs.CurrentNodeName(ctx, vs.hostName)
|
||||
if err != nil {
|
||||
glog.Errorf("Cannot get node name.")
|
||||
return cloudprovider.Zone{}, err
|
||||
}
|
||||
zone := cloudprovider.Zone{}
|
||||
vsi, err := vs.getVSphereInstanceForServer(vs.cfg.Workspace.VCenterIP, ctx)
|
||||
if err != nil {
|
||||
glog.Errorf("Cannot connent to vsphere. Get zone for node %s error", nodeName)
|
||||
return cloudprovider.Zone{}, err
|
||||
}
|
||||
dc, err := vclib.GetDatacenter(ctx, vsi.conn, vs.cfg.Workspace.Datacenter)
|
||||
if err != nil {
|
||||
glog.Errorf("Cannot connent to datacenter. Get zone for node %s error", nodeName)
|
||||
return cloudprovider.Zone{}, err
|
||||
}
|
||||
vmHost, err := dc.GetHostByVMUUID(ctx, vs.vmUUID)
|
||||
if err != nil {
|
||||
glog.Errorf("Cannot find VM runtime host. Get zone for node %s error", nodeName)
|
||||
return cloudprovider.Zone{}, err
|
||||
}
|
||||
client := vsi.conn
|
||||
err = withTagsClient(ctx, client, func(client *tags.RestClient) error {
|
||||
tags, err := client.ListAttachedTags(ctx, vmHost)
|
||||
if err != nil {
|
||||
glog.Errorf("Cannot list attached tags. Get zone for node %s error", nodeName)
|
||||
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 {
|
||||
|
||||
case category.Name == vs.cfg.Labels.Zone:
|
||||
zone.FailureDomain = tag.Name
|
||||
|
||||
case category.Name == vs.cfg.Labels.Region:
|
||||
zone.Region = tag.Name
|
||||
|
||||
default:
|
||||
zone.FailureDomain = ""
|
||||
zone.Region = ""
|
||||
}
|
||||
}
|
||||
switch {
|
||||
case zone.Region == "":
|
||||
if vs.cfg.Labels.Zone != "" {
|
||||
return fmt.Errorf("The zone in vSphere configuration file not match for node %s ", nodeName)
|
||||
}
|
||||
glog.Infof("No zones support for node %s error", nodeName)
|
||||
return nil
|
||||
case zone.FailureDomain == "":
|
||||
if vs.cfg.Labels.Region != "" {
|
||||
return fmt.Errorf("The zone in vSphere configuration file not match for node %s ", nodeName)
|
||||
}
|
||||
glog.Infof("No zones support for node %s error", nodeName)
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
glog.Errorf("Get zone for node %s error", nodeName)
|
||||
return cloudprovider.Zone{}, err
|
||||
}
|
||||
return zone, nil
|
||||
}
|
||||
|
||||
func (vs *VSphere) GetZoneByNodeName(ctx context.Context, nodeName k8stypes.NodeName) (cloudprovider.Zone, error) {
|
||||
return cloudprovider.Zone{}, cloudprovider.NotImplemented
|
||||
}
|
||||
|
||||
func (vs *VSphere) GetZoneByProviderID(ctx context.Context, providerID string) (cloudprovider.Zone, error) {
|
||||
return cloudprovider.Zone{}, cloudprovider.NotImplemented
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user