github.com/verrazzano/verrazzano@v1.7.1/tests/e2e/pkg/test/framework/file_upload_util.go (about)

     1  // Copyright (c) 2022, 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 framework
     5  
     6  import (
     7  	"context"
     8  	"errors"
     9  	"fmt"
    10  	"github.com/oracle/oci-go-sdk/v53/common"
    11  	"github.com/oracle/oci-go-sdk/v53/common/auth"
    12  	"github.com/oracle/oci-go-sdk/v53/objectstorage"
    13  	"github.com/verrazzano/verrazzano/tests/e2e/pkg"
    14  	"io"
    15  	"net/http"
    16  	"os"
    17  	"path"
    18  	"time"
    19  )
    20  
    21  var (
    22  	userName = os.Getenv("FILE_READ_USER")
    23  	password = os.Getenv("FILE_READ_PASSWORD")
    24  )
    25  
    26  // getObjectStorageClient returns an OCI SDK client for ObjectStorage. If a region is specified then use an instance
    27  // principal auth provider, otherwise use the default provider (auth config comes from
    28  // an OCI config file or environment variables).
    29  func getObjectStorageClient(region string) (objectstorage.ObjectStorageClient, error) {
    30  	var provider common.ConfigurationProvider
    31  	var err error
    32  
    33  	if region != "" {
    34  		pkg.Log(pkg.Info, fmt.Sprintf("Using OCI SDK instance principal provider with region: %s\n", region))
    35  		provider, err = auth.InstancePrincipalConfigurationProviderForRegion(common.StringToRegion(region))
    36  	} else {
    37  		pkg.Log(pkg.Info, fmt.Sprintln("Using OCI SDK default provider"))
    38  		provider = common.DefaultConfigProvider()
    39  	}
    40  
    41  	if err != nil {
    42  		return objectstorage.ObjectStorageClient{}, err
    43  	}
    44  	return objectstorage.NewObjectStorageClientWithConfigurationProvider(provider)
    45  }
    46  
    47  // createBucket creates the bucket with the name name in the compartment compartmentID, if it doesn't exist.
    48  func createBucket(client objectstorage.ObjectStorageClient, compartmentID, namespace, name string) error {
    49  	req := objectstorage.GetBucketRequest{
    50  		NamespaceName: &namespace,
    51  		BucketName:    &name,
    52  	}
    53  
    54  	// verify if bucket exists
    55  	response, err := client.GetBucket(context.Background(), req)
    56  	if err == nil {
    57  		pkg.Log(pkg.Info, fmt.Sprintf("Bucket with the name: %s found in the namespace: %s\n", name, namespace))
    58  		return nil
    59  	}
    60  
    61  	// Create the bucket for all the HTTP 4xx error
    62  	if response.RawResponse.StatusCode >= http.StatusBadRequest && response.RawResponse.StatusCode <= http.StatusInternalServerError {
    63  		req := objectstorage.CreateBucketRequest{
    64  			CreateBucketDetails: objectstorage.CreateBucketDetails{StorageTier: objectstorage.CreateBucketDetailsStorageTierStandard,
    65  				Versioning:          objectstorage.CreateBucketDetailsVersioningDisabled,
    66  				CompartmentId:       &compartmentID,
    67  				ObjectEventsEnabled: common.Bool(true),
    68  				Name:                &name,
    69  				PublicAccessType:    objectstorage.CreateBucketDetailsPublicAccessTypeObjectreadwithoutlist},
    70  			NamespaceName: common.String(namespace),
    71  		}
    72  		_, err := client.CreateBucket(context.Background(), req)
    73  		if err != nil {
    74  			pkg.Log(pkg.Info, fmt.Sprintf("An error occurred while creating the bucket: %s\n", err))
    75  			return err
    76  		}
    77  		pkg.Log(pkg.Debug, fmt.Sprintf("Successfully created the bucket: %s\n", err))
    78  	}
    79  	return nil
    80  }
    81  
    82  // uploadObject uploads the given object to the Object Storage in the given bucket.
    83  func uploadObject(client objectstorage.ObjectStorageClient, fileURL, fileName, namespace, bucket string) error {
    84  	remoteFile := path.Base(fileURL)
    85  	err := downloadFile(fileURL, remoteFile)
    86  	if err != nil {
    87  		return err
    88  	}
    89  
    90  	// Open the named file for reading.
    91  	file, openErr := os.Open(remoteFile)
    92  	if openErr != nil {
    93  		pkg.Log(pkg.Info, fmt.Sprintf("There is an error in opening the file for reading: %s\n", openErr))
    94  		return err
    95  	}
    96  	defer file.Close()
    97  
    98  	// Get the fileName from the last element of the path
    99  	if fileName == "" {
   100  		fileName = remoteFile
   101  	}
   102  
   103  	// Get the FileInfo structure to determine the size
   104  	fileInfo, _ := file.Stat()
   105  	contentLen := fileInfo.Size()
   106  
   107  	req := objectstorage.PutObjectRequest{
   108  		NamespaceName: &namespace,
   109  		BucketName:    &bucket,
   110  		ObjectName:    &fileName,
   111  		ContentLength: &contentLen,
   112  		PutObjectBody: file,
   113  		StorageTier:   objectstorage.PutObjectStorageTierStandard,
   114  	}
   115  	_, uploadErr := client.PutObject(context.Background(), req)
   116  	if uploadErr != nil {
   117  		pkg.Log(pkg.Info, fmt.Sprintf("There is an error in uploading the file to the Object Storage: %s\n", uploadErr))
   118  		return uploadErr
   119  	}
   120  	pkg.Log(pkg.Info, fmt.Sprintf("Successfully uploaded %s to the bucket %s\n", fileName, bucket))
   121  	return nil
   122  }
   123  
   124  // downloadFile downloads the file at the fileURL to local file system.
   125  func downloadFile(fileURL, localFile string) error {
   126  	client := http.Client{Timeout: 30 * time.Minute}
   127  	req, err := http.NewRequest(http.MethodGet, fileURL, http.NoBody)
   128  	if err != nil {
   129  		pkg.Log(pkg.Error, fmt.Sprintf("There is an error while creating a new request: %s\n", err))
   130  		return err
   131  	}
   132  
   133  	// Set environment variables FILE_READ_USER and FILE_READ_PASSWORD, if required to download the file
   134  	if userName != "" && password != "" {
   135  		req.SetBasicAuth(userName, password)
   136  	} else {
   137  		pkg.Log(pkg.Info, fmt.Sprintln("Username and/password used for HTTP Basic Authentication is not set"))
   138  	}
   139  
   140  	res, respErr := client.Do(req)
   141  	if respErr != nil {
   142  		pkg.Log(pkg.Error, fmt.Sprintf("There is an error while sending an HTTP request: %s\n", respErr))
   143  		return respErr
   144  	}
   145  	defer res.Body.Close()
   146  
   147  	if 200 != res.StatusCode {
   148  		pkg.Log(pkg.Error, fmt.Sprintf("Downloading the file failed with error code: %d\n", res.StatusCode))
   149  		return errors.New("HTTP Error other than 200")
   150  	}
   151  
   152  	// create the local file
   153  	outFile, createErr := os.Create(localFile)
   154  	if createErr != nil {
   155  		pkg.Log(pkg.Error, fmt.Sprintf("There is an error creating the file: %s\n", localFile))
   156  		return createErr
   157  	}
   158  
   159  	// Write the body to the file
   160  	_, copyErr := io.Copy(outFile, res.Body)
   161  	if copyErr != nil {
   162  		pkg.Log(pkg.Error, fmt.Sprintf("There is an error copying the contents to the out file: %s\n", copyErr))
   163  		return copyErr
   164  	}
   165  	defer outFile.Close()
   166  	return nil
   167  }