github.com/verrazzano/verrazzano@v1.7.1/tests/e2e/clusterapi/oke-capi-driver/environment.go (about)

     1  // Copyright (c) 2023, Oracle and/or its affiliates.
     2  // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
     3  
     4  package okecapidriver
     5  
     6  import (
     7  	"fmt"
     8  	"github.com/Masterminds/semver/v3"
     9  	"net/http"
    10  	"strings"
    11  
    12  	"github.com/hashicorp/go-retryablehttp"
    13  	"github.com/verrazzano/verrazzano/tests/e2e/backup/helpers"
    14  	"github.com/verrazzano/verrazzano/tests/e2e/pkg"
    15  	"go.uber.org/zap"
    16  )
    17  
    18  var (
    19  	// Initialized by ensureOKEDriverVarsInitialized, required environment variables
    20  	region                   string
    21  	vcnID                    string
    22  	userID                   string
    23  	tenancyID                string
    24  	fingerprint              string
    25  	privateKeyPath           string
    26  	nodePublicKeyPath        string
    27  	compartmentID            string
    28  	workerNodeSubnet         string
    29  	controlPlaneSubnet       string
    30  	loadBalancerSubnet       string
    31  	okeCapiClusterNameSuffix string
    32  
    33  	// Initialized by ensureOKEDriverVarsInitialized, optional overrides
    34  	dockerRootDir           string
    35  	enableClusterAlerting   bool
    36  	enableClusterMonitoring bool
    37  	enableNetworkPolicy     bool
    38  	windowsPreferedCluster  bool
    39  	clusterCidr             string
    40  	imageDisplayName        string
    41  	imageID                 string
    42  	kubernetesVersion       string
    43  	podCidr                 string
    44  	nodeShape               string
    45  	applyYAMLs              string
    46  	installVerrazzano       bool
    47  
    48  	okeSupportedVersions []string
    49  
    50  	// Initialized during before suite, and used across helper functions
    51  	rancherURL        string
    52  	httpClient        *retryablehttp.Client
    53  	cloudCredentialID string
    54  
    55  	okeMetadataItemToInstall OKEMetadataItem
    56  	okeMetadataItemToUpgrade OKEMetadataItem
    57  )
    58  
    59  // Verify required Environment Variables are set
    60  func verifyRequiredEnvironmentVariables() {
    61  	region = pkg.GetRequiredEnvVarOrFail("OCI_REGION")
    62  	userID = pkg.GetRequiredEnvVarOrFail("OCI_USER_ID")
    63  	tenancyID = pkg.GetRequiredEnvVarOrFail("OCI_TENANCY_ID")
    64  	fingerprint = pkg.GetRequiredEnvVarOrFail("OCI_CREDENTIALS_FINGERPRINT")
    65  	privateKeyPath = pkg.GetRequiredEnvVarOrFail("OCI_PRIVATE_KEY_PATH")
    66  	okeCapiClusterNameSuffix = pkg.GetRequiredEnvVarOrFail("OKE_CAPI_CLUSTER_NAME_SUFFIX")
    67  	vcnID = pkg.GetRequiredEnvVarOrFail("OCI_VCN_ID")
    68  	nodePublicKeyPath = pkg.GetRequiredEnvVarOrFail("NODE_PUBLIC_KEY_PATH")
    69  	compartmentID = pkg.GetRequiredEnvVarOrFail("OCI_COMPARTMENT_ID")
    70  	workerNodeSubnet = pkg.GetRequiredEnvVarOrFail("WORKER_NODE_SUBNET")
    71  	controlPlaneSubnet = pkg.GetRequiredEnvVarOrFail("CONTROL_PLANE_SUBNET")
    72  	loadBalancerSubnet = pkg.GetRequiredEnvVarOrFail("LOAD_BALANCER_SUBNET")
    73  }
    74  
    75  // Grabs info from optional environment variables.
    76  // Requires an existing cloud credential.
    77  func ensureOKEDriverVarsInitialized(log *zap.SugaredLogger) error {
    78  	// optional overrides
    79  	dockerRootDir = pkg.GetEnvFallback("DOCKER_ROOT_DIR", "/var/lib/docker")
    80  	enableClusterAlerting = pkg.GetEnvFallbackBool("ENABLE_CLUSTER_ALERTING", false)
    81  	enableClusterMonitoring = pkg.GetEnvFallbackBool("ENABLE_CLUSTER_MONITORING", false)
    82  	enableNetworkPolicy = pkg.GetEnvFallbackBool("ENABLE_NETWORK_POLICY", false)
    83  	windowsPreferedCluster = pkg.GetEnvFallbackBool("WINDOWS_PREFERRED_CLUSTER", false)
    84  	clusterCidr = pkg.GetEnvFallback("CLUSTER_CIDR", "10.96.0.0/16")
    85  	imageID = pkg.GetEnvFallback("IMAGE_ID", "")
    86  	podCidr = pkg.GetEnvFallback("POD_CIDR", "10.244.0.0/16")
    87  	applyYAMLs = pkg.GetEnvFallback("APPLY_YAMLS", "")
    88  	installVerrazzano = pkg.GetEnvFallbackBool("INSTALL_VERRAZZANO_ON_CAPI", false)
    89  	if err := fillOKEMetadata(log); err != nil {
    90  		return err
    91  	}
    92  	if err := fillNodeImage(log); err != nil {
    93  		return err
    94  	}
    95  	if err := fillNodeShapes(log); err != nil {
    96  		return err
    97  	}
    98  	return nil
    99  }
   100  
   101  // Initializes variables from OKE metadata ConfigMap. Values are optionally overridden.
   102  func fillOKEMetadata(log *zap.SugaredLogger) error {
   103  	// Initialize values
   104  	kubernetesVersion = pkg.GetEnvFallback("KUBERNETES_VERSION", "v1.26.2")
   105  	okeSupportedVersions = strings.Split(pkg.GetEnvFallback("OKE_VERSIONS", "v1.27.2, v1.26.7, v1.26.2, v1.25.12, v1.25.4"), ",")
   106  
   107  	for _, k8sVersion := range okeSupportedVersions {
   108  		k8sSemVerFallback, err := semver.NewVersion(strings.TrimSpace(k8sVersion))
   109  		if err != nil {
   110  			log.Errorf("kubernetes version parsing error: %s", err)
   111  			return err
   112  		}
   113  		// finding the minimum kubernetes version to install a OKE cluster
   114  		if okeMetadataItemToInstall.KubernetesVersion == nil || k8sSemVerFallback.LessThan(okeMetadataItemToInstall.KubernetesVersion) {
   115  			okeMetadataItemToInstall = OKEMetadataItem{KubernetesVersion: k8sSemVerFallback}
   116  		}
   117  		// finding the maximum kubernetes version to update the OKE cluster
   118  		if okeMetadataItemToUpgrade.KubernetesVersion == nil || k8sSemVerFallback.GreaterThan(okeMetadataItemToUpgrade.KubernetesVersion) {
   119  			okeMetadataItemToUpgrade = OKEMetadataItem{KubernetesVersion: k8sSemVerFallback}
   120  		}
   121  	}
   122  	return nil
   123  }
   124  
   125  // Initializes the node image, optionally overridden
   126  func fillNodeImage(log *zap.SugaredLogger) error {
   127  	var linuxImageFallback string
   128  
   129  	// Use Rancher API call to get fallback value
   130  	requestURL, adminToken := setupRequest(rancherURL, fmt.Sprintf("/meta/oci/nodeImages?cloudCredentialId=%s", cloudCredentialID), log)
   131  	response, err := helpers.HTTPHelper(httpClient, "GET", requestURL, adminToken, "Bearer", http.StatusOK, nil, log)
   132  	if err != nil {
   133  		log.Errorf("error requesting node images from Rancher: %s", err)
   134  		return err
   135  	}
   136  	imageList := response.Children()
   137  	for _, image := range imageList {
   138  		imageString := image.Data().(string)
   139  		// filter a suitable OL 8 image, same as what the rancher UI does
   140  		if strings.HasPrefix(imageString, "Oracle-Linux-8") && !strings.Contains(imageString, "aarch64") {
   141  			linuxImageFallback = imageString
   142  			break
   143  		}
   144  	}
   145  	if linuxImageFallback == "" {
   146  		err = fmt.Errorf("could not find a suitable node image")
   147  		log.Error(err)
   148  		return err
   149  	}
   150  
   151  	// Initialize value
   152  	imageDisplayName = pkg.GetEnvFallback("IMAGE_DISPLAY_NAME", linuxImageFallback)
   153  	return nil
   154  }
   155  
   156  // Initializes the control plane and worker node shapes, optionally overridden.
   157  func fillNodeShapes(log *zap.SugaredLogger) error {
   158  	var nodeShapeFallback string
   159  
   160  	// Use Rancher API call to get fallback values
   161  	requestURL, adminToken := setupRequest(rancherURL, fmt.Sprintf("/meta/oci/nodeShapes?cloudCredentialId=%s", cloudCredentialID), log)
   162  	response, err := helpers.HTTPHelper(httpClient, "GET", requestURL, adminToken, "Bearer", http.StatusOK, nil, log)
   163  	if err != nil {
   164  		log.Errorf("error requesting node shapes from Rancher: %s", err)
   165  		return err
   166  	}
   167  	shapeList := response.Children()
   168  	if len(shapeList) == 0 {
   169  		err = fmt.Errorf("request for node shapes to Rancher API returned an empty list")
   170  		log.Error(err)
   171  		return err
   172  	}
   173  	// If the list contains "VZ.Standard.E4.Flex", default to that, similar to the Rancher UI.
   174  	// Otherwise, use the first image in the list.
   175  	nodeShapeFallback = shapeList[0].Data().(string)
   176  	for _, shape := range shapeList {
   177  		shapeString := shape.Data().(string)
   178  		if shapeString == "VM.Standard.E4.Flex" {
   179  			nodeShapeFallback = shapeString
   180  			break
   181  		}
   182  	}
   183  
   184  	// Initialize values
   185  	nodeShape = pkg.GetEnvFallback("NODE_SHAPE", nodeShapeFallback)
   186  	return nil
   187  }