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  }