Adding vSphere cloud provider support for Instance List

This commit is contained in:
Abitha Palaniappan 2016-04-08 17:38:26 -07:00 committed by dagnello
parent 88f6a6d66b
commit 0d7d7fba60
2 changed files with 102 additions and 18 deletions

View File

@ -23,29 +23,33 @@ import (
"net/url" "net/url"
"github.com/vmware/govmomi" "github.com/vmware/govmomi"
"github.com/vmware/govmomi/find"
"github.com/vmware/govmomi/property"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/types"
"golang.org/x/net/context" "golang.org/x/net/context"
"gopkg.in/gcfg.v1" "gopkg.in/gcfg.v1"
"github.com/golang/glog" "github.com/golang/glog"
"k8s.io/kubernetes/pkg/cloudprovider"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/cloudprovider"
) )
const ProviderName = "vsphere" const ProviderName = "vsphere"
// VSphere is an implementation of Interface, LoadBalancer and Instances for vSphere. // VSphere is an implementation of Interface, LoadBalancer and Instances for vSphere.
type VSphere struct { type VSphere struct {
cfg *VSphereConfig cfg *VSphereConfig
} }
type VSphereConfig struct { type VSphereConfig struct {
Global struct { Global struct {
User string `gcfg:"user"` User string `gcfg:"user"`
Password string `gcfg:"password"` Password string `gcfg:"password"`
VCenterIp string `gcfg:"server"` VCenterIp string `gcfg:"server"`
VCenterPort string `gcfg:"port"` VCenterPort string `gcfg:"port"`
InsecureFlag bool `gcfg:"insecure-flag"` InsecureFlag bool `gcfg:"insecure-flag"`
Datacenter string `gcfg:"datacenter"` Datacenter string `gcfg:"datacenter"`
} }
} }
@ -72,12 +76,12 @@ func init() {
func newVSphere(cfg VSphereConfig) (*VSphere, error) { func newVSphere(cfg VSphereConfig) (*VSphere, error) {
vs := VSphere{ vs := VSphere{
cfg: &cfg, cfg: &cfg,
} }
return &vs, nil return &vs, nil
} }
func vsphereLogin(cfg *VSphereConfig, ctx context.Context) (*govmomi.Client, error) { func vsphereLogin(cfg *VSphereConfig, ctx context.Context) (*govmomi.Client, error) {
// Parse URL from string // Parse URL from string
u, err := url.Parse(fmt.Sprintf("https://%s:%s/sdk", cfg.Global.VCenterIp, cfg.Global.VCenterPort)) u, err := url.Parse(fmt.Sprintf("https://%s:%s/sdk", cfg.Global.VCenterIp, cfg.Global.VCenterPort))
@ -97,16 +101,72 @@ func vsphereLogin(cfg *VSphereConfig, ctx context.Context) (*govmomi.Client, err
} }
type Instances struct { type Instances struct {
cfg *VSphereConfig cfg *VSphereConfig
} }
// Instances returns an implementation of Instances for vSphere. // Instances returns an implementation of Instances for vSphere.
func (vs *VSphere) Instances() (cloudprovider.Instances, bool) { func (vs *VSphere) Instances() (cloudprovider.Instances, bool) {
return &Instances{vs.cfg}, true return &Instances{vs.cfg}, true
} }
func getInstances(c *govmomi.Client, finder *find.Finder, ctx context.Context, nameFilter string) ([]string, error) {
//TODO: get all vms inside subfolders
vms, err := finder.VirtualMachineList(ctx, nameFilter)
if err != nil {
return nil, err
}
var vmRef []types.ManagedObjectReference
for _, vm := range vms {
vmRef = append(vmRef, vm.Reference())
}
pc := property.DefaultCollector(c.Client)
var vmt []mo.VirtualMachine
err = pc.Retrieve(ctx, vmRef, []string{"name", "summary"}, &vmt)
if err != nil {
return nil, err
}
var vmList []string
for _, vm := range vmt {
vmPowerstate := vm.Summary.Runtime.PowerState
if vmPowerstate == "poweredOn" {
vmList = append(vmList, vm.Name)
}
}
return vmList, nil
}
func (i *Instances) List(nameFilter string) ([]string, error) { func (i *Instances) List(nameFilter string) ([]string, error) {
return nil, nil
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
c, err := vsphereLogin(i.cfg, ctx)
if err != nil {
fmt.Errorf("Failed to create vSpere client: %s", err)
}
defer c.Logout(ctx)
fo := find.NewFinder(c.Client, true)
dc, err := fo.Datacenter(ctx, i.cfg.Global.Datacenter)
if err != nil {
glog.Warningf("Failed to find %v", err)
return nil, err
}
finderObj := fo.SetDatacenter(dc)
vmList, err := getInstances(c, finderObj, ctx, nameFilter)
if err != nil {
return nil, err
}
glog.V(3).Infof("Found %v instances matching %v: %v",
len(vmList), nameFilter, vmList)
return vmList, nil
} }
func (i *Instances) NodeAddresses(name string) ([]api.NodeAddress, error) { func (i *Instances) NodeAddresses(name string) ([]api.NodeAddress, error) {

View File

@ -17,7 +17,6 @@ limitations under the License.
package vsphere package vsphere
import ( import (
"fmt"
"log" "log"
"os" "os"
"strconv" "strconv"
@ -28,7 +27,6 @@ import (
) )
func configFromEnv() (cfg VSphereConfig, ok bool) { func configFromEnv() (cfg VSphereConfig, ok bool) {
fmt.Print("inside test")
cfg.Global.VCenterIp = os.Getenv("VSPHERE_VCENTER") cfg.Global.VCenterIp = os.Getenv("VSPHERE_VCENTER")
cfg.Global.VCenterPort = os.Getenv("VSPHERE_VCENTER_PORT") cfg.Global.VCenterPort = os.Getenv("VSPHERE_VCENTER_PORT")
cfg.Global.User = os.Getenv("VSPHERE_USER") cfg.Global.User = os.Getenv("VSPHERE_USER")
@ -42,8 +40,6 @@ func configFromEnv() (cfg VSphereConfig, ok bool) {
cfg.Global.InsecureFlag = InsecureFlag cfg.Global.InsecureFlag = InsecureFlag
ok = (cfg.Global.VCenterIp != "" && ok = (cfg.Global.VCenterIp != "" &&
cfg.Global.User != "") cfg.Global.User != "")
@ -59,7 +55,7 @@ func TestReadConfig(t *testing.T) {
cfg, err := readConfig(strings.NewReader(` cfg, err := readConfig(strings.NewReader(`
[Global] [Global]
server = 0.0.0.0 server = 0.0.0.0
port = 80 port = 443
user = user user = user
password = password password = password
insecure-flag = true insecure-flag = true
@ -73,7 +69,7 @@ datacenter = us-west
t.Errorf("incorrect vcenter ip: %s", cfg.Global.VCenterIp) t.Errorf("incorrect vcenter ip: %s", cfg.Global.VCenterIp)
} }
if cfg.Global.VCenterPort != "80" { if cfg.Global.VCenterPort != "443" {
t.Errorf("incorrect vcenter port: %s", cfg.Global.VCenterPort) t.Errorf("incorrect vcenter port: %s", cfg.Global.VCenterPort)
} }
@ -142,3 +138,31 @@ func TestZones(t *testing.T) {
t.Fatalf("GetZone() returned wrong region (%s)", zone.Region) t.Fatalf("GetZone() returned wrong region (%s)", zone.Region)
} }
} }
func TestInstances(t *testing.T) {
cfg, ok := configFromEnv()
if !ok {
t.Skipf("No config found in environment")
}
vs, err := newVSphere(cfg)
if err != nil {
t.Fatalf("Failed to construct/authenticate vSphere: %s", err)
}
i, ok := vs.Instances()
if !ok {
t.Fatalf("Instances() returned false")
}
srvs, err := i.List("*")
if err != nil {
t.Fatalf("Instances.List() failed: %s", err)
}
if len(srvs) == 0 {
t.Fatalf("Instances.List() returned zero servers")
}
t.Logf("Found servers (%d): %s\n", len(srvs), srvs)
}