k8s.io/kubernetes@v1.29.3/test/e2e/storage/vsphere/connection.go (about)

     1  /*
     2  Copyright 2018 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package vsphere
    18  
    19  import (
    20  	"context"
    21  	"fmt"
    22  	"net"
    23  	neturl "net/url"
    24  	"sync"
    25  
    26  	"github.com/vmware/govmomi"
    27  	"github.com/vmware/govmomi/session"
    28  	"github.com/vmware/govmomi/vim25"
    29  	"k8s.io/klog/v2"
    30  )
    31  
    32  const (
    33  	roundTripperDefaultCount = 3
    34  )
    35  
    36  var (
    37  	clientLock sync.Mutex
    38  )
    39  
    40  // Connect makes connection to vSphere
    41  // No actions are taken if a connection exists and alive. Otherwise, a new client will be created.
    42  func Connect(ctx context.Context, vs *VSphere) error {
    43  	var err error
    44  	clientLock.Lock()
    45  	defer clientLock.Unlock()
    46  
    47  	if vs.Client == nil {
    48  		vs.Client, err = NewClient(ctx, vs)
    49  		if err != nil {
    50  			klog.Errorf("Failed to create govmomi client. err: %+v", err)
    51  			return err
    52  		}
    53  		return nil
    54  	}
    55  	manager := session.NewManager(vs.Client.Client)
    56  	userSession, err := manager.UserSession(ctx)
    57  	if err != nil {
    58  		klog.Errorf("Error while obtaining user session. err: %+v", err)
    59  		return err
    60  	}
    61  	if userSession != nil {
    62  		return nil
    63  	}
    64  	klog.Warningf("Creating new client session since the existing session is not valid or not authenticated")
    65  	vs.Client.Logout(ctx)
    66  	vs.Client, err = NewClient(ctx, vs)
    67  	if err != nil {
    68  		klog.Errorf("Failed to create govmomi client. err: %+v", err)
    69  		return err
    70  	}
    71  	return nil
    72  }
    73  
    74  // NewClient creates a new client for vSphere connection
    75  func NewClient(ctx context.Context, vs *VSphere) (*govmomi.Client, error) {
    76  	url, err := neturl.Parse(fmt.Sprintf("https://%s/sdk", net.JoinHostPort(vs.Config.Hostname, vs.Config.Port)))
    77  	if err != nil {
    78  		klog.Errorf("Failed to parse URL: %s. err: %+v", url, err)
    79  		return nil, err
    80  	}
    81  	url.User = neturl.UserPassword(vs.Config.Username, vs.Config.Password)
    82  	client, err := govmomi.NewClient(ctx, url, true)
    83  	if err != nil {
    84  		klog.Errorf("Failed to create new client. err: %+v", err)
    85  		return nil, err
    86  	}
    87  	if vs.Config.RoundTripperCount == 0 {
    88  		vs.Config.RoundTripperCount = roundTripperDefaultCount
    89  	}
    90  	client.RoundTripper = vim25.Retry(client.RoundTripper, vim25.TemporaryNetworkError(int(vs.Config.RoundTripperCount)))
    91  	return client, nil
    92  }