github.com/jfrog/jfrog-cli-core/v2@v2.51.0/general/cisetup/pipelinesconfig.go (about) 1 package cisetup 2 3 import ( 4 "strings" 5 6 "github.com/jfrog/jfrog-cli-core/v2/utils/config" 7 "github.com/jfrog/jfrog-cli-core/v2/utils/coreutils" 8 "github.com/jfrog/jfrog-client-go/artifactory" 9 clientConfig "github.com/jfrog/jfrog-client-go/config" 10 "github.com/jfrog/jfrog-client-go/pipelines" 11 "github.com/jfrog/jfrog-client-go/pipelines/services" 12 "github.com/jfrog/jfrog-client-go/utils/errorutils" 13 "github.com/jfrog/jfrog-client-go/utils/log" 14 ) 15 16 const ( 17 PipelinesYamlName = "pipelines.yml" 18 ) 19 20 type JFrogPipelinesConfigurator struct { 21 SetupData *CiSetupData 22 PipelinesToken string 23 } 24 25 func (pc *JFrogPipelinesConfigurator) Config() (vcsIntName, rtIntName string, err error) { 26 log.Info("Configuring JFrog Pipelines...") 27 serviceDetails, err := config.GetSpecificConfig(ConfigServerId, false, false) 28 if err != nil { 29 return "", "", err 30 } 31 32 psm, err := pc.createPipelinesServiceManager(serviceDetails) 33 if err != nil { 34 return "", "", err 35 } 36 37 vcsIntName, vcsIntId, err := pc.createVcsIntegration(psm) 38 if err != nil { 39 return "", "", err 40 } 41 42 rtIntName, err = pc.createArtifactoryIntegration(psm, serviceDetails) 43 if err != nil { 44 return "", "", err 45 } 46 47 err = pc.doAddPipelineSource(psm, vcsIntId) 48 if err != nil { 49 return "", "", err 50 } 51 return vcsIntName, rtIntName, nil 52 } 53 54 func (pc *JFrogPipelinesConfigurator) doAddPipelineSource(psm *pipelines.PipelinesServicesManager, projectIntegrationId int) (err error) { 55 _, err = psm.AddPipelineSource(projectIntegrationId, pc.SetupData.GetRepoFullName(), pc.SetupData.GitBranch, PipelinesYamlName) 56 // If source already exists, ignore error. 57 if _, ok := err.(*services.SourceAlreadyExistsError); ok { 58 log.Debug("Pipeline Source for repo '" + pc.SetupData.GetRepoFullName() + "' and branch '" + pc.SetupData.GitBranch + "' already exists and will be used.") 59 err = nil 60 } 61 return 62 } 63 64 func (pc *JFrogPipelinesConfigurator) createPipelinesServiceManager(details *config.ServerDetails) (*pipelines.PipelinesServicesManager, error) { 65 // Create new details with pipelines token. 66 pipelinesDetails := *details 67 pipelinesDetails.AccessToken = pc.PipelinesToken 68 pipelinesDetails.User = "" 69 pipelinesDetails.Password = "" 70 71 certsPath, err := coreutils.GetJfrogCertsDir() 72 if err != nil { 73 return nil, err 74 } 75 pAuth, err := pipelinesDetails.CreatePipelinesAuthConfig() 76 if err != nil { 77 return nil, err 78 } 79 serviceConfig, err := clientConfig.NewConfigBuilder(). 80 SetServiceDetails(pAuth). 81 SetCertificatesPath(certsPath). 82 SetInsecureTls(pipelinesDetails.InsecureTls). 83 SetDryRun(false). 84 Build() 85 if err != nil { 86 return nil, err 87 } 88 return pipelines.New(serviceConfig) 89 } 90 91 func (pc *JFrogPipelinesConfigurator) createVcsIntegration(psm *pipelines.PipelinesServicesManager) (integrationName string, integrationId int, err error) { 92 switch pc.SetupData.GitProvider { 93 case Github: 94 integrationName = pc.createIntegrationName(services.GithubName) 95 integrationId, err = psm.CreateGithubIntegration(integrationName, pc.SetupData.VcsCredentials.AccessToken) 96 case GithubEnterprise: 97 integrationName = pc.createIntegrationName(services.GithubEnterpriseName) 98 integrationId, err = psm.CreateGithubEnterpriseIntegration(integrationName, pc.SetupData.VcsBaseUrl, pc.SetupData.VcsCredentials.AccessToken) 99 case Bitbucket: 100 integrationName = pc.createIntegrationName(services.BitbucketName) 101 integrationId, err = psm.CreateBitbucketIntegration(integrationName, pc.SetupData.VcsCredentials.User, pc.SetupData.VcsCredentials.AccessToken) 102 case BitbucketServer: 103 integrationName = pc.createIntegrationName(services.BitbucketServerName) 104 cred := pc.SetupData.VcsCredentials.AccessToken 105 if cred == "" { 106 cred = pc.SetupData.VcsCredentials.Password 107 } 108 integrationId, err = psm.CreateBitbucketServerIntegration(integrationName, pc.SetupData.VcsBaseUrl, pc.SetupData.VcsCredentials.User, cred) 109 case Gitlab: 110 integrationName = pc.createIntegrationName(services.GitlabName) 111 integrationId, err = psm.CreateGitlabIntegration(integrationName, pc.SetupData.VcsBaseUrl, pc.SetupData.VcsCredentials.AccessToken) 112 default: 113 return "", -1, errorutils.CheckErrorf("vcs type is not supported at the moment") 114 } 115 if _, ok := err.(*services.IntegrationAlreadyExistsError); ok { 116 // If integration already exists, get the id from pipelines. 117 log.Debug("Integration '" + integrationName + "' already exists and will be used. Fetching id from pipelines...") 118 var integration *services.Integration 119 integration, err = psm.GetIntegrationByName(integrationName) 120 if err != nil { 121 return 122 } 123 integrationId = integration.Id 124 } 125 return 126 } 127 128 func (pc *JFrogPipelinesConfigurator) createArtifactoryIntegration(psm *pipelines.PipelinesServicesManager, details *config.ServerDetails) (string, error) { 129 integrationName := pc.createIntegrationName("rt") 130 apiKey, err := pc.getApiKey(details) 131 if err != nil { 132 return "", err 133 } 134 user := details.User 135 _, err = psm.CreateArtifactoryIntegration(integrationName, details.ArtifactoryUrl, user, apiKey) 136 // If integration already exists, ignore error. 137 if _, ok := err.(*services.IntegrationAlreadyExistsError); ok { 138 log.Debug("Integration '" + integrationName + "' already exists and will be used.") 139 err = nil 140 } 141 return integrationName, err 142 } 143 144 // Get API Key if exists, generate one if needed. 145 func (pc *JFrogPipelinesConfigurator) getApiKey(details *config.ServerDetails) (string, error) { 146 // Try getting API Key for the user if exists. 147 asm, err := pc.createRtServiceManager(details) 148 if err != nil { 149 return "", err 150 } 151 apiKey, err := asm.GetAPIKey() 152 if err != nil || apiKey != "" { 153 return apiKey, err 154 } 155 156 // Generate API Key for the user. 157 return asm.CreateAPIKey() 158 } 159 160 func (pc *JFrogPipelinesConfigurator) createIntegrationName(intType string) string { 161 return intType + "_" + createPipelinesSuitableName(pc.SetupData, "integration") 162 } 163 164 func (pc *JFrogPipelinesConfigurator) createRtServiceManager(artDetails *config.ServerDetails) (artifactory.ArtifactoryServicesManager, error) { 165 certsPath, err := coreutils.GetJfrogCertsDir() 166 if err != nil { 167 return nil, err 168 } 169 artAuth, err := artDetails.CreateArtAuthConfig() 170 if err != nil { 171 return nil, err 172 } 173 serviceConfig, err := clientConfig.NewConfigBuilder(). 174 SetServiceDetails(artAuth). 175 SetCertificatesPath(certsPath). 176 SetInsecureTls(artDetails.InsecureTls). 177 SetDryRun(false). 178 Build() 179 if err != nil { 180 return nil, err 181 } 182 return artifactory.New(serviceConfig) 183 } 184 185 func createPipelinesSuitableName(data *CiSetupData, suffix string) string { 186 name := strings.Join([]string{data.ProjectDomain, data.RepositoryName, suffix}, "_") 187 // Pipelines does not allow "-" which might exist in repo names. 188 return strings.ReplaceAll(name, "-", "_") 189 }