k8s.io/kubernetes@v1.29.3/test/e2e/storage/vsphere/config.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  	"errors"
    21  	"fmt"
    22  	"io"
    23  	"os"
    24  
    25  	"gopkg.in/gcfg.v1"
    26  	"k8s.io/kubernetes/test/e2e/framework"
    27  )
    28  
    29  const (
    30  	vSphereConfFileEnvVar = "VSPHERE_CONF_FILE"
    31  )
    32  
    33  var (
    34  	confFileLocation = os.Getenv(vSphereConfFileEnvVar)
    35  )
    36  
    37  // Config represents vSphere configuration
    38  type Config struct {
    39  	Username          string
    40  	Password          string
    41  	Hostname          string
    42  	Port              string
    43  	Datacenters       string
    44  	RoundTripperCount uint
    45  	DefaultDatastore  string
    46  	Folder            string
    47  }
    48  
    49  // ConfigFile represents the content of vsphere.conf file.
    50  // Users specify the configuration of one or more vSphere instances in vsphere.conf where
    51  // the Kubernetes master and worker nodes are running.
    52  type ConfigFile struct {
    53  	Global struct {
    54  		// vCenter username.
    55  		User string `gcfg:"user"`
    56  		// vCenter password in clear text.
    57  		Password string `gcfg:"password"`
    58  		// vCenter port.
    59  		VCenterPort string `gcfg:"port"`
    60  		// True if vCenter uses self-signed cert.
    61  		InsecureFlag bool `gcfg:"insecure-flag"`
    62  		// Datacenter in which VMs are located.
    63  		Datacenters string `gcfg:"datacenters"`
    64  		// Soap round tripper count (retries = RoundTripper - 1)
    65  		RoundTripperCount uint `gcfg:"soap-roundtrip-count"`
    66  	}
    67  
    68  	VirtualCenter map[string]*Config
    69  
    70  	Network struct {
    71  		// PublicNetwork is name of the network the VMs are joined to.
    72  		PublicNetwork string `gcfg:"public-network"`
    73  	}
    74  
    75  	Disk struct {
    76  		// SCSIControllerType defines SCSI controller to be used.
    77  		SCSIControllerType string `dcfg:"scsicontrollertype"`
    78  	}
    79  
    80  	// Endpoint used to create volumes
    81  	Workspace struct {
    82  		VCenterIP        string `gcfg:"server"`
    83  		Datacenter       string `gcfg:"datacenter"`
    84  		Folder           string `gcfg:"folder"`
    85  		DefaultDatastore string `gcfg:"default-datastore"`
    86  		ResourcePoolPath string `gcfg:"resourcepool-path"`
    87  	}
    88  	// Tag categories and tags which correspond to "built-in node labels: zones and region"
    89  	Labels struct {
    90  		Zone   string `gcfg:"zone"`
    91  		Region string `gcfg:"region"`
    92  	}
    93  }
    94  
    95  // GetVSphereInstances parses vsphere.conf and returns VSphere instances
    96  func GetVSphereInstances() (map[string]*VSphere, error) {
    97  	cfg, err := getConfig()
    98  	if err != nil {
    99  		return nil, err
   100  	}
   101  	return populateInstanceMap(cfg)
   102  }
   103  
   104  func getConfig() (*ConfigFile, error) {
   105  	if confFileLocation == "" {
   106  		if framework.TestContext.CloudConfig.ConfigFile == "" {
   107  			return nil, fmt.Errorf("env variable 'VSPHERE_CONF_FILE' is not set, and no config-file specified")
   108  		}
   109  		confFileLocation = framework.TestContext.CloudConfig.ConfigFile
   110  	}
   111  	confFile, err := os.Open(confFileLocation)
   112  	if err != nil {
   113  		return nil, err
   114  	}
   115  	defer confFile.Close()
   116  	cfg, err := readConfig(confFile)
   117  	if err != nil {
   118  		return nil, err
   119  	}
   120  	return &cfg, nil
   121  }
   122  
   123  // readConfig parses vSphere cloud config file into ConfigFile.
   124  func readConfig(config io.Reader) (ConfigFile, error) {
   125  	if config == nil {
   126  		err := fmt.Errorf("no vSphere cloud provider config file given")
   127  		return ConfigFile{}, err
   128  	}
   129  
   130  	var cfg ConfigFile
   131  	err := gcfg.ReadInto(&cfg, config)
   132  	return cfg, err
   133  }
   134  
   135  func populateInstanceMap(cfg *ConfigFile) (map[string]*VSphere, error) {
   136  	vsphereInstances := make(map[string]*VSphere)
   137  
   138  	if cfg.Workspace.VCenterIP == "" || cfg.Workspace.DefaultDatastore == "" || cfg.Workspace.Folder == "" || cfg.Workspace.Datacenter == "" {
   139  		msg := fmt.Sprintf("All fields in workspace are mandatory."+
   140  			" vsphere.conf does not have the workspace specified correctly. cfg.Workspace: %+v", cfg.Workspace)
   141  		framework.Logf(msg)
   142  		return nil, errors.New(msg)
   143  	}
   144  	for vcServer, vcConfig := range cfg.VirtualCenter {
   145  		framework.Logf("Initializing vc server %s", vcServer)
   146  		if vcServer == "" {
   147  			framework.Logf("vsphere.conf does not have the VirtualCenter IP address specified")
   148  			return nil, errors.New("vsphere.conf does not have the VirtualCenter IP address specified")
   149  		}
   150  		vcConfig.Hostname = vcServer
   151  
   152  		if vcConfig.Username == "" {
   153  			vcConfig.Username = cfg.Global.User
   154  		}
   155  		if vcConfig.Password == "" {
   156  			vcConfig.Password = cfg.Global.Password
   157  		}
   158  		if vcConfig.Username == "" {
   159  			msg := fmt.Sprintf("vcConfig.Username is empty for vc %s!", vcServer)
   160  			framework.Logf(msg)
   161  			return nil, errors.New(msg)
   162  		}
   163  		if vcConfig.Password == "" {
   164  			msg := fmt.Sprintf("vcConfig.Password is empty for vc %s!", vcServer)
   165  			framework.Logf(msg)
   166  			return nil, errors.New(msg)
   167  		}
   168  		if vcConfig.Port == "" {
   169  			vcConfig.Port = cfg.Global.VCenterPort
   170  		}
   171  		if vcConfig.Datacenters == "" && cfg.Global.Datacenters != "" {
   172  			vcConfig.Datacenters = cfg.Global.Datacenters
   173  		}
   174  		if vcConfig.RoundTripperCount == 0 {
   175  			vcConfig.RoundTripperCount = cfg.Global.RoundTripperCount
   176  		}
   177  
   178  		vcConfig.DefaultDatastore = cfg.Workspace.DefaultDatastore
   179  		vcConfig.Folder = cfg.Workspace.Folder
   180  
   181  		vsphereIns := VSphere{
   182  			Config: vcConfig,
   183  		}
   184  		vsphereInstances[vcServer] = &vsphereIns
   185  	}
   186  
   187  	framework.Logf("vSphere instances: %v", vsphereInstances)
   188  	return vsphereInstances, nil
   189  }