github.com/jfrog/jfrog-cli-core@v1.12.1/artifactory/commands/replication/template.go (about) 1 package replication 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "os" 7 8 "github.com/c-bata/go-prompt" 9 "github.com/jfrog/jfrog-cli-core/artifactory/commands/utils" 10 "github.com/jfrog/jfrog-cli-core/utils/config" 11 "github.com/jfrog/jfrog-client-go/utils/errorutils" 12 "github.com/jfrog/jfrog-client-go/utils/log" 13 ) 14 15 const ( 16 // Strings for prompt questions 17 SelectConfigKeyMsg = "Select the next configuration key" + utils.PressTabMsg 18 19 // Template types 20 TemplateType = "templateType" 21 JobType = "jobType" 22 Create = "create" 23 Pull = "pull" 24 Push = "push" 25 26 // Common replication configuration JSON keys 27 ServerId = "serverId" 28 CronExp = "cronExp" 29 RepoKey = "repoKey" 30 TargetRepoKey = "targetRepoKey" 31 EnableEventReplication = "enableEventReplication" 32 Enabled = "enabled" 33 SyncDeletes = "syncDeletes" 34 SyncProperties = "syncProperties" 35 SyncStatistics = "syncStatistics" 36 PathPrefix = "pathPrefix" 37 SocketTimeoutMillis = "socketTimeoutMillis" 38 ) 39 40 type ReplicationTemplateCommand struct { 41 path string 42 } 43 44 func NewReplicationTemplateCommand() *ReplicationTemplateCommand { 45 return &ReplicationTemplateCommand{} 46 } 47 48 func (rtc *ReplicationTemplateCommand) SetTemplatePath(path string) *ReplicationTemplateCommand { 49 rtc.path = path 50 return rtc 51 } 52 53 func (rtc *ReplicationTemplateCommand) CommandName() string { 54 return "rt_replication_template" 55 } 56 57 func (rtc *ReplicationTemplateCommand) ServerDetails() (*config.ServerDetails, error) { 58 // Since it's a local command, usage won't be reported. 59 return nil, nil 60 } 61 62 func getArtifactoryServerIds() []prompt.Suggest { 63 suggest := make([]prompt.Suggest, 0) 64 if configurations, _ := config.GetAllServersConfigs(); configurations != nil { 65 for _, conf := range configurations { 66 suggest = append(suggest, prompt.Suggest{Text: conf.ServerId}) 67 } 68 } 69 return suggest 70 } 71 72 func (rtc *ReplicationTemplateCommand) Run() (err error) { 73 replicationTemplateQuestionnaire := &utils.InteractiveQuestionnaire{ 74 MandatoryQuestionsKeys: []string{JobType, RepoKey}, 75 QuestionsMap: questionMap, 76 } 77 err = replicationTemplateQuestionnaire.Perform() 78 if err != nil { 79 return err 80 } 81 resBytes, err := json.Marshal(replicationTemplateQuestionnaire.AnswersMap) 82 if err != nil { 83 return errorutils.CheckError(err) 84 } 85 if err = os.WriteFile(rtc.path, resBytes, 0644); err != nil { 86 return errorutils.CheckError(err) 87 } 88 log.Info(fmt.Sprintf("Replication creation config template successfully created at %s.", rtc.path)) 89 return nil 90 } 91 92 var questionMap = map[string]utils.QuestionInfo{ 93 utils.OptionalKey: { 94 Msg: "", 95 PromptPrefix: "Select the next property >", 96 AllowVars: false, 97 Writer: nil, 98 MapKey: "", 99 Callback: utils.OptionalKeyCallback, 100 }, 101 TemplateType: { 102 Options: []prompt.Suggest{ 103 {Text: Create, Description: "Template for creating a new replication"}, 104 }, 105 Msg: "", 106 PromptPrefix: "Select the template type >", 107 AllowVars: false, 108 Writer: nil, 109 MapKey: "", 110 Callback: nil, 111 }, 112 JobType: { 113 Options: []prompt.Suggest{ 114 {Text: Pull, Description: "Pull replication"}, 115 {Text: Push, Description: "Push replication"}, 116 }, 117 Msg: "", 118 PromptPrefix: "Select replication job type" + utils.PressTabMsg, 119 AllowVars: false, 120 Writer: nil, 121 MapKey: "", 122 Callback: jobTypeCallback, 123 }, 124 RepoKey: { 125 Msg: "", 126 PromptPrefix: "Enter source repo key >", 127 AllowVars: true, 128 Writer: utils.WriteStringAnswer, 129 MapKey: RepoKey, 130 Callback: nil, 131 }, 132 TargetRepoKey: { 133 Msg: "", 134 PromptPrefix: "Enter target repo key >", 135 AllowVars: true, 136 Writer: utils.WriteStringAnswer, 137 MapKey: TargetRepoKey, 138 Callback: nil, 139 }, 140 ServerId: { 141 Options: getArtifactoryServerIds(), 142 Msg: "", 143 PromptPrefix: "Enter target server id" + utils.PressTabMsg, 144 AllowVars: true, 145 Writer: utils.WriteStringAnswer, 146 MapKey: ServerId, 147 Callback: nil, 148 }, 149 CronExp: { 150 Msg: "", 151 PromptPrefix: "Enter cron expression for frequency (for example, 0 0 12 * * ? will replicate daily) >", 152 AllowVars: true, 153 Writer: utils.WriteStringAnswer, 154 MapKey: CronExp, 155 Callback: nil, 156 }, 157 EnableEventReplication: BoolToStringQuestionInfo, 158 Enabled: BoolToStringQuestionInfo, 159 SyncDeletes: BoolToStringQuestionInfo, 160 SyncProperties: BoolToStringQuestionInfo, 161 SyncStatistics: BoolToStringQuestionInfo, 162 PathPrefix: { 163 Msg: "", 164 PromptPrefix: "Enter path prefix >", 165 AllowVars: true, 166 Writer: utils.WriteStringAnswer, 167 MapKey: PathPrefix, 168 Callback: nil, 169 }, 170 SocketTimeoutMillis: { 171 Msg: "", 172 PromptPrefix: "Enter socket timeout millis >", 173 AllowVars: true, 174 Writer: utils.WriteStringAnswer, 175 MapKey: SocketTimeoutMillis, 176 Callback: nil, 177 }, 178 } 179 180 func jobTypeCallback(iq *utils.InteractiveQuestionnaire, jobType string) (string, error) { 181 if jobType == Pull { 182 iq.MandatoryQuestionsKeys = append(iq.MandatoryQuestionsKeys, CronExp) 183 } else { 184 iq.MandatoryQuestionsKeys = append(iq.MandatoryQuestionsKeys, TargetRepoKey, ServerId, CronExp) 185 } 186 iq.OptionalKeysSuggests = getAllPossibleOptionalRepoConfKeys() 187 return "", nil 188 } 189 190 func getAllPossibleOptionalRepoConfKeys(values ...string) []prompt.Suggest { 191 optionalKeys := []string{utils.SaveAndExit, Enabled, SyncDeletes, SyncProperties, SyncStatistics, PathPrefix, EnableEventReplication, SocketTimeoutMillis} 192 if len(values) > 0 { 193 optionalKeys = append(optionalKeys, values...) 194 } 195 return utils.GetSuggestsFromKeys(optionalKeys, suggestionMap) 196 } 197 198 // Specific writers for repo templates, since all the values in the templates should be written as string. 199 var BoolToStringQuestionInfo = utils.QuestionInfo{ 200 Options: utils.GetBoolSuggests(), 201 AllowVars: true, 202 Writer: utils.WriteStringAnswer, 203 } 204 205 var suggestionMap = map[string]prompt.Suggest{ 206 utils.SaveAndExit: {Text: utils.SaveAndExit}, 207 ServerId: {Text: ServerId}, 208 RepoKey: {Text: RepoKey}, 209 TargetRepoKey: {Text: TargetRepoKey}, 210 CronExp: {Text: CronExp}, 211 EnableEventReplication: {Text: EnableEventReplication}, 212 Enabled: {Text: Enabled}, 213 SyncDeletes: {Text: SyncDeletes}, 214 SyncProperties: {Text: SyncProperties}, 215 SyncStatistics: {Text: SyncStatistics}, 216 PathPrefix: {Text: PathPrefix}, 217 SocketTimeoutMillis: {Text: SocketTimeoutMillis}, 218 }