2020-08-04 17:52:28 +02:00
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 abapEnvironmentCheckoutBranch ( options abapEnvironmentCheckoutBranchOptions , 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 := runAbapEnvironmentCheckoutBranch ( & options , telemetryData , & autils , & client )
if err != nil {
log . Entry ( ) . WithError ( err ) . Fatal ( "step execution failed" )
}
}
func runAbapEnvironmentCheckoutBranch ( options * abapEnvironmentCheckoutBranchOptions , 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/" )
if errorGetInfo != nil {
log . Entry ( ) . WithError ( errorGetInfo ) . Fatal ( "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 )
2020-08-07 11:09:58 +02:00
pollIntervall := com . GetPollIntervall ( )
2020-08-04 17:52:28 +02:00
log . Entry ( ) . Infof ( "Starting to switch branch to branch '%v' on repository '%v'" , options . BranchName , options . RepositoryName )
log . Entry ( ) . Info ( "--------------------------------" )
log . Entry ( ) . Info ( "Start checkout branch: " + options . BranchName )
log . Entry ( ) . Info ( "--------------------------------" )
// Triggering the Checkout of the repository into the ABAP Environment system
uriConnectionDetails , errorTriggerCheckout := triggerCheckout ( options . RepositoryName , options . BranchName , connectionDetails , client )
if errorTriggerCheckout != nil {
log . Entry ( ) . WithError ( errorTriggerCheckout ) . Fatal ( "Checkout of " + options . BranchName + " for software component " + options . RepositoryName + " failed on the ABAP System" )
}
// Polling the status of the repository import on the ABAP Environment system
status , errorPollEntity := abaputils . PollEntity ( options . RepositoryName , uriConnectionDetails , client , pollIntervall )
if errorPollEntity != nil {
log . Entry ( ) . WithError ( errorPollEntity ) . Fatal ( "Status of checkout action on repository" + options . RepositoryName + " failed on the ABAP System" )
}
if status == "E" {
log . Entry ( ) . Fatal ( "Checkout of branch " + options . BranchName + " failed on the ABAP System" )
}
log . Entry ( ) . Info ( "--------------------------------" )
log . Entry ( ) . Infof ( "Checkout of branch %v on repository %v was successful" , options . BranchName , options . RepositoryName )
log . Entry ( ) . Info ( "--------------------------------" )
return nil
}
func triggerCheckout ( repositoryName string , branchName string , checkoutConnectionDetails abaputils . ConnectionDetailsHTTP , client piperhttp . Sender ) ( abaputils . ConnectionDetailsHTTP , error ) {
uriConnectionDetails := checkoutConnectionDetails
uriConnectionDetails . URL = ""
checkoutConnectionDetails . XCsrfToken = "fetch"
// Loging into the ABAP System - getting the x-csrf-token and cookies
resp , err := abaputils . GetHTTPResponse ( "HEAD" , checkoutConnectionDetails , nil , client )
if err != nil {
err = abaputils . HandleHTTPError ( resp , err , "Authentication on the ABAP system failed" , checkoutConnectionDetails )
return uriConnectionDetails , err
}
defer resp . Body . Close ( )
log . Entry ( ) . WithField ( "StatusCode" , resp . Status ) . WithField ( "ABAP Endpoint" , checkoutConnectionDetails . URL ) . Info ( "Authentication on the ABAP system was successful" )
uriConnectionDetails . XCsrfToken = resp . Header . Get ( "X-Csrf-Token" )
checkoutConnectionDetails . XCsrfToken = uriConnectionDetails . XCsrfToken
// the request looks like: POST/sap/opu/odata/sap/MANAGE_GIT_REPOSITORY/checkout_branch?branch_name='newBranch'&sc_name=/DMO/GIT_REPOSITORY'
checkoutConnectionDetails . URL = checkoutConnectionDetails . URL + ` /checkout_branch?branch_name=' ` + branchName + ` '&sc_name=' ` + repositoryName + ` ' `
jsonBody := [ ] byte ( ` ` )
// no JSON body needed
resp , err = abaputils . GetHTTPResponse ( "POST" , checkoutConnectionDetails , jsonBody , client )
if err != nil {
err = abaputils . HandleHTTPError ( resp , err , "Could not trigger checkout of branch " + branchName , uriConnectionDetails )
return uriConnectionDetails , err
}
defer resp . Body . Close ( )
log . Entry ( ) . WithField ( "StatusCode" , resp . Status ) . WithField ( "repositoryName" , repositoryName ) . WithField ( "branchName" , branchName ) . Info ( "Triggered checkout of branch" )
// 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 ( "branchName" , branchName ) . Error ( "Could not switch to specified branch" )
err := errors . New ( "Request to ABAP System failed" )
return uriConnectionDetails , err
}
expandLog := "?$expand=to_Execution_log,to_Transport_log"
uriConnectionDetails . URL = body . Metadata . URI + expandLog
return uriConnectionDetails , nil
}