github.com/jfrog/jfrog-client-go@v1.40.2/distribution/services/deleteremote.go (about)

     1  package services
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	artifactoryUtils "github.com/jfrog/jfrog-client-go/artifactory/services/utils"
     7  	"github.com/jfrog/jfrog-client-go/auth"
     8  	"github.com/jfrog/jfrog-client-go/http/jfroghttpclient"
     9  	"github.com/jfrog/jfrog-client-go/utils"
    10  	"github.com/jfrog/jfrog-client-go/utils/distribution"
    11  	"github.com/jfrog/jfrog-client-go/utils/errorutils"
    12  	"github.com/jfrog/jfrog-client-go/utils/log"
    13  	"net/http"
    14  	"time"
    15  )
    16  
    17  type OnSuccess string
    18  
    19  const (
    20  	Keep   OnSuccess = "keep"
    21  	Delete OnSuccess = "delete"
    22  )
    23  
    24  // Delete received release bundles from the edge nodes. On success, keep or delete the release bundle from the distribution service.
    25  type DeleteReleaseBundleService struct {
    26  	client      *jfroghttpclient.JfrogHttpClient
    27  	DistDetails auth.ServiceDetails
    28  	DryRun      bool
    29  	Sync        bool
    30  	// Max time in minutes to wait for sync distribution to finish.
    31  	MaxWaitMinutes int
    32  }
    33  
    34  func NewDeleteReleaseBundleService(client *jfroghttpclient.JfrogHttpClient) *DeleteReleaseBundleService {
    35  	return &DeleteReleaseBundleService{client: client}
    36  }
    37  
    38  func (dr *DeleteReleaseBundleService) GetDistDetails() auth.ServiceDetails {
    39  	return dr.DistDetails
    40  }
    41  
    42  func (dr *DeleteReleaseBundleService) IsDryRun() bool {
    43  	return dr.DryRun
    44  }
    45  
    46  func (dr *DeleteReleaseBundleService) DeleteDistribution(deleteDistributionParams DeleteDistributionParams) error {
    47  	var distributionRules []distribution.DistributionRulesBody
    48  	for _, rule := range deleteDistributionParams.DistributionRules {
    49  		distributionRule := distribution.DistributionRulesBody{
    50  			SiteName:     rule.GetSiteName(),
    51  			CityName:     rule.GetCityName(),
    52  			CountryCodes: rule.GetCountryCodes(),
    53  		}
    54  		distributionRules = append(distributionRules, distributionRule)
    55  	}
    56  
    57  	var onSuccess OnSuccess
    58  	if deleteDistributionParams.DeleteFromDistribution {
    59  		onSuccess = Delete
    60  	} else {
    61  		onSuccess = Keep
    62  	}
    63  
    64  	deleteDistribution := DeleteRemoteDistributionBody{
    65  		ReleaseBundleDistributeV1Body: distribution.ReleaseBundleDistributeV1Body{
    66  			DryRun:            dr.DryRun,
    67  			DistributionRules: distributionRules,
    68  		},
    69  		OnSuccess: onSuccess,
    70  	}
    71  	dr.Sync = deleteDistributionParams.Sync
    72  	dr.MaxWaitMinutes = deleteDistributionParams.MaxWaitMinutes
    73  	return dr.execDeleteDistribute(deleteDistributionParams.Name, deleteDistributionParams.Version, deleteDistribution)
    74  }
    75  
    76  func (dr *DeleteReleaseBundleService) execDeleteDistribute(name, version string, deleteDistribution DeleteRemoteDistributionBody) error {
    77  	dryRunStr := ""
    78  	if dr.IsDryRun() {
    79  		dryRunStr = "[Dry run] "
    80  	}
    81  	log.Info(dryRunStr + "Deleting: " + name + "/" + version)
    82  
    83  	httpClientsDetails := dr.DistDetails.CreateHttpClientDetails()
    84  	content, err := json.Marshal(deleteDistribution)
    85  	if err != nil {
    86  		return errorutils.CheckError(err)
    87  	}
    88  	url := dr.DistDetails.GetUrl() + "api/v1/distribution/" + name + "/" + version + "/delete"
    89  	artifactoryUtils.SetContentType("application/json", &httpClientsDetails.Headers)
    90  	resp, body, err := dr.client.SendPost(url, content, &httpClientsDetails)
    91  	if err != nil {
    92  		return err
    93  	}
    94  	if err = errorutils.CheckResponseStatusWithBody(resp, body, http.StatusOK, http.StatusAccepted); err != nil {
    95  		return err
    96  	}
    97  	if dr.Sync {
    98  		err := dr.waitForDeletion(name, version)
    99  		if err != nil {
   100  			return err
   101  		}
   102  	}
   103  	log.Debug("Distribution response:", resp.Status)
   104  	log.Debug(utils.IndentJson(body))
   105  	return errorutils.CheckError(err)
   106  }
   107  
   108  func (dr *DeleteReleaseBundleService) waitForDeletion(name, version string) error {
   109  	distributeBundleService := NewDistributionStatusService(dr.client)
   110  	distributeBundleService.DistDetails = dr.GetDistDetails()
   111  	httpClientsDetails := distributeBundleService.DistDetails.CreateHttpClientDetails()
   112  	maxWaitMinutes := defaultMaxWaitMinutes
   113  	if dr.MaxWaitMinutes >= 1 {
   114  		maxWaitMinutes = dr.MaxWaitMinutes
   115  	}
   116  	for timeElapsed := 0; timeElapsed < maxWaitMinutes*60; timeElapsed += DefaultDistributeSyncSleepIntervalSeconds {
   117  		if timeElapsed%60 == 0 {
   118  			log.Info(fmt.Sprintf("Performing sync deletion of release bundle %s/%s...", name, version))
   119  		}
   120  		resp, _, _, err := dr.client.SendGet(dr.DistDetails.GetUrl()+"api/v1/release_bundle/"+name+"/"+version+"/distribution", true, &httpClientsDetails)
   121  		if err != nil {
   122  			return err
   123  		}
   124  		if resp.StatusCode == http.StatusNotFound {
   125  			log.Info("Deletion Completed!")
   126  			return nil
   127  		}
   128  		if resp.StatusCode != http.StatusOK {
   129  			return errorutils.CheckErrorf("error while waiting to deletion: status code " + fmt.Sprint(resp.StatusCode) + ".")
   130  		}
   131  		time.Sleep(time.Second * DefaultDistributeSyncSleepIntervalSeconds)
   132  	}
   133  	return errorutils.CheckErrorf("timeout for sync deletion. ")
   134  }
   135  
   136  type DeleteRemoteDistributionBody struct {
   137  	distribution.ReleaseBundleDistributeV1Body
   138  	OnSuccess OnSuccess `json:"on_success"`
   139  }
   140  
   141  type DeleteDistributionParams struct {
   142  	distribution.DistributionParams
   143  	DeleteFromDistribution bool
   144  	Sync                   bool
   145  	// Max time in minutes to wait for sync distribution to finish.
   146  	MaxWaitMinutes int
   147  }
   148  
   149  func NewDeleteReleaseBundleParams(name, version string) DeleteDistributionParams {
   150  	return DeleteDistributionParams{
   151  		DistributionParams: distribution.DistributionParams{
   152  			Name:    name,
   153  			Version: version,
   154  		},
   155  	}
   156  }