github.com/jfrog/jfrog-cli-go@v1.22.1-0.20200318093948-4826ef344ffd/artifactory/commands/replication/template.go (about) 1 package replication 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "io/ioutil" 7 8 "github.com/c-bata/go-prompt" 9 "github.com/jfrog/jfrog-cli-go/artifactory/commands/utils" 10 "github.com/jfrog/jfrog-cli-go/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 EnableEventReplication = "enableEventReplication" 31 Enabled = "enabled" 32 SyncDeletes = "syncDeletes" 33 SyncProperties = "syncProperties" 34 SyncStatistics = "syncStatistics" 35 PathPrefix = "pathPrefix" 36 SocketTimeoutMillis = "socketTimeoutMillis" 37 ) 38 39 type ReplicationTemplateCommand struct { 40 path string 41 } 42 43 func NewReplicationTemplateCommand() *ReplicationTemplateCommand { 44 return &ReplicationTemplateCommand{} 45 } 46 47 func (rtc *ReplicationTemplateCommand) SetTemplatePath(path string) *ReplicationTemplateCommand { 48 rtc.path = path 49 return rtc 50 } 51 52 func (rtc *ReplicationTemplateCommand) CommandName() string { 53 return "rt_replication_template" 54 } 55 56 func (rtc *ReplicationTemplateCommand) RtDetails() (*config.ArtifactoryDetails, error) { 57 // Since it's a local command, usage won't be reported. 58 return nil, nil 59 } 60 61 func (rtc *ReplicationTemplateCommand) Run() (err error) { 62 replicationTemplateQuestionnaire := &utils.InteractiveQuestionnaire{ 63 MandatoryQuestionsKeys: []string{JobType, RepoKey}, 64 QuestionsMap: questionMap, 65 } 66 err = replicationTemplateQuestionnaire.Perform() 67 if err != nil { 68 return err 69 } 70 resBytes, err := json.Marshal(replicationTemplateQuestionnaire.AnswersMap) 71 if err != nil { 72 return errorutils.CheckError(err) 73 } 74 if err = ioutil.WriteFile(rtc.path, resBytes, 0644); err != nil { 75 return errorutils.CheckError(err) 76 } 77 log.Info(fmt.Sprintf("Replication creation config template successfully created at %s.", rtc.path)) 78 return nil 79 } 80 81 var questionMap = map[string]utils.QuestionInfo{ 82 utils.OptionalKey: { 83 Msg: "", 84 PromptPrefix: "Select the next property >", 85 AllowVars: false, 86 Writer: nil, 87 MapKey: "", 88 Callback: utils.OptionalKeyCallback, 89 }, 90 TemplateType: { 91 Options: []prompt.Suggest{ 92 {Text: Create, Description: "Template for creating a new replication"}, 93 }, 94 Msg: "", 95 PromptPrefix: "Select the template type >", 96 AllowVars: true, 97 Writer: nil, 98 MapKey: "", 99 Callback: nil, 100 }, 101 JobType: { 102 Options: []prompt.Suggest{ 103 {Text: Pull, Description: "Pull replication"}, 104 {Text: Push, Description: "Push replication"}, 105 }, 106 Msg: "", 107 PromptPrefix: "Select job type >", 108 AllowVars: true, 109 Writer: nil, 110 MapKey: "", 111 Callback: jobTypeCallback, 112 }, 113 RepoKey: { 114 Msg: "", 115 PromptPrefix: "Enter repo key >", 116 AllowVars: true, 117 Writer: utils.WriteStringAnswer, 118 MapKey: RepoKey, 119 Callback: nil, 120 }, 121 ServerId: { 122 Msg: "", 123 PromptPrefix: "Enter server id >", 124 AllowVars: true, 125 Writer: utils.WriteStringAnswer, 126 MapKey: ServerId, 127 Callback: nil, 128 }, 129 CronExp: { 130 Msg: "", 131 PromptPrefix: "Enter cron expression >", 132 AllowVars: true, 133 Writer: utils.WriteStringAnswer, 134 MapKey: CronExp, 135 Callback: nil, 136 }, 137 EnableEventReplication: BoolToStringQuestionInfo, 138 Enabled: BoolToStringQuestionInfo, 139 SyncDeletes: BoolToStringQuestionInfo, 140 SyncProperties: BoolToStringQuestionInfo, 141 SyncStatistics: BoolToStringQuestionInfo, 142 PathPrefix: { 143 Msg: "", 144 PromptPrefix: "Enter path prefix >", 145 AllowVars: false, 146 Writer: utils.WriteStringAnswer, 147 MapKey: PathPrefix, 148 Callback: nil, 149 }, 150 SocketTimeoutMillis: { 151 Msg: "", 152 PromptPrefix: "Enter socket timeout millis >", 153 AllowVars: false, 154 Writer: utils.WriteStringAnswer, 155 MapKey: SocketTimeoutMillis, 156 Callback: nil, 157 }, 158 } 159 160 func jobTypeCallback(iq *utils.InteractiveQuestionnaire, jobType string) (string, error) { 161 iq.MandatoryQuestionsKeys = append(iq.MandatoryQuestionsKeys, CronExp) 162 if jobType == Pull { 163 iq.OptionalKeysSuggests = getAllPossibleOptionalRepoConfKeys() 164 } else { 165 iq.MandatoryQuestionsKeys = append(iq.MandatoryQuestionsKeys, ServerId) 166 iq.OptionalKeysSuggests = getAllPossibleOptionalRepoConfKeys() 167 } 168 return "", nil 169 } 170 171 func getAllPossibleOptionalRepoConfKeys(values ...string) []prompt.Suggest { 172 optionalKeys := []string{utils.SaveAndExit, Enabled, SyncDeletes, SyncProperties, SyncStatistics, PathPrefix, EnableEventReplication, SocketTimeoutMillis} 173 if len(values) > 0 { 174 optionalKeys = append(optionalKeys, values...) 175 } 176 return utils.GetSuggestsFromKeys(optionalKeys, suggestionMap) 177 } 178 179 // Specific writers for repo templates, since all the values in the templates should be written as string. 180 var BoolToStringQuestionInfo = utils.QuestionInfo{ 181 Options: utils.GetBoolSuggests(), 182 AllowVars: true, 183 Writer: utils.WriteStringAnswer, 184 } 185 186 var suggestionMap = map[string]prompt.Suggest{ 187 utils.SaveAndExit: {Text: utils.SaveAndExit}, 188 ServerId: {Text: ServerId}, 189 RepoKey: {Text: RepoKey}, 190 CronExp: {Text: CronExp}, 191 EnableEventReplication: {Text: EnableEventReplication}, 192 Enabled: {Text: Enabled}, 193 SyncDeletes: {Text: SyncDeletes}, 194 SyncProperties: {Text: SyncProperties}, 195 SyncStatistics: {Text: SyncStatistics}, 196 PathPrefix: {Text: PathPrefix}, 197 SocketTimeoutMillis: {Text: SocketTimeoutMillis}, 198 }