github.com/jfrog/jfrog-cli-core@v1.12.1/artifactory/commands/repository/template.go (about) 1 package repository 2 3 import ( 4 "encoding/json" 5 "errors" 6 "fmt" 7 "os" 8 "strings" 9 10 "github.com/c-bata/go-prompt" 11 "github.com/jfrog/jfrog-cli-core/artifactory/commands/utils" 12 "github.com/jfrog/jfrog-cli-core/utils/config" 13 "github.com/jfrog/jfrog-client-go/utils/errorutils" 14 "github.com/jfrog/jfrog-client-go/utils/log" 15 ) 16 17 type RepoTemplateCommand struct { 18 path string 19 } 20 21 const ( 22 PathErrorSuffixMsg = " please enter a path, in which the new template file will be created" 23 24 // Strings for prompt questions 25 SelectConfigKeyMsg = "Select the next configuration key" + utils.PressTabMsg 26 InsertValuePromptMsg = "Insert the value for " 27 28 TemplateType = "templateType" 29 Create = "create" 30 Update = "update" 31 32 MandatoryUrl = "mandatoryUrl" 33 34 // Common repository configuration JSON keys 35 Key = "key" 36 Rclass = "rclass" 37 PackageType = "packageType" 38 Description = "description" 39 Notes = "notes" 40 IncludePatterns = "includesPattern" 41 ExcludePatterns = "excludesPattern" 42 RepoLayoutRef = "repoLayoutRef" 43 44 // Mutual local and remote repository configuration JSON keys 45 HandleReleases = "handleReleases" 46 HandleSnapshots = "handleSnapshots" 47 MaxUniqueSnapshots = "maxUniqueSnapshots" 48 SuppressPomConsistencyChecks = "suppressPomConsistencyChecks" 49 BlackedOut = "blackedOut" 50 XrayIndex = "xrayIndex" 51 PropertySets = "propertySets" 52 DownloadRedirect = "downloadRedirect" 53 BlockPushingSchema1 = "blockPushingSchema1" 54 55 // Mutual local and virtual repository configuration JSON keys 56 DebianTrivialLayout = "debianTrivialLayout" 57 58 // Mutual remote and virtual repository configuration JSON keys 59 ExternalDependenciesEnabled = "externalDependenciesEnabled" 60 ExternalDependenciesPatterns = "externalDependenciesPatterns" 61 62 // Unique local repository configuration JSON keys 63 ChecksumPolicyType = "checksumPolicyType" 64 MaxUniqueTags = "maxUniqueTags" 65 SnapshotVersionBehavior = "snapshotVersionBehavior" 66 ArchiveBrowsingEnabled = "archiveBrowsingEnabled" 67 CalculateYumMetadata = "calculateYumMetadata" 68 YumRootDepth = "yumRootDepth" 69 DockerApiVersion = "dockerApiVersion" 70 EnableFileListsIndexing = "enableFileListsIndexing" 71 OptionalIndexCompressionFormats = "optionalIndexCompressionFormats" 72 ForceNugetAuthentication = "forceNugetAuthentication" 73 74 // Unique remote repository configuration JSON keys 75 Url = "url" 76 Username = "username" 77 Password = "password" 78 Proxy = "proxy" 79 RemoteRepoChecksumPolicyType = "remoteRepoChecksumPolicyType" 80 HardFail = "hardFail" 81 Offline = "offline" 82 StoreArtifactsLocally = "storeArtifactsLocally" 83 SocketTimeoutMillis = "socketTimeoutMillis" 84 LocalAddress = "localAddress" 85 RetrievalCachePeriodSecs = "retrievalCachePeriodSecs" 86 FailedRetrievalCachePeriodSecs = "failedRetrievalCachePeriodSecs" 87 MissedRetrievalCachePeriodSecs = "missedRetrievalCachePeriodSecs" 88 UnusedArtifactsCleanupEnabled = "unusedArtifactsCleanupEnabled" 89 UnusedArtifactsCleanupPeriodHours = "unusedArtifactsCleanupPeriodHours" 90 AssumedOfflinePeriodSecs = "assumedOfflinePeriodSecs" 91 FetchJarsEagerly = "fetchJarsEagerly" 92 FetchSourcesEagerly = "fetchSourcesEagerly" 93 RejectInvalidJars = "rejectInvalidJars" 94 ShareConfiguration = "shareConfiguration" 95 SynchronizeProperties = "synchronizeProperties" 96 BlockMismatchingMimeTypes = "blockMismatchingMimeTypes" 97 AllowAnyHostAuth = "allowAnyHostAuth" 98 EnableCookieManagement = "enableCookieManagement" 99 BowerRegistryUrl = "bowerRegistryUrl" 100 ComposerRegistryUrl = "composerRegistryUrl" 101 PyPIRegistryUrl = "pyPIRegistryUrl" 102 VcsType = "vcsType" 103 VcsGitProvider = "vcsGitProvider" 104 VcsGitDownloadUrl = "vcsGitDownloadUrl" 105 BypassHeadRequests = "bypassHeadRequests" 106 ClientTlsCertificate = "clientTlsCertificate" 107 FeedContextPath = "feedContextPath" 108 DownloadContextPath = "downloadContextPath" 109 V3FeedUrl = "v3FeedUrl" 110 ContentSynchronisation = "contentSynchronisation" 111 ListRemoteFolderItems = "listRemoteFolderItems" 112 EnableTokenAuthentication = "enableTokenAuthentication" 113 PodsSpecsRepoUrl = "podsSpecsRepoUrl" 114 115 // Unique virtual repository configuration JSON keys 116 Repositories = "repositories" 117 ArtifactoryRequestsCanRetrieveRemoteArtifacts = "artifactoryRequestsCanRetrieveRemoteArtifacts" 118 KeyPair = "keyPair" 119 PomRepositoryReferencesCleanupPolicy = "pomRepositoryReferencesCleanupPolicy" 120 DefaultDeploymentRepo = "defaultDeploymentRepo" 121 ForceMavenAuthentication = "forceMavenAuthentication" 122 ExternalDependenciesRemoteRepo = "externalDependenciesRemoteRepo" 123 124 // rclasses 125 Local = "local" 126 Remote = "remote" 127 Virtual = "virtual" 128 129 // PackageTypes 130 Generic = "generic" 131 Maven = "maven" 132 Gradle = "gradle" 133 Ivy = "ivy" 134 Sbt = "sbt" 135 Helm = "helm" 136 Cocoapods = "cocoapods" 137 Opkg = "opkg" 138 Rpm = "rpm" 139 Nuget = "nuget" 140 Cran = "cran" 141 Gems = "gems" 142 Npm = "npm" 143 Bower = "bower" 144 Debian = "debian" 145 Composer = "composer" 146 Pypi = "pypi" 147 Docker = "docker" 148 Vagrant = "vagrant" 149 Gitlfs = "gitlfs" 150 Go = "go" 151 Yum = "yum" 152 Conan = "conan" 153 Chef = "chef" 154 Puppet = "puppet" 155 Vcs = "vcs" 156 Conda = "conda" 157 P2 = "p2" 158 159 // Repo layout Refs 160 BowerDefaultRepoLayout = "bower-default" 161 buildDefaultRepoLayout = "build-default" 162 ComposerDefaultRepoLayout = "composer-default" 163 ConanDefaultRepoLayout = "conan-default" 164 GoDefaultRepoLayout = "go-default" 165 GradleDefaultRepoLayout = "maven-2-default" 166 IvyDefaultRepoLayout = "ivy-default" 167 Maven1DefaultRepoLayout = "maven-1-default" 168 Maven2DefaultRepoLayout = "maven-2-default" 169 NpmDefaultRepoLayout = "npm-default" 170 NugetDefaultRepoLayout = "nuget-default" 171 puppetDefaultRepoLayout = "puppet-default" 172 SbtDefaultRepoLayout = "sbt-default" 173 SimpleDefaultRepoLayout = "simple-default" 174 VcsDefaultRepoLayout = "vcs-default" 175 176 // Checksum Policies 177 ClientChecksumPolicy = "client-checksums" 178 ServerGeneratedChecksumsPolicy = "server-generated-checksums" 179 180 // Snapshot version behaviors 181 UniqueBehavior = "unique" 182 NonUniqueBehavior = "non-unique" 183 DeployerBehavior = "deployer" 184 185 // Optional index compression formats 186 Bz2Compression = "bz2" 187 LzmaCompression = "lzma" 188 XzCompression = "xz" 189 190 // Docker api versions 191 DockerApiV1 = "V1" 192 DockerApiV2 = "V2" 193 194 // Remote repo checksum policies 195 GenerateIfAbsentPolicy = "generate-if-absent" 196 FailPolicy = "fail" 197 IgnoreAndGeneratePolicy = "ignore-and-generate" 198 PassThruPolicy = "pass-thru" 199 200 // Vcs Types 201 Git = "GIT" 202 203 // Vcs git provider 204 GithubVcsProvider = "GITHUB" 205 BitbucketVcsProvider = "BITBUCKET" 206 OldstashVcsProvider = "OLDSTASH" 207 StashVcsProvider = "STASH" 208 ArtifactoryVcsProvider = "ARTIFACTORY" 209 CustomVcsProvider = "CUSTOM" 210 211 // POM repository references cleanup policies 212 DiscardActiveRefrencePolicy = "discard_active_reference" 213 DiscardAnyReferencePolicy = "discard_any_reference" 214 NothingPolicy = "nothing" 215 ) 216 217 var optionalSuggestsMap = map[string]prompt.Suggest{ 218 utils.SaveAndExit: {Text: utils.SaveAndExit}, 219 Description: {Text: Description}, 220 Notes: {Text: Notes}, 221 IncludePatterns: {Text: IncludePatterns}, 222 ExcludePatterns: {Text: ExcludePatterns}, 223 RepoLayoutRef: {Text: RepoLayoutRef}, 224 HandleReleases: {Text: HandleReleases}, 225 HandleSnapshots: {Text: HandleSnapshots}, 226 MaxUniqueSnapshots: {Text: MaxUniqueSnapshots}, 227 SuppressPomConsistencyChecks: {Text: SuppressPomConsistencyChecks}, 228 BlackedOut: {Text: BlackedOut}, 229 DownloadRedirect: {Text: DownloadRedirect}, 230 BlockPushingSchema1: {Text: BlockPushingSchema1}, 231 DebianTrivialLayout: {Text: DebianTrivialLayout}, 232 ExternalDependenciesEnabled: {Text: ExternalDependenciesEnabled}, 233 ExternalDependenciesPatterns: {Text: ExternalDependenciesPatterns}, 234 ChecksumPolicyType: {Text: ChecksumPolicyType}, 235 MaxUniqueTags: {Text: MaxUniqueTags}, 236 SnapshotVersionBehavior: {Text: SnapshotVersionBehavior}, 237 XrayIndex: {Text: XrayIndex}, 238 PropertySets: {Text: PropertySets}, 239 ArchiveBrowsingEnabled: {Text: ArchiveBrowsingEnabled}, 240 CalculateYumMetadata: {Text: CalculateYumMetadata}, 241 YumRootDepth: {Text: YumRootDepth}, 242 DockerApiVersion: {Text: DockerApiVersion}, 243 EnableFileListsIndexing: {Text: EnableFileListsIndexing}, 244 OptionalIndexCompressionFormats: {Text: OptionalIndexCompressionFormats}, 245 Url: {Text: Url}, 246 Username: {Text: Username}, 247 Password: {Text: Password}, 248 Proxy: {Text: Proxy}, 249 RemoteRepoChecksumPolicyType: {Text: RemoteRepoChecksumPolicyType}, 250 HardFail: {Text: HardFail}, 251 Offline: {Text: Offline}, 252 StoreArtifactsLocally: {Text: StoreArtifactsLocally}, 253 SocketTimeoutMillis: {Text: SocketTimeoutMillis}, 254 LocalAddress: {Text: LocalAddress}, 255 RetrievalCachePeriodSecs: {Text: RetrievalCachePeriodSecs}, 256 FailedRetrievalCachePeriodSecs: {Text: FailedRetrievalCachePeriodSecs}, 257 MissedRetrievalCachePeriodSecs: {Text: MissedRetrievalCachePeriodSecs}, 258 UnusedArtifactsCleanupEnabled: {Text: UnusedArtifactsCleanupEnabled}, 259 UnusedArtifactsCleanupPeriodHours: {Text: UnusedArtifactsCleanupPeriodHours}, 260 AssumedOfflinePeriodSecs: {Text: AssumedOfflinePeriodSecs}, 261 FetchJarsEagerly: {Text: FetchJarsEagerly}, 262 FetchSourcesEagerly: {Text: FetchSourcesEagerly}, 263 RejectInvalidJars: {Text: RejectInvalidJars}, 264 ShareConfiguration: {Text: ShareConfiguration}, 265 SynchronizeProperties: {Text: SynchronizeProperties}, 266 BlockMismatchingMimeTypes: {Text: BlockMismatchingMimeTypes}, 267 AllowAnyHostAuth: {Text: AllowAnyHostAuth}, 268 EnableCookieManagement: {Text: EnableCookieManagement}, 269 BowerRegistryUrl: {Text: BowerRegistryUrl}, 270 ComposerRegistryUrl: {Text: ComposerRegistryUrl}, 271 PyPIRegistryUrl: {Text: PyPIRegistryUrl}, 272 VcsType: {Text: VcsType}, 273 VcsGitProvider: {Text: VcsGitProvider}, 274 VcsGitDownloadUrl: {Text: VcsGitDownloadUrl}, 275 BypassHeadRequests: {Text: BypassHeadRequests}, 276 ClientTlsCertificate: {Text: ClientTlsCertificate}, 277 FeedContextPath: {Text: FeedContextPath}, 278 DownloadContextPath: {Text: DownloadContextPath}, 279 V3FeedUrl: {Text: V3FeedUrl}, 280 ContentSynchronisation: {Text: ContentSynchronisation}, 281 ListRemoteFolderItems: {Text: ListRemoteFolderItems}, 282 PodsSpecsRepoUrl: {Text: PodsSpecsRepoUrl}, 283 EnableTokenAuthentication: {Text: EnableTokenAuthentication}, 284 Repositories: {Text: Repositories}, 285 ArtifactoryRequestsCanRetrieveRemoteArtifacts: {Text: ArtifactoryRequestsCanRetrieveRemoteArtifacts}, 286 KeyPair: {Text: KeyPair}, 287 PomRepositoryReferencesCleanupPolicy: {Text: PomRepositoryReferencesCleanupPolicy}, 288 DefaultDeploymentRepo: {Text: DefaultDeploymentRepo}, 289 ForceMavenAuthentication: {Text: ForceMavenAuthentication}, 290 ExternalDependenciesRemoteRepo: {Text: ExternalDependenciesRemoteRepo}, 291 } 292 293 var baseLocalRepoConfKeys = []string{ 294 Description, Notes, IncludePatterns, ExcludePatterns, RepoLayoutRef, BlackedOut, XrayIndex, 295 PropertySets, ArchiveBrowsingEnabled, OptionalIndexCompressionFormats, DownloadRedirect, BlockPushingSchema1, 296 } 297 298 var mavenGradleLocalRepoConfKeys = []string{ 299 MaxUniqueSnapshots, HandleReleases, HandleSnapshots, SuppressPomConsistencyChecks, SnapshotVersionBehavior, ChecksumPolicyType, 300 } 301 302 var rpmLocalRepoConfKeys = []string{ 303 YumRootDepth, CalculateYumMetadata, EnableFileListsIndexing, 304 } 305 306 var nugetLocalRepoConfKeys = []string{ 307 MaxUniqueSnapshots, ForceNugetAuthentication, 308 } 309 310 var debianLocalRepoConfKeys = []string{ 311 DebianTrivialLayout, 312 } 313 314 var dockerLocalRepoConfKeys = []string{ 315 DockerApiVersion, MaxUniqueTags, 316 } 317 318 var baseRemoteRepoConfKeys = []string{ 319 Username, Password, Proxy, Description, Notes, IncludePatterns, ExcludePatterns, RepoLayoutRef, HardFail, Offline, 320 BlackedOut, XrayIndex, StoreArtifactsLocally, SocketTimeoutMillis, LocalAddress, RetrievalCachePeriodSecs, FailedRetrievalCachePeriodSecs, 321 MissedRetrievalCachePeriodSecs, UnusedArtifactsCleanupEnabled, UnusedArtifactsCleanupPeriodHours, AssumedOfflinePeriodSecs, 322 ShareConfiguration, SynchronizeProperties, BlockMismatchingMimeTypes, PropertySets, AllowAnyHostAuth, EnableCookieManagement, 323 BypassHeadRequests, ClientTlsCertificate, DownloadRedirect, BlockPushingSchema1, ContentSynchronisation, 324 } 325 326 var mavenGradleRemoteRepoConfKeys = []string{ 327 FetchJarsEagerly, FetchSourcesEagerly, RemoteRepoChecksumPolicyType, HandleReleases, HandleSnapshots, 328 SuppressPomConsistencyChecks, RejectInvalidJars, 329 } 330 331 var cocoapodsRemoteRepoConfKeys = []string{ 332 PodsSpecsRepoUrl, 333 } 334 335 var opkgRemoteRepoConfKeys = []string{ 336 ListRemoteFolderItems, 337 } 338 339 var rpmRemoteRepoConfKeys = []string{ 340 ListRemoteFolderItems, 341 } 342 343 var nugetRemoteRepoConfKeys = []string{ 344 FeedContextPath, DownloadContextPath, V3FeedUrl, ForceNugetAuthentication, 345 } 346 347 var gemsRemoteRepoConfKeys = []string{ 348 ListRemoteFolderItems, 349 } 350 351 var npmRemoteRepoConfKeys = []string{ 352 ListRemoteFolderItems, 353 } 354 355 var bowerRemoteRepoConfKeys = []string{ 356 BowerRegistryUrl, 357 } 358 359 var debianRemoteRepoConfKeys = []string{ 360 ListRemoteFolderItems, 361 } 362 363 var composerRemoteRepoConfKeys = []string{ 364 ComposerRegistryUrl, 365 } 366 367 var pypiRemoteRepoConfKeys = []string{ 368 PyPIRegistryUrl, ListRemoteFolderItems, 369 } 370 371 var dockerRemoteRepoConfKeys = []string{ 372 ExternalDependenciesEnabled, ExternalDependenciesPatterns, EnableTokenAuthentication, 373 } 374 375 var gitlfsRemoteRepoConfKeys = []string{ 376 ListRemoteFolderItems, 377 } 378 379 var vcsRemoteRepoConfKeys = []string{ 380 VcsGitProvider, VcsType, MaxUniqueSnapshots, VcsGitDownloadUrl, ListRemoteFolderItems, 381 } 382 383 var genericRemoteRepoConfKeys = []string{ 384 ListRemoteFolderItems, 385 } 386 387 var baseVirtualRepoConfKeys = []string{ 388 Repositories, Description, Notes, IncludePatterns, ExcludePatterns, RepoLayoutRef, ArtifactoryRequestsCanRetrieveRemoteArtifacts, 389 DefaultDeploymentRepo, 390 } 391 392 var mavenGradleVirtualRepoConfKeys = []string{ 393 ForceMavenAuthentication, PomRepositoryReferencesCleanupPolicy, KeyPair, 394 } 395 396 var nugetVirtualRepoConfKeys = []string{ 397 ForceNugetAuthentication, 398 } 399 400 var npmVirtualRepoConfKeys = []string{ 401 ExternalDependenciesEnabled, ExternalDependenciesPatterns, ExternalDependenciesRemoteRepo, 402 } 403 404 var bowerVirtualRepoConfKeys = []string{ 405 ExternalDependenciesEnabled, ExternalDependenciesPatterns, ExternalDependenciesRemoteRepo, 406 } 407 408 var debianVirtualRepoConfKeys = []string{ 409 DebianTrivialLayout, 410 } 411 412 var goVirtualRepoConfKeys = []string{ 413 ExternalDependenciesEnabled, ExternalDependenciesPatterns, 414 } 415 416 var commonPkgTypes = []string{ 417 Maven, Gradle, Ivy, Sbt, Helm, Rpm, Nuget, Cran, Gems, Npm, Bower, Debian, Pypi, Docker, Gitlfs, Go, Yum, Conan, 418 Chef, Puppet, Generic, 419 } 420 421 var localRepoAdditionalPkgTypes = []string{ 422 Cocoapods, Opkg, Composer, Vagrant, 423 } 424 425 var remoteRepoAdditionalPkgTypes = []string{ 426 Cocoapods, Opkg, Composer, Conda, P2, Vcs, 427 } 428 429 var virtualRepoAdditionalPkgTypes = []string{ 430 Conda, P2, 431 } 432 433 var pkgTypeSuggestsMap = map[string]prompt.Suggest{ 434 Generic: {Text: Generic}, 435 Maven: {Text: Maven}, 436 Gradle: {Text: Gradle}, 437 Ivy: {Text: Ivy}, 438 Sbt: {Text: Sbt}, 439 Helm: {Text: Helm}, 440 Cocoapods: {Text: Cocoapods}, 441 Opkg: {Text: Opkg}, 442 Rpm: {Text: Rpm}, 443 Nuget: {Text: Nuget}, 444 Cran: {Text: Cran}, 445 Gems: {Text: Gems}, 446 Npm: {Text: Npm}, 447 Bower: {Text: Bower}, 448 Debian: {Text: Debian}, 449 Composer: {Text: Composer}, 450 Pypi: {Text: Pypi}, 451 Docker: {Text: Docker}, 452 Vagrant: {Text: Vagrant}, 453 Gitlfs: {Text: Gitlfs}, 454 Go: {Text: Go}, 455 Yum: {Text: Yum}, 456 Conan: {Text: Conan}, 457 Chef: {Text: Chef}, 458 Puppet: {Text: Puppet}, 459 Vcs: {Text: Vcs}, 460 Conda: {Text: Conda}, 461 P2: {Text: P2}, 462 } 463 464 func NewRepoTemplateCommand() *RepoTemplateCommand { 465 return &RepoTemplateCommand{} 466 } 467 468 func (rtc *RepoTemplateCommand) SetTemplatePath(path string) *RepoTemplateCommand { 469 rtc.path = path 470 return rtc 471 } 472 473 func (rtc *RepoTemplateCommand) ServerDetails() (*config.ServerDetails, error) { 474 // Since it's a local command, usage won't be reported. 475 return nil, nil 476 } 477 478 func (rtc *RepoTemplateCommand) Run() (err error) { 479 err = utils.ValidateTemplatePath(rtc.path) 480 if err != nil { 481 return 482 } 483 repoTemplateQuestionnaire := &utils.InteractiveQuestionnaire{ 484 MandatoryQuestionsKeys: []string{TemplateType, Key, Rclass}, 485 QuestionsMap: questionMap, 486 } 487 err = repoTemplateQuestionnaire.Perform() 488 if err != nil { 489 return err 490 } 491 resBytes, err := json.Marshal(repoTemplateQuestionnaire.AnswersMap) 492 if err != nil { 493 return errorutils.CheckError(err) 494 } 495 if err = os.WriteFile(rtc.path, resBytes, 0644); err != nil { 496 return errorutils.CheckError(err) 497 } 498 log.Info(fmt.Sprintf("Repository configuration template successfully created at %s.", rtc.path)) 499 500 return nil 501 } 502 503 func (rtc *RepoTemplateCommand) CommandName() string { 504 return "rt_repo_template" 505 } 506 507 func rclassCallback(iq *utils.InteractiveQuestionnaire, rclass string) (string, error) { 508 var pkgTypes []string 509 switch rclass { 510 case Remote: 511 // For create template url is mandatory, for update we will allow url as an optional key 512 if _, ok := iq.AnswersMap[TemplateType]; !ok { 513 return "", errors.New("package type is missing in configuration map") 514 } 515 if iq.AnswersMap[TemplateType] == Create { 516 iq.AskQuestion(iq.QuestionsMap[MandatoryUrl]) 517 } 518 pkgTypes = append(commonPkgTypes, remoteRepoAdditionalPkgTypes...) 519 case Local: 520 pkgTypes = append(commonPkgTypes, localRepoAdditionalPkgTypes...) 521 case Virtual: 522 pkgTypes = append(commonPkgTypes, virtualRepoAdditionalPkgTypes...) 523 default: 524 return "", errors.New("unsupported rclass") 525 } 526 // PackageType is also mandatory. Since the possible types depend on which rcalss was chosen, we ask the question here. 527 var pkgTypeQuestion = utils.QuestionInfo{ 528 Options: utils.GetSuggestsFromKeys(pkgTypes, pkgTypeSuggestsMap), 529 Msg: "", 530 PromptPrefix: "Select the repository's package type" + utils.PressTabMsg, 531 AllowVars: false, 532 Writer: utils.WriteStringAnswer, 533 MapKey: PackageType, 534 Callback: pkgTypeCallback, 535 } 536 return iq.AskQuestion(pkgTypeQuestion) 537 } 538 539 func pkgTypeCallback(iq *utils.InteractiveQuestionnaire, pkgType string) (string, error) { 540 // Each combination of (rclass,packageType) has its own optional configuration keys. 541 // We set the questionnaire's optionalKeys suggests according to the selected combination. 542 if _, ok := iq.AnswersMap[Rclass]; !ok { 543 return "", errors.New("rclass is missing in configuration map") 544 } 545 switch iq.AnswersMap[Rclass] { 546 case Local: 547 iq.OptionalKeysSuggests = getLocalRepoConfKeys(pkgType) 548 case Remote: 549 // For update template we need to allow url as an optional key 550 if _, ok := iq.AnswersMap[TemplateType]; !ok { 551 return "", errors.New("package type is missing in configuration map") 552 } 553 iq.OptionalKeysSuggests = getRemoteRepoConfKeys(pkgType, iq.AnswersMap[TemplateType].(string)) 554 case Virtual: 555 iq.OptionalKeysSuggests = getVirtualRepoConfKeys(pkgType) 556 default: 557 return "", errors.New("unsupported rclass was configured") 558 } 559 // We don't need the templateType value in the final configuration 560 delete(iq.AnswersMap, TemplateType) 561 return "", nil 562 } 563 564 func getLocalRepoConfKeys(pkgType string) []prompt.Suggest { 565 optionalKeys := []string{utils.SaveAndExit} 566 optionalKeys = append(optionalKeys, baseLocalRepoConfKeys...) 567 switch pkgType { 568 case Gradle: 569 case Maven: 570 optionalKeys = append(optionalKeys, mavenGradleLocalRepoConfKeys...) 571 case Rpm: 572 optionalKeys = append(optionalKeys, rpmLocalRepoConfKeys...) 573 case Nuget: 574 optionalKeys = append(optionalKeys, nugetLocalRepoConfKeys...) 575 case Debian: 576 optionalKeys = append(optionalKeys, debianLocalRepoConfKeys...) 577 case Docker: 578 optionalKeys = append(optionalKeys, dockerLocalRepoConfKeys...) 579 } 580 return utils.GetSuggestsFromKeys(optionalKeys, optionalSuggestsMap) 581 } 582 583 func getRemoteRepoConfKeys(pkgType, templateType string) []prompt.Suggest { 584 optionalKeys := []string{utils.SaveAndExit} 585 if templateType == Update { 586 optionalKeys = append(optionalKeys, Url) 587 } 588 optionalKeys = append(optionalKeys, baseRemoteRepoConfKeys...) 589 switch pkgType { 590 case Gradle: 591 case Maven: 592 optionalKeys = append(optionalKeys, mavenGradleRemoteRepoConfKeys...) 593 case Cocoapods: 594 optionalKeys = append(optionalKeys, cocoapodsRemoteRepoConfKeys...) 595 case Opkg: 596 optionalKeys = append(optionalKeys, opkgRemoteRepoConfKeys...) 597 case Rpm: 598 optionalKeys = append(optionalKeys, rpmRemoteRepoConfKeys...) 599 case Nuget: 600 optionalKeys = append(optionalKeys, nugetRemoteRepoConfKeys...) 601 case Gems: 602 optionalKeys = append(optionalKeys, gemsRemoteRepoConfKeys...) 603 case Npm: 604 optionalKeys = append(optionalKeys, npmRemoteRepoConfKeys...) 605 case Bower: 606 optionalKeys = append(optionalKeys, bowerRemoteRepoConfKeys...) 607 case Debian: 608 optionalKeys = append(optionalKeys, debianRemoteRepoConfKeys...) 609 case Composer: 610 optionalKeys = append(optionalKeys, composerRemoteRepoConfKeys...) 611 case Pypi: 612 optionalKeys = append(optionalKeys, pypiRemoteRepoConfKeys...) 613 case Docker: 614 optionalKeys = append(optionalKeys, dockerRemoteRepoConfKeys...) 615 case Gitlfs: 616 optionalKeys = append(optionalKeys, gitlfsRemoteRepoConfKeys...) 617 case Vcs: 618 optionalKeys = append(optionalKeys, vcsRemoteRepoConfKeys...) 619 } 620 return utils.GetSuggestsFromKeys(optionalKeys, optionalSuggestsMap) 621 } 622 623 func getVirtualRepoConfKeys(pkgType string) []prompt.Suggest { 624 optionalKeys := []string{utils.SaveAndExit} 625 optionalKeys = append(optionalKeys, baseVirtualRepoConfKeys...) 626 switch pkgType { 627 case Gradle: 628 case Maven: 629 optionalKeys = append(optionalKeys, mavenGradleVirtualRepoConfKeys...) 630 case Nuget: 631 optionalKeys = append(optionalKeys, nugetVirtualRepoConfKeys...) 632 case Npm: 633 optionalKeys = append(optionalKeys, npmVirtualRepoConfKeys...) 634 case Bower: 635 optionalKeys = append(optionalKeys, bowerVirtualRepoConfKeys...) 636 case Debian: 637 optionalKeys = append(optionalKeys, debianVirtualRepoConfKeys...) 638 case Go: 639 optionalKeys = append(optionalKeys, goVirtualRepoConfKeys...) 640 } 641 return utils.GetSuggestsFromKeys(optionalKeys, optionalSuggestsMap) 642 } 643 644 func contentSynchronisationCallBack(iq *utils.InteractiveQuestionnaire, answer string) (value string, err error) { 645 // contentSynchronisation has an object value with 4 bool fields. 646 // We ask for the rest of the values and writes the values in comma separated list. 647 if err != nil { 648 return "", nil 649 } 650 answer += "," + utils.AskFromList("", "Insert the value for statistic.enable >", false, utils.GetBoolSuggests(), "") 651 //cs.Statistics.Enabled, err = strconv.ParseBool(enabled) 652 if err != nil { 653 return "", nil 654 } 655 answer += "," + utils.AskFromList("", "Insert the value for properties.enable >", false, utils.GetBoolSuggests(), "") 656 //cs.Properties.Enabled, err = strconv.ParseBool(enabled) 657 if err != nil { 658 return "", nil 659 } 660 answer += "," + utils.AskFromList("", "Insert the value for source.originAbsenceDetection >", false, utils.GetBoolSuggests(), "") 661 //cs.Source.OriginAbsenceDetection, err = strconv.ParseBool(enabled) 662 if err != nil { 663 return "", nil 664 } 665 iq.AnswersMap[ContentSynchronisation] = answer 666 return "", nil 667 } 668 669 // Specific writers for repo templates, since all the values in the templates should be written as string 670 var BoolToStringQuestionInfo = utils.QuestionInfo{ 671 Options: utils.GetBoolSuggests(), 672 AllowVars: true, 673 Writer: utils.WriteStringAnswer, 674 } 675 676 var IntToStringQuestionInfo = utils.QuestionInfo{ 677 Options: nil, 678 AllowVars: true, 679 Writer: utils.WriteStringAnswer, 680 } 681 682 var StringListToStringQuestionInfo = utils.QuestionInfo{ 683 Msg: utils.CommaSeparatedListMsg, 684 Options: nil, 685 AllowVars: true, 686 Writer: utils.WriteStringAnswer, 687 } 688 689 var questionMap = map[string]utils.QuestionInfo{ 690 TemplateType: { 691 Options: []prompt.Suggest{ 692 {Text: Create, Description: "Template for creating a new repository"}, 693 {Text: Update, Description: "Template for updating an existing repository"}, 694 }, 695 Msg: "", 696 PromptPrefix: "Select the template type" + utils.PressTabMsg, 697 AllowVars: false, 698 Writer: utils.WriteStringAnswer, 699 MapKey: TemplateType, 700 Callback: nil, 701 }, 702 utils.OptionalKey: { 703 Msg: "", 704 PromptPrefix: SelectConfigKeyMsg, 705 AllowVars: false, 706 Writer: nil, 707 MapKey: "", 708 Callback: utils.OptionalKeyCallback, 709 }, 710 Key: { 711 Msg: "", 712 PromptPrefix: "Insert the repository key >", 713 AllowVars: true, 714 Writer: utils.WriteStringAnswer, 715 MapKey: Key, 716 Callback: nil, 717 }, 718 Rclass: { 719 Options: []prompt.Suggest{ 720 {Text: Local, Description: "A physical, locally-managed repository into which you can deploy artifacts"}, 721 {Text: Remote, Description: "A caching proxy for a repository managed at a remote URL"}, 722 {Text: Virtual, Description: "An Aggregation of several repositories with the same package type under a common URL."}, 723 }, 724 Msg: "", 725 PromptPrefix: "Select the repository class" + utils.PressTabMsg, 726 AllowVars: false, 727 Writer: utils.WriteStringAnswer, 728 MapKey: Rclass, 729 Callback: rclassCallback, 730 }, 731 MandatoryUrl: { 732 Msg: "", 733 PromptPrefix: "Insert the remote repository URL >", 734 AllowVars: true, 735 Writer: utils.WriteStringAnswer, 736 MapKey: Url, 737 Callback: nil, 738 }, 739 Url: utils.FreeStringQuestionInfo, 740 Description: utils.FreeStringQuestionInfo, 741 Notes: utils.FreeStringQuestionInfo, 742 IncludePatterns: StringListToStringQuestionInfo, 743 ExcludePatterns: StringListToStringQuestionInfo, 744 RepoLayoutRef: { 745 Options: []prompt.Suggest{ 746 {Text: BowerDefaultRepoLayout}, 747 {Text: buildDefaultRepoLayout}, 748 {Text: ComposerDefaultRepoLayout}, 749 {Text: ConanDefaultRepoLayout}, 750 {Text: GoDefaultRepoLayout}, 751 {Text: GradleDefaultRepoLayout}, 752 {Text: IvyDefaultRepoLayout}, 753 {Text: Maven1DefaultRepoLayout}, 754 {Text: Maven2DefaultRepoLayout}, 755 {Text: NpmDefaultRepoLayout}, 756 {Text: NugetDefaultRepoLayout}, 757 {Text: puppetDefaultRepoLayout}, 758 {Text: SbtDefaultRepoLayout}, 759 {Text: SimpleDefaultRepoLayout}, 760 {Text: VcsDefaultRepoLayout}, 761 }, 762 AllowVars: true, 763 Writer: utils.WriteStringAnswer, 764 }, 765 HandleReleases: BoolToStringQuestionInfo, 766 HandleSnapshots: BoolToStringQuestionInfo, 767 MaxUniqueSnapshots: IntToStringQuestionInfo, 768 SuppressPomConsistencyChecks: BoolToStringQuestionInfo, 769 BlackedOut: BoolToStringQuestionInfo, 770 DownloadRedirect: BoolToStringQuestionInfo, 771 BlockPushingSchema1: BoolToStringQuestionInfo, 772 DebianTrivialLayout: BoolToStringQuestionInfo, 773 ExternalDependenciesEnabled: BoolToStringQuestionInfo, 774 ExternalDependenciesPatterns: StringListToStringQuestionInfo, 775 ChecksumPolicyType: { 776 Options: []prompt.Suggest{ 777 {Text: ClientChecksumPolicy}, 778 {Text: ServerGeneratedChecksumsPolicy}, 779 }, 780 AllowVars: true, 781 Writer: utils.WriteStringAnswer, 782 }, 783 MaxUniqueTags: IntToStringQuestionInfo, 784 SnapshotVersionBehavior: { 785 Options: []prompt.Suggest{ 786 {Text: UniqueBehavior}, 787 {Text: NonUniqueBehavior}, 788 {Text: DeployerBehavior}, 789 }, 790 AllowVars: true, 791 Writer: utils.WriteStringAnswer, 792 }, 793 XrayIndex: BoolToStringQuestionInfo, 794 PropertySets: StringListToStringQuestionInfo, 795 ArchiveBrowsingEnabled: BoolToStringQuestionInfo, 796 CalculateYumMetadata: BoolToStringQuestionInfo, 797 YumRootDepth: IntToStringQuestionInfo, 798 DockerApiVersion: { 799 Options: []prompt.Suggest{ 800 {Text: DockerApiV1}, 801 {Text: DockerApiV2}, 802 }, 803 AllowVars: true, 804 Writer: utils.WriteStringAnswer, 805 }, 806 EnableFileListsIndexing: BoolToStringQuestionInfo, 807 OptionalIndexCompressionFormats: { 808 Msg: "Enter a comma separated list of values from " + strings.Join([]string{Bz2Compression, LzmaCompression, XzCompression}, ","), 809 Options: nil, 810 AllowVars: true, 811 Writer: utils.WriteStringArrayAnswer, 812 }, 813 Username: utils.FreeStringQuestionInfo, 814 Password: utils.FreeStringQuestionInfo, 815 Proxy: utils.FreeStringQuestionInfo, 816 RemoteRepoChecksumPolicyType: { 817 Options: []prompt.Suggest{ 818 {Text: GenerateIfAbsentPolicy}, 819 {Text: FailPolicy}, 820 {Text: IgnoreAndGeneratePolicy}, 821 {Text: PassThruPolicy}, 822 }, 823 AllowVars: true, 824 Writer: utils.WriteStringAnswer, 825 }, 826 HardFail: BoolToStringQuestionInfo, 827 Offline: BoolToStringQuestionInfo, 828 StoreArtifactsLocally: BoolToStringQuestionInfo, 829 SocketTimeoutMillis: IntToStringQuestionInfo, 830 LocalAddress: utils.FreeStringQuestionInfo, 831 RetrievalCachePeriodSecs: IntToStringQuestionInfo, 832 FailedRetrievalCachePeriodSecs: IntToStringQuestionInfo, 833 MissedRetrievalCachePeriodSecs: IntToStringQuestionInfo, 834 UnusedArtifactsCleanupEnabled: BoolToStringQuestionInfo, 835 UnusedArtifactsCleanupPeriodHours: IntToStringQuestionInfo, 836 AssumedOfflinePeriodSecs: IntToStringQuestionInfo, 837 FetchJarsEagerly: BoolToStringQuestionInfo, 838 FetchSourcesEagerly: BoolToStringQuestionInfo, 839 RejectInvalidJars: BoolToStringQuestionInfo, 840 ShareConfiguration: BoolToStringQuestionInfo, 841 SynchronizeProperties: BoolToStringQuestionInfo, 842 BlockMismatchingMimeTypes: BoolToStringQuestionInfo, 843 AllowAnyHostAuth: BoolToStringQuestionInfo, 844 EnableCookieManagement: BoolToStringQuestionInfo, 845 BowerRegistryUrl: utils.FreeStringQuestionInfo, 846 ComposerRegistryUrl: utils.FreeStringQuestionInfo, 847 PyPIRegistryUrl: utils.FreeStringQuestionInfo, 848 VcsType: { 849 Options: []prompt.Suggest{ 850 {Text: Git}, 851 }, 852 AllowVars: true, 853 Writer: utils.WriteStringAnswer, 854 }, 855 VcsGitProvider: { 856 Options: []prompt.Suggest{ 857 {Text: GithubVcsProvider}, 858 {Text: BitbucketVcsProvider}, 859 {Text: OldstashVcsProvider}, 860 {Text: StashVcsProvider}, 861 {Text: ArtifactoryVcsProvider}, 862 {Text: CustomVcsProvider}, 863 }, 864 AllowVars: true, 865 Writer: utils.WriteStringAnswer, 866 }, 867 VcsGitDownloadUrl: utils.FreeStringQuestionInfo, 868 BypassHeadRequests: BoolToStringQuestionInfo, 869 ClientTlsCertificate: utils.FreeStringQuestionInfo, 870 FeedContextPath: utils.FreeStringQuestionInfo, 871 DownloadContextPath: utils.FreeStringQuestionInfo, 872 V3FeedUrl: utils.FreeStringQuestionInfo, 873 ListRemoteFolderItems: BoolToStringQuestionInfo, 874 EnableTokenAuthentication: BoolToStringQuestionInfo, 875 PodsSpecsRepoUrl: utils.FreeStringQuestionInfo, 876 ContentSynchronisation: { 877 Options: utils.GetBoolSuggests(), 878 AllowVars: true, 879 Writer: nil, 880 Callback: contentSynchronisationCallBack, 881 }, 882 Repositories: StringListToStringQuestionInfo, 883 ArtifactoryRequestsCanRetrieveRemoteArtifacts: BoolToStringQuestionInfo, 884 KeyPair: utils.FreeStringQuestionInfo, 885 PomRepositoryReferencesCleanupPolicy: { 886 Options: []prompt.Suggest{ 887 {Text: DiscardActiveRefrencePolicy}, 888 {Text: DiscardAnyReferencePolicy}, 889 {Text: NothingPolicy}, 890 }, 891 AllowVars: true, 892 Writer: utils.WriteStringAnswer, 893 }, 894 DefaultDeploymentRepo: utils.FreeStringQuestionInfo, 895 ForceMavenAuthentication: BoolToStringQuestionInfo, 896 ExternalDependenciesRemoteRepo: utils.FreeStringQuestionInfo, 897 }