github.com/jfrog/jfrog-cli-core@v1.12.1/artifactory/utils/utils.go (about)

     1  package utils
     2  
     3  import (
     4  	"encoding/json"
     5  	"errors"
     6  	"io"
     7  	"net/http"
     8  	"net/url"
     9  	"os"
    10  	"path"
    11  	"path/filepath"
    12  
    13  	ioutils "github.com/jfrog/jfrog-client-go/utils/io"
    14  
    15  	"github.com/jfrog/jfrog-cli-core/utils/config"
    16  	"github.com/jfrog/jfrog-cli-core/utils/coreutils"
    17  	"github.com/jfrog/jfrog-client-go/access"
    18  	"github.com/jfrog/jfrog-client-go/artifactory"
    19  	"github.com/jfrog/jfrog-client-go/auth"
    20  	clientConfig "github.com/jfrog/jfrog-client-go/config"
    21  	"github.com/jfrog/jfrog-client-go/distribution"
    22  	"github.com/jfrog/jfrog-client-go/http/httpclient"
    23  	"github.com/jfrog/jfrog-client-go/utils/errorutils"
    24  )
    25  
    26  const repoDetailsUrl = "api/repositories/"
    27  
    28  func GetProjectDir(global bool) (string, error) {
    29  	configDir, err := getConfigDir(global)
    30  	if err != nil {
    31  		return "", errorutils.CheckError(err)
    32  	}
    33  	return filepath.Join(configDir, "projects"), nil
    34  }
    35  
    36  func getConfigDir(global bool) (string, error) {
    37  	if !global {
    38  		wd, err := os.Getwd()
    39  		if err != nil {
    40  			return "", err
    41  		}
    42  		return filepath.Join(wd, ".jfrog"), nil
    43  	}
    44  	return coreutils.GetJfrogHomeDir()
    45  }
    46  
    47  func GetEncryptedPasswordFromArtifactory(artifactoryAuth auth.ServiceDetails, insecureTls bool) (string, error) {
    48  	u, err := url.Parse(artifactoryAuth.GetUrl())
    49  	if err != nil {
    50  		return "", err
    51  	}
    52  	u.Path = path.Join(u.Path, "api/security/encryptedPassword")
    53  	httpClientsDetails := artifactoryAuth.CreateHttpClientDetails()
    54  	certsPath, err := coreutils.GetJfrogCertsDir()
    55  	if err != nil {
    56  		return "", err
    57  	}
    58  	client, err := httpclient.ClientBuilder().
    59  		SetCertificatesPath(certsPath).
    60  		SetInsecureTls(insecureTls).
    61  		SetClientCertPath(artifactoryAuth.GetClientCertPath()).
    62  		SetClientCertKeyPath(artifactoryAuth.GetClientCertKeyPath()).
    63  		Build()
    64  	if err != nil {
    65  		return "", err
    66  	}
    67  	resp, body, _, err := client.SendGet(u.String(), true, httpClientsDetails, "")
    68  	if err != nil {
    69  		return "", err
    70  	}
    71  
    72  	if resp.StatusCode == http.StatusOK {
    73  		return string(body), nil
    74  	}
    75  
    76  	if resp.StatusCode == http.StatusConflict {
    77  		message := "\nYour Artifactory server is not configured to encrypt passwords.\n" +
    78  			"You may use \"art config --enc-password=false\""
    79  		return "", errorutils.CheckError(errors.New(message))
    80  	}
    81  
    82  	return "", errorutils.CheckError(errors.New("Artifactory response: " + resp.Status))
    83  }
    84  
    85  func CreateServiceManager(serverDetails *config.ServerDetails, httpRetries int, isDryRun bool) (artifactory.ArtifactoryServicesManager, error) {
    86  	return CreateServiceManagerWithThreads(serverDetails, isDryRun, 0, httpRetries)
    87  }
    88  
    89  // Create a service manager with threads.
    90  // If the value sent for httpRetries is negative, the default will be used.
    91  func CreateServiceManagerWithThreads(serverDetails *config.ServerDetails, isDryRun bool, threads, httpRetries int) (artifactory.ArtifactoryServicesManager, error) {
    92  	certsPath, err := coreutils.GetJfrogCertsDir()
    93  	if err != nil {
    94  		return nil, err
    95  	}
    96  	artAuth, err := serverDetails.CreateArtAuthConfig()
    97  	if err != nil {
    98  		return nil, err
    99  	}
   100  	config := clientConfig.NewConfigBuilder().
   101  		SetServiceDetails(artAuth).
   102  		SetCertificatesPath(certsPath).
   103  		SetInsecureTls(serverDetails.InsecureTls).
   104  		SetDryRun(isDryRun)
   105  	if httpRetries >= 0 {
   106  		config.SetHttpRetries(httpRetries)
   107  	}
   108  	if threads > 0 {
   109  		config.SetThreads(threads)
   110  	}
   111  	serviceConfig, err := config.Build()
   112  	if err != nil {
   113  		return nil, err
   114  	}
   115  	return artifactory.New(serviceConfig)
   116  }
   117  
   118  func CreateServiceManagerWithProgressBar(serverDetails *config.ServerDetails, threads, httpRetries int, dryRun bool, progressBar ioutils.ProgressMgr) (artifactory.ArtifactoryServicesManager, error) {
   119  	certsPath, err := coreutils.GetJfrogCertsDir()
   120  	if err != nil {
   121  		return nil, err
   122  	}
   123  	artAuth, err := serverDetails.CreateArtAuthConfig()
   124  	if err != nil {
   125  		return nil, err
   126  	}
   127  	servicesConfig, err := clientConfig.NewConfigBuilder().
   128  		SetServiceDetails(artAuth).
   129  		SetDryRun(dryRun).
   130  		SetCertificatesPath(certsPath).
   131  		SetInsecureTls(serverDetails.InsecureTls).
   132  		SetThreads(threads).
   133  		SetHttpRetries(httpRetries).
   134  		Build()
   135  
   136  	if err != nil {
   137  		return nil, err
   138  	}
   139  	return artifactory.NewWithProgress(servicesConfig, progressBar)
   140  }
   141  
   142  func CreateDistributionServiceManager(serviceDetails *config.ServerDetails, isDryRun bool) (*distribution.DistributionServicesManager, error) {
   143  	certsPath, err := coreutils.GetJfrogCertsDir()
   144  	if err != nil {
   145  		return nil, err
   146  	}
   147  	distAuth, err := serviceDetails.CreateDistAuthConfig()
   148  	if err != nil {
   149  		return nil, err
   150  	}
   151  	serviceConfig, err := clientConfig.NewConfigBuilder().
   152  		SetServiceDetails(distAuth).
   153  		SetCertificatesPath(certsPath).
   154  		SetInsecureTls(serviceDetails.InsecureTls).
   155  		SetDryRun(isDryRun).
   156  		Build()
   157  	if err != nil {
   158  		return nil, err
   159  	}
   160  	return distribution.New(serviceConfig)
   161  }
   162  
   163  func CreateAccessServiceManager(serviceDetails *config.ServerDetails, isDryRun bool) (*access.AccessServicesManager, error) {
   164  	certsPath, err := coreutils.GetJfrogCertsDir()
   165  	if err != nil {
   166  		return nil, err
   167  	}
   168  	accessAuth, err := serviceDetails.CreateAccessAuthConfig()
   169  	if err != nil {
   170  		return nil, err
   171  	}
   172  	serviceConfig, err := clientConfig.NewConfigBuilder().
   173  		SetServiceDetails(accessAuth).
   174  		SetCertificatesPath(certsPath).
   175  		SetInsecureTls(serviceDetails.InsecureTls).
   176  		SetDryRun(isDryRun).
   177  		Build()
   178  	if err != nil {
   179  		return nil, err
   180  	}
   181  	return access.New(serviceConfig)
   182  }
   183  
   184  func isRepoExists(repository string, artDetails auth.ServiceDetails) (bool, error) {
   185  	artHttpDetails := artDetails.CreateHttpClientDetails()
   186  	client, err := httpclient.ClientBuilder().SetRetries(3).Build()
   187  	if err != nil {
   188  		return false, err
   189  	}
   190  	resp, _, _, err := client.SendGet(artDetails.GetUrl()+repoDetailsUrl+repository, true, artHttpDetails, "")
   191  	if err != nil {
   192  		return false, errorutils.CheckError(err)
   193  	}
   194  
   195  	if resp.StatusCode != http.StatusBadRequest {
   196  		return true, nil
   197  	}
   198  	return false, nil
   199  }
   200  
   201  func CheckIfRepoExists(repository string, artDetails auth.ServiceDetails) error {
   202  	repoExists, err := isRepoExists(repository, artDetails)
   203  	if err != nil {
   204  		return err
   205  	}
   206  
   207  	if !repoExists {
   208  		return errorutils.CheckError(errors.New("The repository '" + repository + "' does not exist."))
   209  	}
   210  	return nil
   211  }
   212  
   213  // Get build name and number from env, only if both were not provided
   214  func GetBuildNameAndNumber(buildName, buildNumber string) (string, string) {
   215  	if buildName != "" || buildNumber != "" {
   216  		return buildName, buildNumber
   217  	}
   218  	return os.Getenv(coreutils.BuildName), os.Getenv(coreutils.BuildNumber)
   219  }
   220  
   221  // Get build project from env, if not provided
   222  func GetBuildProject(buildProject string) string {
   223  	if buildProject != "" {
   224  		return buildProject
   225  	}
   226  	return os.Getenv(coreutils.Project)
   227  }
   228  
   229  // This error indicates that the build was scanned by Xray, but Xray found issues with the build.
   230  // If Xray failed to scan the build, for example due to a networking issue, a regular error should be returned.
   231  var buildScanError = errors.New("issues found during xray build scan")
   232  
   233  func GetBuildScanError() error {
   234  	return buildScanError
   235  }
   236  
   237  // Download and unmarshal a file from artifactory.
   238  func RemoteUnmarshal(serviceManager artifactory.ArtifactoryServicesManager, remoteFileUrl string, loadTarget interface{}) (err error) {
   239  	ioReaderCloser, err := serviceManager.ReadRemoteFile(remoteFileUrl)
   240  	if err != nil {
   241  		return
   242  	}
   243  	defer func() {
   244  		if localErr := ioReaderCloser.Close(); err == nil {
   245  			err = localErr
   246  		}
   247  	}()
   248  	content, err := io.ReadAll(ioReaderCloser)
   249  	if err != nil {
   250  		return errorutils.CheckError(err)
   251  	}
   252  	return errorutils.CheckError(json.Unmarshal(content, loadTarget))
   253  }