mirror of
https://github.com/SAP/jenkins-library.git
synced 2024-12-12 10:55:20 +02:00
dbc459d6ea
* chore: cleanup linting issues in abap steps * update * do not break on errors during testing * Fix warning Co-authored-by: Daniel Mieg <daniel.mieg@sap.com>
260 lines
8.6 KiB
Go
260 lines
8.6 KiB
Go
package cmd
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"net/http/cookiejar"
|
|
"strings"
|
|
"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 abapEnvironmentCreateTag(config abapEnvironmentCreateTagOptions, telemetryData *telemetry.CustomData) {
|
|
|
|
c := command.Command{}
|
|
|
|
c.Stdout(log.Writer())
|
|
c.Stderr(log.Writer())
|
|
|
|
var autils = abaputils.AbapUtils{
|
|
Exec: &c,
|
|
}
|
|
|
|
client := piperhttp.Client{}
|
|
|
|
if err := runAbapEnvironmentCreateTag(&config, telemetryData, &autils, &client); err != nil {
|
|
log.Entry().WithError(err).Fatal("step execution failed")
|
|
}
|
|
}
|
|
|
|
func runAbapEnvironmentCreateTag(config *abapEnvironmentCreateTagOptions, telemetryData *telemetry.CustomData, com abaputils.Communication, client piperhttp.Sender) error {
|
|
|
|
connectionDetails, errorGetInfo := com.GetAbapCommunicationArrangementInfo(convertTagConfig(config), "")
|
|
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")
|
|
}
|
|
|
|
client.SetOptions(piperhttp.ClientOptions{
|
|
MaxRequestDuration: 180 * time.Second,
|
|
CookieJar: cookieJar,
|
|
Username: connectionDetails.User,
|
|
Password: connectionDetails.Password,
|
|
})
|
|
|
|
backlog, errorPrepare := prepareBacklog(config)
|
|
if errorPrepare != nil {
|
|
return fmt.Errorf("Something failed during the tag creation: %w", errorPrepare)
|
|
}
|
|
|
|
return createTags(backlog, telemetryData, connectionDetails, client, com)
|
|
}
|
|
|
|
func createTags(backlog []CreateTagBacklog, telemetryData *telemetry.CustomData, con abaputils.ConnectionDetailsHTTP, client piperhttp.Sender, com abaputils.Communication) (err error) {
|
|
|
|
connection := con
|
|
connection.XCsrfToken = "fetch"
|
|
connection.URL = con.URL + "/sap/opu/odata/sap/MANAGE_GIT_REPOSITORY/Tags"
|
|
resp, err := abaputils.GetHTTPResponse("HEAD", connection, nil, client)
|
|
if err != nil {
|
|
return abaputils.HandleHTTPError(resp, err, "Authentication on the ABAP system failed", con)
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
log.Entry().WithField("StatusCode", resp.Status).WithField("ABAP Endpoint", connection.URL).Debug("Authentication on the ABAP system successful")
|
|
connection.XCsrfToken = resp.Header.Get("X-Csrf-Token")
|
|
|
|
errorOccurred := false
|
|
for _, item := range backlog {
|
|
err = createTagsForSingleItem(item, telemetryData, connection, client, com)
|
|
if err != nil {
|
|
errorOccurred = true
|
|
}
|
|
}
|
|
|
|
if errorOccurred {
|
|
message := "At least one tag has not been created"
|
|
log.Entry().Errorf(message)
|
|
return errors.New(message)
|
|
}
|
|
return nil
|
|
|
|
}
|
|
|
|
func createTagsForSingleItem(item CreateTagBacklog, telemetryData *telemetry.CustomData, con abaputils.ConnectionDetailsHTTP, client piperhttp.Sender, com abaputils.Communication) (err error) {
|
|
|
|
errorOccurred := false
|
|
for index := range item.tags {
|
|
err = createSingleTag(item, index, telemetryData, con, client, com)
|
|
if err != nil {
|
|
errorOccurred = true
|
|
}
|
|
}
|
|
if errorOccurred {
|
|
message := "At least one tag has not been created"
|
|
err = errors.New(message)
|
|
}
|
|
return err
|
|
}
|
|
|
|
func createSingleTag(item CreateTagBacklog, index int, telemetryData *telemetry.CustomData, con abaputils.ConnectionDetailsHTTP, client piperhttp.Sender, com abaputils.Communication) (err error) {
|
|
|
|
requestBodyStruct := CreateTagBody{RepositoryName: item.repositoryName, CommitID: item.commitID, Tag: item.tags[index].tagName, Description: item.tags[index].tagDescription}
|
|
requestBodyJson, err := json.Marshal(&requestBodyStruct)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
log.Entry().Debugf("Request body: %s", requestBodyJson)
|
|
resp, err := abaputils.GetHTTPResponse("POST", con, requestBodyJson, client)
|
|
if err != nil {
|
|
errorMessage := "Could not create tag " + requestBodyStruct.Tag + " for repository " + requestBodyStruct.RepositoryName + " with commitID " + requestBodyStruct.CommitID
|
|
err = abaputils.HandleHTTPError(resp, err, errorMessage, con)
|
|
return err
|
|
}
|
|
defer resp.Body.Close()
|
|
|
|
// Parse response
|
|
var createTagResponse CreateTagResponse
|
|
var abapResp map[string]*json.RawMessage
|
|
bodyText, _ := ioutil.ReadAll(resp.Body)
|
|
|
|
if err = json.Unmarshal(bodyText, &abapResp); err != nil {
|
|
return err
|
|
}
|
|
if err = json.Unmarshal(*abapResp["d"], &createTagResponse); err != nil {
|
|
return err
|
|
}
|
|
|
|
con.URL = con.Host + "/sap/opu/odata/sap/MANAGE_GIT_REPOSITORY/Pull(guid'" + createTagResponse.UUID + "')"
|
|
err = checkStatus(con, client, com)
|
|
|
|
if err == nil {
|
|
log.Entry().Info("Created tag " + requestBodyStruct.Tag + " for repository " + requestBodyStruct.RepositoryName + " with commitID " + requestBodyStruct.CommitID)
|
|
} else {
|
|
log.Entry().Error("NOT created: Tag " + requestBodyStruct.Tag + " for repository " + requestBodyStruct.RepositoryName + " with commitID " + requestBodyStruct.CommitID)
|
|
}
|
|
|
|
return err
|
|
}
|
|
|
|
func checkStatus(con abaputils.ConnectionDetailsHTTP, client piperhttp.Sender, com abaputils.Communication) (err error) {
|
|
var status string
|
|
pollIntervall := com.GetPollIntervall()
|
|
count := 0
|
|
for {
|
|
count += 1
|
|
entity, _, err := abaputils.GetStatus("Could not create Tag", con, client)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
status = entity.Status
|
|
if status != "R" {
|
|
if status == "E" {
|
|
err = errors.New("Could not create Tag")
|
|
}
|
|
return err
|
|
}
|
|
if count >= 200 {
|
|
return errors.New("Could not create Tag (Timeout)")
|
|
}
|
|
time.Sleep(pollIntervall)
|
|
}
|
|
}
|
|
|
|
func prepareBacklog(config *abapEnvironmentCreateTagOptions) (backlog []CreateTagBacklog, err error) {
|
|
|
|
if config.Repositories != "" && config.RepositoryName != "" {
|
|
return nil, errors.New("Configuring the parameter repositories and the parameter repositoryName at the same time is not allowed")
|
|
}
|
|
|
|
if config.RepositoryName != "" && config.CommitID != "" {
|
|
backlog = append(backlog, CreateTagBacklog{repositoryName: config.RepositoryName, commitID: config.CommitID})
|
|
}
|
|
|
|
if config.Repositories != "" {
|
|
descriptor, err := abaputils.ReadAddonDescriptor(config.Repositories) //config.Repositories should contain a file name
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
for _, repo := range descriptor.Repositories {
|
|
backlogInstance := CreateTagBacklog{repositoryName: repo.Name, commitID: repo.CommitID}
|
|
if config.GenerateTagForAddonComponentVersion && repo.VersionYAML != "" {
|
|
tag := Tag{tagName: "v" + repo.VersionYAML, tagDescription: "Generated by the ABAP Environment Pipeline"}
|
|
backlogInstance.tags = append(backlogInstance.tags, tag)
|
|
}
|
|
backlog = append(backlog, backlogInstance)
|
|
}
|
|
if config.GenerateTagForAddonProductVersion {
|
|
if descriptor.AddonProduct != "" && descriptor.AddonVersionYAML != "" {
|
|
addonProductDash := strings.Replace(descriptor.AddonProduct, "/", "-", 2)
|
|
backlog = addTagToList(backlog, addonProductDash+"-"+descriptor.AddonVersionYAML, "Generated by the ABAP Environment Pipeline")
|
|
} else {
|
|
log.Entry().WithField("generateTagForAddonProductVersion", config.GenerateTagForAddonProductVersion).WithField("AddonProduct", descriptor.AddonProduct).WithField("AddonVersion", descriptor.AddonVersionYAML).Infof("Not all required values are provided to create an addon product version tag")
|
|
}
|
|
}
|
|
}
|
|
if config.TagName != "" {
|
|
backlog = addTagToList(backlog, config.TagName, config.TagDescription)
|
|
}
|
|
return backlog, nil
|
|
}
|
|
|
|
func addTagToList(backlog []CreateTagBacklog, tag string, description string) []CreateTagBacklog {
|
|
|
|
for i, item := range backlog {
|
|
tag := Tag{tagName: tag, tagDescription: description}
|
|
backlog[i].tags = append(item.tags, tag)
|
|
}
|
|
return backlog
|
|
}
|
|
|
|
func convertTagConfig(config *abapEnvironmentCreateTagOptions) abaputils.AbapEnvironmentOptions {
|
|
subOptions := abaputils.AbapEnvironmentOptions{}
|
|
|
|
subOptions.CfAPIEndpoint = config.CfAPIEndpoint
|
|
subOptions.CfServiceInstance = config.CfServiceInstance
|
|
subOptions.CfServiceKeyName = config.CfServiceKeyName
|
|
subOptions.CfOrg = config.CfOrg
|
|
subOptions.CfSpace = config.CfSpace
|
|
subOptions.Host = config.Host
|
|
subOptions.Password = config.Password
|
|
subOptions.Username = config.Username
|
|
|
|
return subOptions
|
|
}
|
|
|
|
type CreateTagBacklog struct {
|
|
repositoryName string
|
|
commitID string
|
|
tags []Tag
|
|
}
|
|
|
|
type Tag struct {
|
|
tagName string
|
|
tagDescription string
|
|
}
|
|
|
|
type CreateTagBody struct {
|
|
RepositoryName string `json:"sc_name"`
|
|
CommitID string `json:"commit_id"`
|
|
Tag string `json:"tag_name"`
|
|
Description string `json:"tag_description"`
|
|
}
|
|
|
|
type CreateTagResponse struct {
|
|
UUID string `json:"uuid"`
|
|
}
|