package cmd import ( "encoding/json" "io/ioutil" "net/http/cookiejar" "reflect" "time" "github.com/SAP/jenkins-library/pkg/abaputils" "github.com/SAP/jenkins-library/pkg/command" piperhttp "github.com/SAP/jenkins-library/pkg/http" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/telemetry" "github.com/pkg/errors" ) func abapEnvironmentPullGitRepo(options abapEnvironmentPullGitRepoOptions, telemetryData *telemetry.CustomData) { // for command execution use Command c := command.Command{} // reroute command output to logging framework c.Stdout(log.Writer()) c.Stderr(log.Writer()) var autils = abaputils.AbapUtils{ Exec: &c, } client := piperhttp.Client{} // for http calls import piperhttp "github.com/SAP/jenkins-library/pkg/http" // and use a &piperhttp.Client{} in a custom system // Example: step checkmarxExecuteScan.go // error situations should stop execution through log.Entry().Fatal() call which leads to an os.Exit(1) in the end err := runAbapEnvironmentPullGitRepo(&options, telemetryData, &autils, &client) if err != nil { log.Entry().WithError(err).Fatal("step execution failed") } } func runAbapEnvironmentPullGitRepo(options *abapEnvironmentPullGitRepoOptions, telemetryData *telemetry.CustomData, com abaputils.Communication, client piperhttp.Sender) error { // Mapping for options subOptions := abaputils.AbapEnvironmentOptions{} subOptions.CfAPIEndpoint = options.CfAPIEndpoint subOptions.CfServiceInstance = options.CfServiceInstance subOptions.CfServiceKeyName = options.CfServiceKeyName subOptions.CfOrg = options.CfOrg subOptions.CfSpace = options.CfSpace subOptions.Host = options.Host subOptions.Password = options.Password subOptions.Username = options.Username // Determine the host, user and password, either via the input parameters or via a cloud foundry service key connectionDetails, errorGetInfo := com.GetAbapCommunicationArrangementInfo(subOptions, "/sap/opu/odata/sap/MANAGE_GIT_REPOSITORY/Pull") if errorGetInfo != nil { return errors.Wrap(errorGetInfo, "Parameters for the ABAP Connection not available") } // Configuring the HTTP Client and CookieJar cookieJar, errorCookieJar := cookiejar.New(nil) if errorCookieJar != nil { return errors.Wrap(errorCookieJar, "Could not create a Cookie Jar") } clientOptions := piperhttp.ClientOptions{ MaxRequestDuration: 180 * time.Second, CookieJar: cookieJar, Username: connectionDetails.User, Password: connectionDetails.Password, } client.SetOptions(clientOptions) pollIntervall := 10 * time.Second log.Entry().Infof("Start pulling %v repositories", len(options.RepositoryNames)) for _, repositoryName := range options.RepositoryNames { log.Entry().Info("-------------------------") log.Entry().Info("Start pulling " + repositoryName) log.Entry().Info("-------------------------") // Triggering the Pull of the repository into the ABAP Environment system uriConnectionDetails, errorTriggerPull := triggerPull(repositoryName, connectionDetails, client) if errorTriggerPull != nil { return errors.Wrapf(errorTriggerPull, "Pull of '%s' failed on the ABAP System", repositoryName) } // Polling the status of the repository import on the ABAP Environment system status, errorPollEntity := abaputils.PollEntity(repositoryName, uriConnectionDetails, client, pollIntervall) if errorPollEntity != nil { return errors.Wrapf(errorPollEntity, "Pull of '%s' failed on the ABAP System", repositoryName) } if status == "E" { return errors.New("Pull of " + repositoryName + " failed on the ABAP System") } log.Entry().Info(repositoryName + " was pulled successfully") } log.Entry().Info("-------------------------") log.Entry().Info("All repositories were pulled successfully") return nil } func triggerPull(repositoryName string, pullConnectionDetails abaputils.ConnectionDetailsHTTP, client piperhttp.Sender) (abaputils.ConnectionDetailsHTTP, error) { uriConnectionDetails := pullConnectionDetails uriConnectionDetails.URL = "" pullConnectionDetails.XCsrfToken = "fetch" // Loging into the ABAP System - getting the x-csrf-token and cookies resp, err := abaputils.GetHTTPResponse("HEAD", pullConnectionDetails, nil, client) if err != nil { err = abaputils.HandleHTTPError(resp, err, "Authentication on the ABAP system failed", pullConnectionDetails) return uriConnectionDetails, err } defer resp.Body.Close() log.Entry().WithField("StatusCode", resp.Status).WithField("ABAP Endpoint", pullConnectionDetails.URL).Info("Authentication on the ABAP system successfull") uriConnectionDetails.XCsrfToken = resp.Header.Get("X-Csrf-Token") pullConnectionDetails.XCsrfToken = uriConnectionDetails.XCsrfToken // Trigger the Pull of a Repository if repositoryName == "" { return uriConnectionDetails, errors.New("An empty string was passed for the parameter 'repositoryName'") } jsonBody := []byte(`{"sc_name":"` + repositoryName + `"}`) resp, err = abaputils.GetHTTPResponse("POST", pullConnectionDetails, jsonBody, client) if err != nil { err = abaputils.HandleHTTPError(resp, err, "Could not pull the Repository / Software Component "+repositoryName, uriConnectionDetails) return uriConnectionDetails, err } defer resp.Body.Close() log.Entry().WithField("StatusCode", resp.Status).WithField("repositoryName", repositoryName).Info("Triggered Pull of Repository / Software Component") // Parse Response var body abaputils.PullEntity var abapResp map[string]*json.RawMessage bodyText, errRead := ioutil.ReadAll(resp.Body) if errRead != nil { return uriConnectionDetails, err } json.Unmarshal(bodyText, &abapResp) json.Unmarshal(*abapResp["d"], &body) if reflect.DeepEqual(abaputils.PullEntity{}, body) { log.Entry().WithField("StatusCode", resp.Status).WithField("repositoryName", repositoryName).Error("Could not pull the Repository / Software Component") err := errors.New("Request to ABAP System not successful") return uriConnectionDetails, err } expandLog := "?$expand=to_Execution_log,to_Transport_log" uriConnectionDetails.URL = body.Metadata.URI + expandLog return uriConnectionDetails, nil }