github.com/SAP/jenkins-library@v1.362.0/cmd/abapEnvironmentCloneGitRepo.go (about) 1 package cmd 2 3 import ( 4 "time" 5 6 "github.com/SAP/jenkins-library/pkg/abaputils" 7 "github.com/SAP/jenkins-library/pkg/command" 8 piperhttp "github.com/SAP/jenkins-library/pkg/http" 9 "github.com/SAP/jenkins-library/pkg/log" 10 "github.com/SAP/jenkins-library/pkg/telemetry" 11 "github.com/pkg/errors" 12 ) 13 14 func abapEnvironmentCloneGitRepo(config abapEnvironmentCloneGitRepoOptions, _ *telemetry.CustomData) { 15 16 c := command.Command{} 17 18 c.Stdout(log.Writer()) 19 c.Stderr(log.Writer()) 20 21 var autils = abaputils.AbapUtils{ 22 Exec: &c, 23 } 24 25 apiManager := abaputils.SoftwareComponentApiManager{ 26 Client: &piperhttp.Client{}, 27 PollIntervall: 5 * time.Second, 28 } 29 // error situations should stop execution through log.Entry().Fatal() call which leads to an os.Exit(1) in the end 30 err := runAbapEnvironmentCloneGitRepo(&config, &autils, &apiManager) 31 if err != nil { 32 log.Entry().WithError(err).Fatal("step execution failed") 33 } 34 } 35 36 func runAbapEnvironmentCloneGitRepo(config *abapEnvironmentCloneGitRepoOptions, com abaputils.Communication, apiManager abaputils.SoftwareComponentApiManagerInterface) error { 37 // Mapping for options 38 subOptions := convertCloneConfig(config) 39 40 errConfig := checkConfiguration(config) 41 if errConfig != nil { 42 return errors.Wrap(errConfig, "The provided configuration is not allowed") 43 } 44 45 repositories, errGetRepos := abaputils.GetRepositories(&abaputils.RepositoriesConfig{BranchName: config.BranchName, RepositoryName: config.RepositoryName, Repositories: config.Repositories}, false) 46 if errGetRepos != nil { 47 return errors.Wrap(errGetRepos, "Could not read repositories") 48 } 49 50 // Determine the host, user and password, either via the input parameters or via a cloud foundry service key 51 connectionDetails, errorGetInfo := com.GetAbapCommunicationArrangementInfo(subOptions, "") 52 if errorGetInfo != nil { 53 return errors.Wrap(errorGetInfo, "Parameters for the ABAP Connection not available") 54 } 55 connectionDetails.CertificateNames = config.CertificateNames 56 57 log.Entry().Infof("Start cloning %v repositories", len(repositories)) 58 for _, repo := range repositories { 59 60 cloneError := cloneSingleRepo(apiManager, connectionDetails, repo, config, com) 61 if cloneError != nil { 62 return cloneError 63 } 64 } 65 abaputils.AddDefaultDashedLine(1) 66 log.Entry().Info("All repositories were cloned successfully") 67 return nil 68 } 69 70 func cloneSingleRepo(apiManager abaputils.SoftwareComponentApiManagerInterface, connectionDetails abaputils.ConnectionDetailsHTTP, repo abaputils.Repository, config *abapEnvironmentCloneGitRepoOptions, com abaputils.Communication) error { 71 72 // New API instance for each request 73 // Triggering the Clone of the repository into the ABAP Environment system 74 // Polling the status of the repository import on the ABAP Environment system 75 // If the repository had been cloned already, as checkout/pull has been done - polling the status is not necessary anymore 76 api, errGetAPI := apiManager.GetAPI(connectionDetails, repo) 77 if errGetAPI != nil { 78 return errors.Wrap(errGetAPI, "Could not initialize the connection to the system") 79 } 80 81 logString := repo.GetCloneLogString() 82 errorString := "Clone of " + logString + " failed on the ABAP system" 83 84 abaputils.AddDefaultDashedLine(1) 85 log.Entry().Info("Start cloning " + logString) 86 abaputils.AddDefaultDashedLine(1) 87 88 alreadyCloned, activeBranch, errCheckCloned := api.GetRepository() 89 if errCheckCloned != nil { 90 return errors.Wrapf(errCheckCloned, errorString) 91 } 92 93 if !alreadyCloned { 94 errClone := api.Clone() 95 if errClone != nil { 96 return errors.Wrapf(errClone, errorString) 97 } 98 99 status, errorPollEntity := abaputils.PollEntity(api, apiManager.GetPollIntervall()) 100 if errorPollEntity != nil { 101 return errors.Wrapf(errorPollEntity, errorString) 102 } 103 if status == "E" { 104 return errors.New("Clone of " + logString + " failed on the ABAP System") 105 } 106 log.Entry().Info("The " + logString + " was cloned successfully") 107 } else { 108 abaputils.AddDefaultDashedLine(2) 109 log.Entry().Infof("%s", "The repository / software component has already been cloned on the ABAP Environment system ") 110 log.Entry().Infof("%s", "If required, a `checkout branch`, and a `pull` will be performed instead") 111 abaputils.AddDefaultDashedLine(2) 112 var returnedError error 113 if repo.Branch != "" && !(activeBranch == repo.Branch) { 114 returnedError = runAbapEnvironmentCheckoutBranch(getCheckoutOptions(config, repo), com, apiManager) 115 abaputils.AddDefaultDashedLine(2) 116 if returnedError != nil { 117 return returnedError 118 } 119 } 120 returnedError = runAbapEnvironmentPullGitRepo(getPullOptions(config, repo), com, apiManager) 121 return returnedError 122 } 123 return nil 124 } 125 126 func getCheckoutOptions(config *abapEnvironmentCloneGitRepoOptions, repo abaputils.Repository) *abapEnvironmentCheckoutBranchOptions { 127 checkoutOptions := abapEnvironmentCheckoutBranchOptions{ 128 Username: config.Username, 129 Password: config.Password, 130 Host: config.Host, 131 RepositoryName: repo.Name, 132 BranchName: repo.Branch, 133 CfAPIEndpoint: config.CfAPIEndpoint, 134 CfOrg: config.CfOrg, 135 CfServiceInstance: config.CfServiceInstance, 136 CfServiceKeyName: config.CfServiceKeyName, 137 CfSpace: config.CfSpace, 138 } 139 return &checkoutOptions 140 } 141 142 func getPullOptions(config *abapEnvironmentCloneGitRepoOptions, repo abaputils.Repository) *abapEnvironmentPullGitRepoOptions { 143 pullOptions := abapEnvironmentPullGitRepoOptions{ 144 Username: config.Username, 145 Password: config.Password, 146 Host: config.Host, 147 RepositoryName: repo.Name, 148 CommitID: repo.CommitID, 149 CfAPIEndpoint: config.CfAPIEndpoint, 150 CfOrg: config.CfOrg, 151 CfServiceInstance: config.CfServiceInstance, 152 CfServiceKeyName: config.CfServiceKeyName, 153 CfSpace: config.CfSpace, 154 } 155 return &pullOptions 156 } 157 158 func checkConfiguration(config *abapEnvironmentCloneGitRepoOptions) error { 159 if config.Repositories != "" && config.RepositoryName != "" { 160 return errors.New("It is not allowed to configure the parameters `repositories`and `repositoryName` at the same time") 161 } 162 if config.Repositories == "" && config.RepositoryName == "" { 163 return errors.New("Please provide one of the following parameters: `repositories` or `repositoryName`") 164 } 165 return nil 166 } 167 168 func triggerClone(repo abaputils.Repository, api abaputils.SoftwareComponentApiInterface) (error, bool) { 169 170 //cloneConnectionDetails.URL = cloneConnectionDetails.URL + "/sap/opu/odata/sap/MANAGE_GIT_REPOSITORY/Clones" 171 172 // The entity "Clones" does not allow for polling. To poll the progress, the related entity "Pull" has to be called 173 // While "Clones" has the key fields UUID, SC_NAME and BRANCH_NAME, "Pull" only has the key field UUID 174 //uriConnectionDetails.URL = uriConnectionDetails.URL + "/sap/opu/odata/sap/MANAGE_GIT_REPOSITORY/Pull(uuid=guid'" + body.UUID + "')" 175 return nil, false 176 } 177 178 func convertCloneConfig(config *abapEnvironmentCloneGitRepoOptions) abaputils.AbapEnvironmentOptions { 179 subOptions := abaputils.AbapEnvironmentOptions{} 180 181 subOptions.CfAPIEndpoint = config.CfAPIEndpoint 182 subOptions.CfServiceInstance = config.CfServiceInstance 183 subOptions.CfServiceKeyName = config.CfServiceKeyName 184 subOptions.CfOrg = config.CfOrg 185 subOptions.CfSpace = config.CfSpace 186 subOptions.Host = config.Host 187 subOptions.Password = config.Password 188 subOptions.Username = config.Username 189 return subOptions 190 }