github.com/jfrog/jfrog-cli-core/v2@v2.51.0/artifactory/commands/replication/create.go (about)

     1  package replication
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"strings"
     7  
     8  	"github.com/jfrog/jfrog-cli-core/v2/artifactory/commands/utils"
     9  	rtUtils "github.com/jfrog/jfrog-cli-core/v2/artifactory/utils"
    10  	"github.com/jfrog/jfrog-cli-core/v2/utils/config"
    11  	"github.com/jfrog/jfrog-cli-core/v2/utils/coreutils"
    12  	"github.com/jfrog/jfrog-cli-core/v2/utils/ioutils"
    13  	"github.com/jfrog/jfrog-client-go/artifactory/services"
    14  	"github.com/jfrog/jfrog-client-go/utils/errorutils"
    15  	"github.com/jfrog/jfrog-client-go/utils/io/fileutils"
    16  )
    17  
    18  type ReplicationCreateCommand struct {
    19  	serverDetails *config.ServerDetails
    20  	templatePath  string
    21  	vars          string
    22  }
    23  
    24  func NewReplicationCreateCommand() *ReplicationCreateCommand {
    25  	return &ReplicationCreateCommand{}
    26  }
    27  
    28  func (rcc *ReplicationCreateCommand) SetTemplatePath(path string) *ReplicationCreateCommand {
    29  	rcc.templatePath = path
    30  	return rcc
    31  }
    32  
    33  func (rcc *ReplicationCreateCommand) SetVars(vars string) *ReplicationCreateCommand {
    34  	rcc.vars = vars
    35  	return rcc
    36  }
    37  
    38  func (rcc *ReplicationCreateCommand) SetServerDetails(serverDetails *config.ServerDetails) *ReplicationCreateCommand {
    39  	rcc.serverDetails = serverDetails
    40  	return rcc
    41  }
    42  
    43  func (rcc *ReplicationCreateCommand) ServerDetails() (*config.ServerDetails, error) {
    44  	return rcc.serverDetails, nil
    45  }
    46  
    47  func (rcc *ReplicationCreateCommand) CommandName() string {
    48  	return "rt_replication_create"
    49  }
    50  
    51  func (rcc *ReplicationCreateCommand) Run() (err error) {
    52  	content, err := fileutils.ReadFile(rcc.templatePath)
    53  	if errorutils.CheckError(err) != nil {
    54  		return
    55  	}
    56  	// Replace vars string-by-string if needed
    57  	if len(rcc.vars) > 0 {
    58  		templateVars := coreutils.SpecVarsStringToMap(rcc.vars)
    59  		content = coreutils.ReplaceVars(content, templateVars)
    60  	}
    61  	// Unmarshal template to a map
    62  	var replicationConfigMap map[string]interface{}
    63  	err = json.Unmarshal(content, &replicationConfigMap)
    64  	if errorutils.CheckError(err) != nil {
    65  		return
    66  	}
    67  	// All the values in the template are strings
    68  	// Go over the confMap and write the values with the correct type using the writersMap
    69  	serverId := ""
    70  	for key, value := range replicationConfigMap {
    71  		if err = utils.ValidateMapEntry(key, value, writersMap); err != nil {
    72  			return
    73  		}
    74  		if key == "serverId" {
    75  			serverId = fmt.Sprint(value)
    76  		} else {
    77  			err := writersMap[key](&replicationConfigMap, key, fmt.Sprint(value))
    78  			if err != nil {
    79  				return err
    80  			}
    81  		}
    82  	}
    83  	err = fillMissingDefaultValue(replicationConfigMap)
    84  	if err != nil {
    85  		return err
    86  	}
    87  	// Write a JSON with the correct values
    88  	content, err = json.Marshal(replicationConfigMap)
    89  	if errorutils.CheckError(err) != nil {
    90  		return
    91  	}
    92  	var params services.CreateReplicationParams
    93  	err = json.Unmarshal(content, &params)
    94  	if errorutils.CheckError(err) != nil {
    95  		return
    96  	}
    97  
    98  	setPathPrefixBackwardCompatibility(&params)
    99  	servicesManager, err := rtUtils.CreateServiceManager(rcc.serverDetails, -1, 0, false)
   100  	if err != nil {
   101  		return err
   102  	}
   103  	// In case 'serverId' is not found, pull replication will be assumed.
   104  	if serverId != "" {
   105  		if targetRepo, ok := replicationConfigMap["targetRepoKey"]; ok {
   106  			if err = updateArtifactoryInfo(&params, serverId, fmt.Sprint(targetRepo)); err != nil {
   107  				return err
   108  			}
   109  		} else {
   110  			return errorutils.CheckErrorf("expected 'targetRepoKey' field in the json template file.")
   111  		}
   112  	}
   113  	return servicesManager.CreateReplication(params)
   114  }
   115  
   116  func fillMissingDefaultValue(replicationConfigMap map[string]interface{}) error {
   117  	if _, ok := replicationConfigMap["socketTimeoutMillis"]; !ok {
   118  		err := writersMap["socketTimeoutMillis"](&replicationConfigMap, "socketTimeoutMillis", "15000")
   119  		if err != nil {
   120  			return err
   121  		}
   122  	}
   123  	if _, ok := replicationConfigMap["syncProperties"]; !ok {
   124  		err := writersMap["syncProperties"](&replicationConfigMap, "syncProperties", "true")
   125  		if err != nil {
   126  			return err
   127  		}
   128  	}
   129  	return nil
   130  }
   131  
   132  // Make the pathPrefix parameter equals to the includePathPrefixPattern to support Artifactory < 7.27.4
   133  func setPathPrefixBackwardCompatibility(params *services.CreateReplicationParams) {
   134  	if params.IncludePathPrefixPattern == "" {
   135  		params.IncludePathPrefixPattern = params.PathPrefix
   136  		return
   137  	}
   138  	if params.PathPrefix == "" {
   139  		params.PathPrefix = params.IncludePathPrefixPattern
   140  	}
   141  }
   142  
   143  func updateArtifactoryInfo(param *services.CreateReplicationParams, serverId, targetRepo string) error {
   144  	singleConfig, err := config.GetSpecificConfig(serverId, true, false)
   145  	if err != nil {
   146  		return err
   147  	}
   148  	param.Url, param.Password, param.Username = strings.TrimSuffix(singleConfig.GetArtifactoryUrl(), "/")+"/"+targetRepo, singleConfig.GetPassword(), singleConfig.GetUser()
   149  	return nil
   150  }
   151  
   152  var writersMap = map[string]ioutils.AnswerWriter{
   153  	ServerId:                 ioutils.WriteStringAnswer,
   154  	RepoKey:                  ioutils.WriteStringAnswer,
   155  	TargetRepoKey:            ioutils.WriteStringAnswer,
   156  	CronExp:                  ioutils.WriteStringAnswer,
   157  	EnableEventReplication:   ioutils.WriteBoolAnswer,
   158  	Enabled:                  ioutils.WriteBoolAnswer,
   159  	SyncDeletes:              ioutils.WriteBoolAnswer,
   160  	SyncProperties:           ioutils.WriteBoolAnswer,
   161  	SyncStatistics:           ioutils.WriteBoolAnswer,
   162  	PathPrefix:               ioutils.WriteStringAnswer,
   163  	IncludePathPrefixPattern: ioutils.WriteStringAnswer,
   164  	SocketTimeoutMillis:      ioutils.WriteIntAnswer,
   165  	DisableProxy:             ioutils.WriteBoolAnswer,
   166  }