github.com/cobalt77/jfrog-client-go@v0.14.5/artifactory/usage/reportusage.go (about)

     1  package usage
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"net/http"
     7  
     8  	"errors"
     9  
    10  	"github.com/cobalt77/jfrog-client-go/artifactory"
    11  	"github.com/cobalt77/jfrog-client-go/artifactory/services/utils"
    12  	clientutils "github.com/cobalt77/jfrog-client-go/utils"
    13  	"github.com/cobalt77/jfrog-client-go/utils/errorutils"
    14  	"github.com/cobalt77/jfrog-client-go/utils/log"
    15  	versionutil "github.com/cobalt77/jfrog-client-go/utils/version"
    16  )
    17  
    18  const minArtifactoryVersion = "6.9.0"
    19  const ReportUsagePrefix = "Usage Report: "
    20  
    21  func SendReportUsage(productId, commandName string, serviceManager artifactory.ArtifactoryServicesManager) error {
    22  	config := serviceManager.GetConfig()
    23  	if config == nil {
    24  		return errorutils.CheckError(errors.New(ReportUsagePrefix + "Expected full config, but no configuration exists."))
    25  	}
    26  	rtDetails := config.GetServiceDetails()
    27  	if rtDetails == nil {
    28  		return errorutils.CheckError(errors.New(ReportUsagePrefix + "Artifactory details not configured."))
    29  	}
    30  	url, err := utils.BuildArtifactoryUrl(rtDetails.GetUrl(), "api/system/usage", make(map[string]string))
    31  	if err != nil {
    32  		return errors.New(ReportUsagePrefix + err.Error())
    33  	}
    34  	clientDetails := rtDetails.CreateHttpClientDetails()
    35  	// Check Artifactory version
    36  	artifactoryVersion, err := rtDetails.GetVersion()
    37  	if err != nil {
    38  		return errors.New(ReportUsagePrefix + err.Error())
    39  	}
    40  	if !isVersionCompatible(artifactoryVersion) {
    41  		log.Debug(fmt.Sprintf(ReportUsagePrefix+"Expected Artifactory version %s or above, got %s", minArtifactoryVersion, artifactoryVersion))
    42  		return nil
    43  	}
    44  
    45  	bodyContent, err := reportUsageToJson(productId, commandName)
    46  	if err != nil {
    47  		return errors.New(ReportUsagePrefix + err.Error())
    48  	}
    49  	utils.AddHeader("Content-Type", "application/json", &clientDetails.Headers)
    50  	resp, body, err := serviceManager.Client().SendPost(url, bodyContent, &clientDetails)
    51  	if err != nil {
    52  		return errors.New(ReportUsagePrefix + err.Error())
    53  	}
    54  	if resp.StatusCode != http.StatusOK {
    55  		return errors.New(ReportUsagePrefix + "Artifactory response: " + resp.Status + "\n" + clientutils.IndentJson(body))
    56  	}
    57  
    58  	log.Debug(ReportUsagePrefix+"Artifactory response:", resp.Status)
    59  	log.Debug(ReportUsagePrefix + "Usage info sent successfully.")
    60  	return nil
    61  }
    62  
    63  // Returns an error if the Artifactory version is not compatible
    64  func isVersionCompatible(artifactoryVersion string) bool {
    65  	// API exists from Artifactory version 6.9.0 and above:
    66  	version := versionutil.NewVersion(artifactoryVersion)
    67  	return version.AtLeast(minArtifactoryVersion)
    68  }
    69  
    70  func reportUsageToJson(productId, commandName string) ([]byte, error) {
    71  	featureInfo := feature{FeatureId: commandName}
    72  	params := reportUsageParams{ProductId: productId, Features: []feature{featureInfo}}
    73  	bodyContent, err := json.Marshal(params)
    74  	return bodyContent, errorutils.CheckError(err)
    75  }
    76  
    77  type reportUsageParams struct {
    78  	ProductId string    `json:"productId"`
    79  	Features  []feature `json:"features,omitempty"`
    80  }
    81  
    82  type feature struct {
    83  	FeatureId string `json:"featureId,omitempty"`
    84  }