vsphere: use vim25.Client directly to support token authentication

This refactor is in support of SAML token authentication: #63209
Avoid use of govmomi.Client as it only supports username+password authentication via SessionManager.Login().
Using vim25.Client directly will allow VCP to add other authentication methods,
such as SessionManager.LoginByToken().
pull/8/head
Doug MacEachern 2018-05-05 11:33:53 -07:00
parent f4b2452654
commit 64601373f1
10 changed files with 39 additions and 22 deletions

View File

@ -18,19 +18,19 @@ package vclib
import (
"context"
"fmt"
"net"
neturl "net/url"
"sync"
"github.com/golang/glog"
"github.com/vmware/govmomi"
"github.com/vmware/govmomi/session"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/soap"
)
// VSphereConnection contains information for connecting to vCenter
type VSphereConnection struct {
GoVmomiClient *govmomi.Client
GoVmomiClient *vim25.Client
Username string
Password string
Hostname string
@ -59,7 +59,7 @@ func (connection *VSphereConnection) Connect(ctx context.Context) error {
}
return nil
}
m := session.NewManager(connection.GoVmomiClient.Client)
m := session.NewManager(connection.GoVmomiClient)
userSession, err := m.UserSession(ctx)
if err != nil {
glog.Errorf("Error while obtaining user session. err: %+v", err)
@ -69,7 +69,7 @@ func (connection *VSphereConnection) Connect(ctx context.Context) error {
return nil
}
glog.Warningf("Creating new client session since the existing session is not valid or not authenticated")
connection.GoVmomiClient.Logout(ctx)
connection.GoVmomiClient, err = connection.NewClient(ctx)
if err != nil {
glog.Errorf("Failed to create govmomi client. err: %+v", err)
@ -78,19 +78,36 @@ func (connection *VSphereConnection) Connect(ctx context.Context) error {
return nil
}
// Logout calls SessionManager.Logout for the given connection.
func (connection *VSphereConnection) Logout(ctx context.Context) {
m := session.NewManager(connection.GoVmomiClient)
if err := m.Logout(ctx); err != nil {
glog.Errorf("Logout failed: %s", err)
}
}
// NewClient creates a new govmomi client for the VSphereConnection obj
func (connection *VSphereConnection) NewClient(ctx context.Context) (*govmomi.Client, error) {
url, err := neturl.Parse(fmt.Sprintf("https://%s:%s/sdk", connection.Hostname, connection.Port))
func (connection *VSphereConnection) NewClient(ctx context.Context) (*vim25.Client, error) {
url, err := soap.ParseURL(net.JoinHostPort(connection.Hostname, connection.Port))
if err != nil {
glog.Errorf("Failed to parse URL: %s. err: %+v", url, err)
return nil, err
}
url.User = neturl.UserPassword(connection.Username, connection.Password)
client, err := govmomi.NewClient(ctx, url, connection.Insecure)
sc := soap.NewClient(url, connection.Insecure)
client, err := vim25.NewClient(ctx, sc)
if err != nil {
glog.Errorf("Failed to create new client. err: %+v", err)
return nil, err
}
m := session.NewManager(client)
err = m.Login(ctx, neturl.UserPassword(connection.Username, connection.Password))
if err != nil {
return nil, err
}
if connection.RoundTripperCount == 0 {
connection.RoundTripperCount = RoundTripperDefaultCount
}

View File

@ -39,7 +39,7 @@ type Datacenter struct {
// GetDatacenter returns the DataCenter Object for the given datacenterPath
// If datacenter is located in a folder, include full path to datacenter else just provide the datacenter name
func GetDatacenter(ctx context.Context, connection *VSphereConnection, datacenterPath string) (*Datacenter, error) {
finder := find.NewFinder(connection.GoVmomiClient.Client, false)
finder := find.NewFinder(connection.GoVmomiClient, false)
datacenter, err := finder.Datacenter(ctx, datacenterPath)
if err != nil {
glog.Errorf("Failed to find the datacenter: %s. err: %+v", datacenterPath, err)
@ -52,7 +52,7 @@ func GetDatacenter(ctx context.Context, connection *VSphereConnection, datacente
// GetAllDatacenter returns all the DataCenter Objects
func GetAllDatacenter(ctx context.Context, connection *VSphereConnection) ([]*Datacenter, error) {
var dc []*Datacenter
finder := find.NewFinder(connection.GoVmomiClient.Client, false)
finder := find.NewFinder(connection.GoVmomiClient, false)
datacenters, err := finder.DatacenterList(ctx, "*")
if err != nil {
glog.Errorf("Failed to find the datacenter. err: %+v", err)

View File

@ -47,7 +47,7 @@ func TestDatacenter(t *testing.T) {
t.Fatal(err)
}
vc := &VSphereConnection{GoVmomiClient: c}
vc := &VSphereConnection{GoVmomiClient: c.Client}
_, err = GetDatacenter(ctx, vc, testNameNotFound)
if err == nil {

View File

@ -45,7 +45,7 @@ func TestDatastore(t *testing.T) {
t.Fatal(err)
}
vc := &VSphereConnection{GoVmomiClient: c}
vc := &VSphereConnection{GoVmomiClient: c.Client}
dc, err := GetDatacenter(ctx, vc, testDefaultDatacenter)
if err != nil {

View File

@ -47,7 +47,7 @@ func TestFolder(t *testing.T) {
t.Fatal(err)
}
vc := &VSphereConnection{GoVmomiClient: c}
vc := &VSphereConnection{GoVmomiClient: c.Client}
dc, err := GetDatacenter(ctx, vc, testDefaultDatacenter)
if err != nil {

View File

@ -46,7 +46,7 @@ func TestUtils(t *testing.T) {
t.Fatal(err)
}
vc := &VSphereConnection{GoVmomiClient: c}
vc := &VSphereConnection{GoVmomiClient: c.Client}
dc, err := GetDatacenter(ctx, vc, testDefaultDatacenter)
if err != nil {

View File

@ -23,9 +23,9 @@ import (
"time"
"github.com/golang/glog"
"github.com/vmware/govmomi"
"github.com/vmware/govmomi/object"
"github.com/vmware/govmomi/property"
"github.com/vmware/govmomi/vim25"
"github.com/vmware/govmomi/vim25/mo"
"github.com/vmware/govmomi/vim25/types"
)
@ -403,8 +403,8 @@ func (vm *VirtualMachine) deleteController(ctx context.Context, controllerDevice
}
// RenewVM renews this virtual machine with new client connection.
func (vm *VirtualMachine) RenewVM(client *govmomi.Client) VirtualMachine {
dc := Datacenter{Datacenter: object.NewDatacenter(client.Client, vm.Datacenter.Reference())}
newVM := object.NewVirtualMachine(client.Client, vm.VirtualMachine.Reference())
func (vm *VirtualMachine) RenewVM(client *vim25.Client) VirtualMachine {
dc := Datacenter{Datacenter: object.NewDatacenter(client, vm.Datacenter.Reference())}
newVM := object.NewVirtualMachine(client, vm.VirtualMachine.Reference())
return VirtualMachine{VirtualMachine: newVM, Datacenter: &dc}
}

View File

@ -43,7 +43,7 @@ func TestVirtualMachine(t *testing.T) {
t.Fatal(err)
}
vc := &VSphereConnection{GoVmomiClient: c}
vc := &VSphereConnection{GoVmomiClient: c.Client}
dc, err := GetDatacenter(ctx, vc, testDefaultDatacenter)
if err != nil {

View File

@ -411,7 +411,7 @@ func newControllerNode(cfg VSphereConfig) (*VSphere, error) {
func logout(vs *VSphere) {
for _, vsphereIns := range vs.vsphereInstanceMap {
if vsphereIns.conn.GoVmomiClient != nil {
vsphereIns.conn.GoVmomiClient.Logout(context.TODO())
vsphereIns.conn.Logout(context.TODO())
}
}

View File

@ -135,7 +135,7 @@ func TestVSphereLogin(t *testing.T) {
if err != nil {
t.Errorf("Failed to connect to vSphere: %s", err)
}
defer vcInstance.conn.GoVmomiClient.Logout(ctx)
defer vcInstance.conn.Logout(ctx)
}
func TestZones(t *testing.T) {