From 051aa190e91126444b5c6eda12e7d7e6a762c86c Mon Sep 17 00:00:00 2001 From: dagnello Date: Wed, 6 Apr 2016 18:10:12 -0700 Subject: [PATCH] Adding vSphere Instances Scaffolding --- .../providers/vsphere/vsphere.go | 74 +++++++++++++------ .../providers/vsphere/vsphere_test.go | 43 ++++++++++- 2 files changed, 90 insertions(+), 27 deletions(-) diff --git a/pkg/cloudprovider/providers/vsphere/vsphere.go b/pkg/cloudprovider/providers/vsphere/vsphere.go index 72b2c3132ca..14b54645a85 100644 --- a/pkg/cloudprovider/providers/vsphere/vsphere.go +++ b/pkg/cloudprovider/providers/vsphere/vsphere.go @@ -17,6 +17,7 @@ limitations under the License. package vsphere import ( + "errors" "fmt" "io" "net/url" @@ -26,24 +27,22 @@ import ( "gopkg.in/gcfg.v1" "k8s.io/kubernetes/pkg/cloudprovider" + "k8s.io/kubernetes/pkg/api" ) const ProviderName = "vsphere" // VSphere is an implementation of Interface, LoadBalancer and Instances for vSphere. type VSphere struct { - provider *govmomi.Client - region string - datacenter string - // cfg *VSphereConfig - // Add vSphere instance + cfg *VSphereConfig } type VSphereConfig struct { Global struct { User string `gcfg:"user"` Password string `gcfg:"password"` - VSphereServer string `gcfg:"server"` + VCenterIp string `gcfg:"server"` + VCenterPort string `gcfg:"port"` InsecureFlag bool `gcfg:"insecure-flag"` Datacenter string `gcfg:"datacenter"` } @@ -71,39 +70,68 @@ func init() { } func newVSphere(cfg VSphereConfig) (*VSphere, error) { - - u, err := url.Parse("https://" + cfg.Global.VSphereServer + "/sdk") - if err != nil { - return nil, fmt.Errorf("Error parse url: %s", err) - } - - u.User = url.UserPassword(cfg.Global.User, cfg.Global.Password) - - provider, err := govmomi.NewClient(context.TODO(), u, cfg.Global.InsecureFlag) - if err != nil { - return nil, err - } - vs := VSphere{ - provider: provider, - datacenter: cfg.Global.Datacenter, - // cfg *VSphereConfig, + cfg: &cfg, } return &vs, nil } +func vsphereLogin(cfg *VSphereConfig, ctx context.Context) (*govmomi.Client, error) { + + // Parse URL from string + u, err := url.Parse(fmt.Sprintf("https://%s:%s/sdk", cfg.Global.VCenterIp, cfg.Global.VCenterPort)) + if err != nil { + return nil, err + } + // set username and password for the URL + u.User = url.UserPassword(cfg.Global.User, cfg.Global.Password) + + // Connect and log in to ESX or vCenter + c, err := govmomi.NewClient(ctx, u, cfg.Global.InsecureFlag) + if err != nil { + return nil, err + } + + return c, nil +} + type Instances struct { + cfg *VSphereConfig } // Instances returns an implementation of Instances for vSphere. func (vs *VSphere) Instances() (cloudprovider.Instances, bool) { - return nil, true + return &Instances{vs.cfg}, true } func (i *Instances) List(nameFilter string) ([]string, error) { return nil, nil } +func (i *Instances) NodeAddresses(name string) ([]api.NodeAddress, error) { + return nil, nil +} + +func (i *Instances) AddSSHKeyToAllInstances(user string, keyData []byte) error { + return errors.New("unimplemented") +} + +func (i *Instances) CurrentNodeName(hostname string) (string, error) { + return hostname, nil +} + +func (i *Instances) ExternalID(name string) (string, error) { + return "", nil +} + +func (i *Instances) InstanceType(name string) (string, error) { + return "", nil +} + +func (i *Instances) InstanceID(name string) (string, error) { + return "/" + " ", nil +} + func (vs *VSphere) Clusters() (cloudprovider.Clusters, bool) { return nil, true } diff --git a/pkg/cloudprovider/providers/vsphere/vsphere_test.go b/pkg/cloudprovider/providers/vsphere/vsphere_test.go index 6fd39b1f217..06cf5f541e8 100644 --- a/pkg/cloudprovider/providers/vsphere/vsphere_test.go +++ b/pkg/cloudprovider/providers/vsphere/vsphere_test.go @@ -23,11 +23,14 @@ import ( "strconv" "strings" "testing" + + "golang.org/x/net/context" ) func configFromEnv() (cfg VSphereConfig, ok bool) { fmt.Print("inside test") - cfg.Global.VSphereServer = os.Getenv("VSPHERE_SERVER") + cfg.Global.VCenterIp = os.Getenv("VSPHERE_VCENTER") + cfg.Global.VCenterPort = os.Getenv("VSPHERE_VCENTER_PORT") cfg.Global.User = os.Getenv("VSPHERE_USER") cfg.Global.Password = os.Getenv("VSPHERE_PASSWORD") cfg.Global.Datacenter = os.Getenv("VSPHERE_DATACENTER") @@ -39,7 +42,9 @@ func configFromEnv() (cfg VSphereConfig, ok bool) { cfg.Global.InsecureFlag = InsecureFlag - ok = (cfg.Global.VSphereServer != "" && + + + ok = (cfg.Global.VCenterIp != "" && cfg.Global.User != "") return @@ -54,6 +59,7 @@ func TestReadConfig(t *testing.T) { cfg, err := readConfig(strings.NewReader(` [Global] server = 0.0.0.0 +port = 80 user = user password = password insecure-flag = true @@ -62,8 +68,13 @@ datacenter = us-west if err != nil { t.Fatalf("Should succeed when a valid config is provided: %s", err) } - if cfg.Global.VSphereServer != "0.0.0.0" { - t.Errorf("incorrect server: %s", cfg.Global.VSphereServer) + + if cfg.Global.VCenterIp != "0.0.0.0" { + t.Errorf("incorrect vcenter ip: %s", cfg.Global.VCenterIp) + } + + if cfg.Global.VCenterPort != "80" { + t.Errorf("incorrect vcenter port: %s", cfg.Global.VCenterPort) } if cfg.Global.Datacenter != "us-west" { @@ -82,3 +93,27 @@ func TestNewVSphere(t *testing.T) { t.Fatalf("Failed to construct/authenticate vSphere: %s", err) } } + +func TestVSphereLogin(t *testing.T) { + cfg, ok := configFromEnv() + if !ok { + t.Skipf("No config found in environment") + } + + // Create vSphere configuration object + vs, err := newVSphere(cfg) + if err != nil { + t.Fatalf("Failed to construct/authenticate vSphere: %s", err) + } + + // Create context + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + + // Create vSphere client + c, err := vsphereLogin(vs.cfg, ctx) + if err != nil { + t.Errorf("Failed to create vSpere client: %s", err) + } + defer c.Logout(ctx) +}