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