github.com/jfrog/jfrog-cli-go@v1.22.1-0.20200318093948-4826ef344ffd/artifactory/utils/dependenciesutils.go (about)

     1  package utils
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	bintrayutils "github.com/jfrog/jfrog-cli-go/bintray/utils"
     7  	"github.com/jfrog/jfrog-cli-go/utils/cliutils"
     8  	"github.com/jfrog/jfrog-cli-go/utils/config"
     9  	rthttpclient "github.com/jfrog/jfrog-client-go/artifactory/httpclient"
    10  	"github.com/jfrog/jfrog-client-go/bintray"
    11  	"github.com/jfrog/jfrog-client-go/bintray/auth"
    12  	"github.com/jfrog/jfrog-client-go/bintray/services"
    13  	"github.com/jfrog/jfrog-client-go/bintray/services/utils"
    14  	"github.com/jfrog/jfrog-client-go/httpclient"
    15  	"github.com/jfrog/jfrog-client-go/utils/errorutils"
    16  	"github.com/jfrog/jfrog-client-go/utils/io/fileutils"
    17  	"github.com/jfrog/jfrog-client-go/utils/log"
    18  	"net/http"
    19  	"os"
    20  	"path"
    21  )
    22  
    23  const (
    24  	// This env var should be used for downloading the extractor jars through an Artifactory remote
    25  	// repository, instead of downloading directly from jcenter. The remote repository should be
    26  	// configured to proxy jcenter.
    27  	// The env var should store a server ID configured by JFrog CLI.
    28  	JCenterRemoteServerEnv = "JFROG_CLI_JCENTER_REMOTE_SERVER"
    29  	// If the JCenterRemoteServerEnv env var is used, a maven remote repository named jcenter is assumed.
    30  	// This env var can be used to use a different remote repository name.
    31  	JCenterRemoteRepoEnv = "JFROG_CLI_JCENTER_REMOTE_REPO"
    32  )
    33  
    34  // Download the relevant build-info-extractor jar, if it does not already exist locally.
    35  // By default, the jar is downloaded directly from jcenter.
    36  // If the JCenterRemoteServerEnv environment variable is configured, the jar will be
    37  // downloaded from a remote Artifactory repository which proxies jcenter.
    38  //
    39  // downloadPath: The Bintray or Artifactory download path.
    40  // filename: The local file name.
    41  // targetPath: The local download path (without the file name).
    42  func DownloadExtractorIfNeeded(downloadPath, targetPath string) error {
    43  	// If the file exists locally, we're done.
    44  	exists, err := fileutils.IsFileExists(targetPath, false)
    45  	if exists || err != nil {
    46  		return err
    47  	}
    48  
    49  	artDetails, remotePath, err := GetJcenterRemoteDetails(downloadPath)
    50  	if err != nil {
    51  		return err
    52  	}
    53  
    54  	// Download through a remote repository in Artifactory, if configured to do so.
    55  	if artDetails != nil {
    56  		return downloadFileFromArtifactory(artDetails, remotePath, targetPath)
    57  	}
    58  
    59  	// If not configured to download through a remote repository in Artifactory,
    60  	// download from jcenter.
    61  	return downloadFileFromBintray(remotePath, targetPath)
    62  }
    63  
    64  func GetJcenterRemoteDetails(downloadPath string) (artDetails *config.ArtifactoryDetails, remotePath string, err error) {
    65  	// Download through a remote repository in Artifactory, if configured to do so.
    66  	serverId := os.Getenv(JCenterRemoteServerEnv)
    67  	if serverId != "" {
    68  		artDetails, err = config.GetArtifactoryConf(serverId)
    69  		if err != nil {
    70  			return
    71  		}
    72  
    73  		remotePath = path.Join(getJcenterRemoteRepoName(), downloadPath)
    74  		return
    75  	}
    76  
    77  	// If not configured to download through a remote repository in Artifactory,
    78  	// download from jcenter.
    79  	remotePath = path.Join("bintray/jcenter", downloadPath)
    80  	return
    81  }
    82  
    83  func getJcenterRemoteRepoName() string {
    84  	jcenterRemoteRepo := os.Getenv(JCenterRemoteRepoEnv)
    85  	if jcenterRemoteRepo == "" {
    86  		jcenterRemoteRepo = "jcenter"
    87  	}
    88  	return jcenterRemoteRepo
    89  }
    90  
    91  func downloadFileFromArtifactory(artDetails *config.ArtifactoryDetails, downloadPath, targetPath string) error {
    92  	downloadUrl := fmt.Sprintf("%s%s", artDetails.Url, downloadPath)
    93  	log.Info("Downloading build-info-extractor from", downloadUrl)
    94  	filename, localDir := fileutils.GetFileAndDirFromPath(targetPath)
    95  
    96  	downloadFileDetails := &httpclient.DownloadFileDetails{
    97  		FileName:      filename,
    98  		DownloadPath:  downloadUrl,
    99  		LocalPath:     localDir,
   100  		LocalFileName: filename,
   101  	}
   102  
   103  	auth, err := artDetails.CreateArtAuthConfig()
   104  	if err != nil {
   105  		return err
   106  	}
   107  	securityDir, err := cliutils.GetJfrogSecurityDir()
   108  	if err != nil {
   109  		return err
   110  	}
   111  
   112  	client, err := rthttpclient.ArtifactoryClientBuilder().
   113  		SetCertificatesPath(securityDir).
   114  		SetInsecureTls(artDetails.InsecureTls).
   115  		SetCommonDetails(&auth).
   116  		Build()
   117  	if err != nil {
   118  		return err
   119  	}
   120  
   121  	httpClientDetails := auth.CreateHttpClientDetails()
   122  	resp, err := client.DownloadFile(downloadFileDetails, "", &httpClientDetails, 3, false)
   123  	if err == nil && resp.StatusCode != http.StatusOK {
   124  		err = errorutils.CheckError(errors.New(resp.Status + " received when attempting to download " + downloadUrl))
   125  	}
   126  
   127  	return err
   128  }
   129  
   130  func downloadFileFromBintray(downloadPath, targetPath string) error {
   131  	bintrayConfig := auth.NewBintrayDetails()
   132  	config := bintray.NewConfigBuilder().SetBintrayDetails(bintrayConfig).Build()
   133  
   134  	pathDetails, err := utils.CreatePathDetails(downloadPath)
   135  	if err != nil {
   136  		return err
   137  	}
   138  
   139  	params := &services.DownloadFileParams{}
   140  	params.PathDetails = pathDetails
   141  	params.TargetPath = targetPath
   142  	params.Flat = true
   143  
   144  	_, _, err = bintrayutils.DownloadFileFromBintray(config, params)
   145  	return err
   146  }