mirror of
https://github.com/SAP/jenkins-library.git
synced 2024-12-12 10:55:20 +02:00
Add ABAP step: createTag (#3633)
* Cloud Platform -> BTP * Initial generation of new step * add flag * wip * Fix warnings * Add command * Added Tag Decription * Add status check * Improve handling * Improve handling * Add test for happy path * Add test reports to gitignore * Add second test * Improve createTag * Add testcase * Adaptions * Add test * Update cmd/abapEnvironmentCreateTag.go Co-authored-by: tiloKo <70266685+tiloKo@users.noreply.github.com> * Update cmd/abapEnvironmentCreateTag.go Co-authored-by: tiloKo <70266685+tiloKo@users.noreply.github.com> * Adapt error handling * Improve coding * Add info * Disallow repositories and repositoryName at the same time * Regenerate * Adapt to feedback * Update cmd/abapEnvironmentCreateTag.go Co-authored-by: tiloKo <70266685+tiloKo@users.noreply.github.com> * Update cmd/abapEnvironmentCreateTag.go Co-authored-by: tiloKo <70266685+tiloKo@users.noreply.github.com> Co-authored-by: tiloKo <70266685+tiloKo@users.noreply.github.com>
This commit is contained in:
parent
d30395931b
commit
cda6e71ab9
5
.gitignore
vendored
5
.gitignore
vendored
@ -45,3 +45,8 @@ ATCResults.xml
|
||||
AUnitResults.xml
|
||||
ATCResults.html
|
||||
AUnitResults.html
|
||||
cmd/checkmarx/piper_checkmarx_report.json
|
||||
cmd/fortify/piper_fortify_report.html
|
||||
cmd/fortify/piper_fortify_report.json
|
||||
cmd/toolruns/toolrun_malwarescan_20220519143229.json
|
||||
cmd/toolruns/toolrun_protecode_20220519143230.json
|
||||
|
259
cmd/abapEnvironmentCreateTag.go
Normal file
259
cmd/abapEnvironmentCreateTag.go
Normal file
@ -0,0 +1,259 @@
|
||||
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) {
|
||||
status := "R"
|
||||
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"`
|
||||
}
|
321
cmd/abapEnvironmentCreateTag_generated.go
Normal file
321
cmd/abapEnvironmentCreateTag_generated.go
Normal file
@ -0,0 +1,321 @@
|
||||
// Code generated by piper's step-generator. DO NOT EDIT.
|
||||
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/SAP/jenkins-library/pkg/config"
|
||||
"github.com/SAP/jenkins-library/pkg/log"
|
||||
"github.com/SAP/jenkins-library/pkg/splunk"
|
||||
"github.com/SAP/jenkins-library/pkg/telemetry"
|
||||
"github.com/SAP/jenkins-library/pkg/validation"
|
||||
"github.com/spf13/cobra"
|
||||
)
|
||||
|
||||
type abapEnvironmentCreateTagOptions struct {
|
||||
Username string `json:"username,omitempty"`
|
||||
Password string `json:"password,omitempty"`
|
||||
Repositories string `json:"repositories,omitempty"`
|
||||
RepositoryName string `json:"repositoryName,omitempty"`
|
||||
CommitID string `json:"commitID,omitempty"`
|
||||
TagName string `json:"tagName,omitempty"`
|
||||
TagDescription string `json:"tagDescription,omitempty"`
|
||||
GenerateTagForAddonProductVersion bool `json:"generateTagForAddonProductVersion,omitempty"`
|
||||
GenerateTagForAddonComponentVersion bool `json:"generateTagForAddonComponentVersion,omitempty"`
|
||||
Host string `json:"host,omitempty"`
|
||||
CfAPIEndpoint string `json:"cfApiEndpoint,omitempty"`
|
||||
CfOrg string `json:"cfOrg,omitempty"`
|
||||
CfSpace string `json:"cfSpace,omitempty"`
|
||||
CfServiceInstance string `json:"cfServiceInstance,omitempty"`
|
||||
CfServiceKeyName string `json:"cfServiceKeyName,omitempty"`
|
||||
}
|
||||
|
||||
// AbapEnvironmentCreateTagCommand Creates a tag for a git repository to a SAP BTP ABAP Environment system
|
||||
func AbapEnvironmentCreateTagCommand() *cobra.Command {
|
||||
const STEP_NAME = "abapEnvironmentCreateTag"
|
||||
|
||||
metadata := abapEnvironmentCreateTagMetadata()
|
||||
var stepConfig abapEnvironmentCreateTagOptions
|
||||
var startTime time.Time
|
||||
var logCollector *log.CollectorHook
|
||||
var splunkClient *splunk.Splunk
|
||||
telemetryClient := &telemetry.Telemetry{}
|
||||
|
||||
var createAbapEnvironmentCreateTagCmd = &cobra.Command{
|
||||
Use: STEP_NAME,
|
||||
Short: "Creates a tag for a git repository to a SAP BTP ABAP Environment system",
|
||||
Long: `Creates tags for specific commits of one or multiple repositories / software components. The tag can be specified explicitly as well as being generated by an addon product version or an addon component version.
|
||||
Please provide either of the following options:
|
||||
|
||||
* The host and credentials the BTP ABAP Environment system itself. The credentials must be configured for the Communication Scenario [SAP_COM_0510](https://help.sap.com/viewer/65de2977205c403bbc107264b8eccf4b/Cloud/en-US/b04a9ae412894725a2fc539bfb1ca055.html).
|
||||
* The Cloud Foundry parameters (API endpoint, organization, space), credentials, the service instance for the ABAP service and the service key for the Communication Scenario SAP_COM_0510.
|
||||
* Only provide one of those options with the respective credentials. If all values are provided, the direct communication (via host) has priority.`,
|
||||
PreRunE: func(cmd *cobra.Command, _ []string) error {
|
||||
startTime = time.Now()
|
||||
log.SetStepName(STEP_NAME)
|
||||
log.SetVerbose(GeneralConfig.Verbose)
|
||||
|
||||
GeneralConfig.GitHubAccessTokens = ResolveAccessTokens(GeneralConfig.GitHubTokens)
|
||||
|
||||
path, _ := os.Getwd()
|
||||
fatalHook := &log.FatalHook{CorrelationID: GeneralConfig.CorrelationID, Path: path}
|
||||
log.RegisterHook(fatalHook)
|
||||
|
||||
err := PrepareConfig(cmd, &metadata, STEP_NAME, &stepConfig, config.OpenPiperFile)
|
||||
if err != nil {
|
||||
log.SetErrorCategory(log.ErrorConfiguration)
|
||||
return err
|
||||
}
|
||||
log.RegisterSecret(stepConfig.Username)
|
||||
log.RegisterSecret(stepConfig.Password)
|
||||
|
||||
if len(GeneralConfig.HookConfig.SentryConfig.Dsn) > 0 {
|
||||
sentryHook := log.NewSentryHook(GeneralConfig.HookConfig.SentryConfig.Dsn, GeneralConfig.CorrelationID)
|
||||
log.RegisterHook(&sentryHook)
|
||||
}
|
||||
|
||||
if len(GeneralConfig.HookConfig.SplunkConfig.Dsn) > 0 {
|
||||
splunkClient = &splunk.Splunk{}
|
||||
logCollector = &log.CollectorHook{CorrelationID: GeneralConfig.CorrelationID}
|
||||
log.RegisterHook(logCollector)
|
||||
}
|
||||
|
||||
validation, err := validation.New(validation.WithJSONNamesForStructFields(), validation.WithPredefinedErrorMessages())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err = validation.ValidateStruct(stepConfig); err != nil {
|
||||
log.SetErrorCategory(log.ErrorConfiguration)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
Run: func(_ *cobra.Command, _ []string) {
|
||||
stepTelemetryData := telemetry.CustomData{}
|
||||
stepTelemetryData.ErrorCode = "1"
|
||||
handler := func() {
|
||||
config.RemoveVaultSecretFiles()
|
||||
stepTelemetryData.Duration = fmt.Sprintf("%v", time.Since(startTime).Milliseconds())
|
||||
stepTelemetryData.ErrorCategory = log.GetErrorCategory().String()
|
||||
stepTelemetryData.PiperCommitHash = GitCommit
|
||||
telemetryClient.SetData(&stepTelemetryData)
|
||||
telemetryClient.Send()
|
||||
if len(GeneralConfig.HookConfig.SplunkConfig.Dsn) > 0 {
|
||||
splunkClient.Send(telemetryClient.GetData(), logCollector)
|
||||
}
|
||||
}
|
||||
log.DeferExitHandler(handler)
|
||||
defer handler()
|
||||
telemetryClient.Initialize(GeneralConfig.NoTelemetry, STEP_NAME)
|
||||
if len(GeneralConfig.HookConfig.SplunkConfig.Dsn) > 0 {
|
||||
splunkClient.Initialize(GeneralConfig.CorrelationID,
|
||||
GeneralConfig.HookConfig.SplunkConfig.Dsn,
|
||||
GeneralConfig.HookConfig.SplunkConfig.Token,
|
||||
GeneralConfig.HookConfig.SplunkConfig.Index,
|
||||
GeneralConfig.HookConfig.SplunkConfig.SendLogs)
|
||||
}
|
||||
abapEnvironmentCreateTag(stepConfig, &stepTelemetryData)
|
||||
stepTelemetryData.ErrorCode = "0"
|
||||
log.Entry().Info("SUCCESS")
|
||||
},
|
||||
}
|
||||
|
||||
addAbapEnvironmentCreateTagFlags(createAbapEnvironmentCreateTagCmd, &stepConfig)
|
||||
return createAbapEnvironmentCreateTagCmd
|
||||
}
|
||||
|
||||
func addAbapEnvironmentCreateTagFlags(cmd *cobra.Command, stepConfig *abapEnvironmentCreateTagOptions) {
|
||||
cmd.Flags().StringVar(&stepConfig.Username, "username", os.Getenv("PIPER_username"), "User for either the Cloud Foundry API or the Communication Arrangement for SAP_COM_0510")
|
||||
cmd.Flags().StringVar(&stepConfig.Password, "password", os.Getenv("PIPER_password"), "Password for either the Cloud Foundry API or the Communication Arrangement for SAP_COM_0510")
|
||||
cmd.Flags().StringVar(&stepConfig.Repositories, "repositories", os.Getenv("PIPER_repositories"), "Specifies a YAML file containing the repositories configuration")
|
||||
cmd.Flags().StringVar(&stepConfig.RepositoryName, "repositoryName", os.Getenv("PIPER_repositoryName"), "Specifies a repository (Software Components) on the SAP BTP ABAP Environment system")
|
||||
cmd.Flags().StringVar(&stepConfig.CommitID, "commitID", os.Getenv("PIPER_commitID"), "Specifies a commitID, for which a tag will be created")
|
||||
cmd.Flags().StringVar(&stepConfig.TagName, "tagName", os.Getenv("PIPER_tagName"), "Specifies a tagName that will be created for the repositories on the SAP BTP ABAP Environment system")
|
||||
cmd.Flags().StringVar(&stepConfig.TagDescription, "tagDescription", os.Getenv("PIPER_tagDescription"), "Specifies a description for the created tag")
|
||||
cmd.Flags().BoolVar(&stepConfig.GenerateTagForAddonProductVersion, "generateTagForAddonProductVersion", false, "Specifies if a tag will be created for the repositories on the SAP BTP ABAP Environment system")
|
||||
cmd.Flags().BoolVar(&stepConfig.GenerateTagForAddonComponentVersion, "generateTagForAddonComponentVersion", false, "Specifies if a tag will be created for the repositories on the SAP BTP ABAP Environment system")
|
||||
cmd.Flags().StringVar(&stepConfig.Host, "host", os.Getenv("PIPER_host"), "Specifies the host address of the SAP BTP ABAP Environment system")
|
||||
cmd.Flags().StringVar(&stepConfig.CfAPIEndpoint, "cfApiEndpoint", os.Getenv("PIPER_cfApiEndpoint"), "Cloud Foundry API Enpoint")
|
||||
cmd.Flags().StringVar(&stepConfig.CfOrg, "cfOrg", os.Getenv("PIPER_cfOrg"), "Cloud Foundry target organization")
|
||||
cmd.Flags().StringVar(&stepConfig.CfSpace, "cfSpace", os.Getenv("PIPER_cfSpace"), "Cloud Foundry target space")
|
||||
cmd.Flags().StringVar(&stepConfig.CfServiceInstance, "cfServiceInstance", os.Getenv("PIPER_cfServiceInstance"), "Cloud Foundry Service Instance")
|
||||
cmd.Flags().StringVar(&stepConfig.CfServiceKeyName, "cfServiceKeyName", os.Getenv("PIPER_cfServiceKeyName"), "Cloud Foundry Service Key")
|
||||
|
||||
cmd.MarkFlagRequired("username")
|
||||
cmd.MarkFlagRequired("password")
|
||||
}
|
||||
|
||||
// retrieve step metadata
|
||||
func abapEnvironmentCreateTagMetadata() config.StepData {
|
||||
var theMetaData = config.StepData{
|
||||
Metadata: config.StepMetadata{
|
||||
Name: "abapEnvironmentCreateTag",
|
||||
Aliases: []config.Alias{},
|
||||
Description: "Creates a tag for a git repository to a SAP BTP ABAP Environment system",
|
||||
},
|
||||
Spec: config.StepSpec{
|
||||
Inputs: config.StepInputs{
|
||||
Secrets: []config.StepSecrets{
|
||||
{Name: "abapCredentialsId", Description: "Jenkins credentials ID containing user and password to authenticate to the BTP ABAP Environment system or the Cloud Foundry API", Type: "jenkins", Aliases: []config.Alias{{Name: "cfCredentialsId", Deprecated: false}, {Name: "credentialsId", Deprecated: false}}},
|
||||
},
|
||||
Parameters: []config.StepParameters{
|
||||
{
|
||||
Name: "username",
|
||||
ResourceRef: []config.ResourceReference{
|
||||
{
|
||||
Name: "abapCredentialsId",
|
||||
Param: "username",
|
||||
Type: "secret",
|
||||
},
|
||||
},
|
||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||
Type: "string",
|
||||
Mandatory: true,
|
||||
Aliases: []config.Alias{},
|
||||
Default: os.Getenv("PIPER_username"),
|
||||
},
|
||||
{
|
||||
Name: "password",
|
||||
ResourceRef: []config.ResourceReference{
|
||||
{
|
||||
Name: "abapCredentialsId",
|
||||
Param: "password",
|
||||
Type: "secret",
|
||||
},
|
||||
},
|
||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||
Type: "string",
|
||||
Mandatory: true,
|
||||
Aliases: []config.Alias{},
|
||||
Default: os.Getenv("PIPER_password"),
|
||||
},
|
||||
{
|
||||
Name: "repositories",
|
||||
ResourceRef: []config.ResourceReference{},
|
||||
Scope: []string{"GENERAL", "PARAMETERS", "STAGES", "STEPS"},
|
||||
Type: "string",
|
||||
Mandatory: false,
|
||||
Aliases: []config.Alias{},
|
||||
Default: os.Getenv("PIPER_repositories"),
|
||||
},
|
||||
{
|
||||
Name: "repositoryName",
|
||||
ResourceRef: []config.ResourceReference{},
|
||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||
Type: "string",
|
||||
Mandatory: false,
|
||||
Aliases: []config.Alias{},
|
||||
Default: os.Getenv("PIPER_repositoryName"),
|
||||
},
|
||||
{
|
||||
Name: "commitID",
|
||||
ResourceRef: []config.ResourceReference{},
|
||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||
Type: "string",
|
||||
Mandatory: false,
|
||||
Aliases: []config.Alias{},
|
||||
Default: os.Getenv("PIPER_commitID"),
|
||||
},
|
||||
{
|
||||
Name: "tagName",
|
||||
ResourceRef: []config.ResourceReference{},
|
||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||
Type: "string",
|
||||
Mandatory: false,
|
||||
Aliases: []config.Alias{},
|
||||
Default: os.Getenv("PIPER_tagName"),
|
||||
},
|
||||
{
|
||||
Name: "tagDescription",
|
||||
ResourceRef: []config.ResourceReference{},
|
||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||
Type: "string",
|
||||
Mandatory: false,
|
||||
Aliases: []config.Alias{},
|
||||
Default: os.Getenv("PIPER_tagDescription"),
|
||||
},
|
||||
{
|
||||
Name: "generateTagForAddonProductVersion",
|
||||
ResourceRef: []config.ResourceReference{},
|
||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||
Type: "bool",
|
||||
Mandatory: false,
|
||||
Aliases: []config.Alias{},
|
||||
Default: false,
|
||||
},
|
||||
{
|
||||
Name: "generateTagForAddonComponentVersion",
|
||||
ResourceRef: []config.ResourceReference{},
|
||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||
Type: "bool",
|
||||
Mandatory: false,
|
||||
Aliases: []config.Alias{},
|
||||
Default: false,
|
||||
},
|
||||
{
|
||||
Name: "host",
|
||||
ResourceRef: []config.ResourceReference{},
|
||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS", "GENERAL"},
|
||||
Type: "string",
|
||||
Mandatory: false,
|
||||
Aliases: []config.Alias{},
|
||||
Default: os.Getenv("PIPER_host"),
|
||||
},
|
||||
{
|
||||
Name: "cfApiEndpoint",
|
||||
ResourceRef: []config.ResourceReference{},
|
||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS", "GENERAL"},
|
||||
Type: "string",
|
||||
Mandatory: false,
|
||||
Aliases: []config.Alias{{Name: "cloudFoundry/apiEndpoint"}},
|
||||
Default: os.Getenv("PIPER_cfApiEndpoint"),
|
||||
},
|
||||
{
|
||||
Name: "cfOrg",
|
||||
ResourceRef: []config.ResourceReference{},
|
||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS", "GENERAL"},
|
||||
Type: "string",
|
||||
Mandatory: false,
|
||||
Aliases: []config.Alias{{Name: "cloudFoundry/org"}},
|
||||
Default: os.Getenv("PIPER_cfOrg"),
|
||||
},
|
||||
{
|
||||
Name: "cfSpace",
|
||||
ResourceRef: []config.ResourceReference{},
|
||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS", "GENERAL"},
|
||||
Type: "string",
|
||||
Mandatory: false,
|
||||
Aliases: []config.Alias{{Name: "cloudFoundry/space"}},
|
||||
Default: os.Getenv("PIPER_cfSpace"),
|
||||
},
|
||||
{
|
||||
Name: "cfServiceInstance",
|
||||
ResourceRef: []config.ResourceReference{},
|
||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS", "GENERAL"},
|
||||
Type: "string",
|
||||
Mandatory: false,
|
||||
Aliases: []config.Alias{{Name: "cloudFoundry/serviceInstance"}},
|
||||
Default: os.Getenv("PIPER_cfServiceInstance"),
|
||||
},
|
||||
{
|
||||
Name: "cfServiceKeyName",
|
||||
ResourceRef: []config.ResourceReference{},
|
||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS", "GENERAL"},
|
||||
Type: "string",
|
||||
Mandatory: false,
|
||||
Aliases: []config.Alias{{Name: "cloudFoundry/serviceKey"}, {Name: "cloudFoundry/serviceKeyName"}, {Name: "cfServiceKey"}},
|
||||
Default: os.Getenv("PIPER_cfServiceKeyName"),
|
||||
},
|
||||
},
|
||||
},
|
||||
Containers: []config.Container{
|
||||
{Name: "cf", Image: "ppiper/cf-cli:7"},
|
||||
},
|
||||
},
|
||||
}
|
||||
return theMetaData
|
||||
}
|
17
cmd/abapEnvironmentCreateTag_generated_test.go
Normal file
17
cmd/abapEnvironmentCreateTag_generated_test.go
Normal file
@ -0,0 +1,17 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestAbapEnvironmentCreateTagCommand(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
testCmd := AbapEnvironmentCreateTagCommand()
|
||||
|
||||
// only high level testing performed - details are tested in step generation procedure
|
||||
assert.Equal(t, "abapEnvironmentCreateTag", testCmd.Use, "command name incorrect")
|
||||
|
||||
}
|
349
cmd/abapEnvironmentCreateTag_test.go
Normal file
349
cmd/abapEnvironmentCreateTag_test.go
Normal file
@ -0,0 +1,349 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/SAP/jenkins-library/pkg/abaputils"
|
||||
"github.com/SAP/jenkins-library/pkg/log"
|
||||
"github.com/SAP/jenkins-library/pkg/mock"
|
||||
"github.com/sirupsen/logrus/hooks/test"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
type abapEnvironmentCreateTagMockUtils struct {
|
||||
*mock.ExecMockRunner
|
||||
*mock.FilesMock
|
||||
}
|
||||
|
||||
func newAbapEnvironmentCreateTagTestsUtils() abapEnvironmentCreateTagMockUtils {
|
||||
utils := abapEnvironmentCreateTagMockUtils{
|
||||
ExecMockRunner: &mock.ExecMockRunner{},
|
||||
FilesMock: &mock.FilesMock{},
|
||||
}
|
||||
return utils
|
||||
}
|
||||
|
||||
func TestRunAbapEnvironmentCreateTag(t *testing.T) {
|
||||
|
||||
t.Run("happy path", func(t *testing.T) {
|
||||
|
||||
var autils = &abaputils.AUtilsMock{}
|
||||
defer autils.Cleanup()
|
||||
autils.ReturnedConnectionDetailsHTTP.Password = "password"
|
||||
autils.ReturnedConnectionDetailsHTTP.User = "user"
|
||||
autils.ReturnedConnectionDetailsHTTP.URL = "https://example.com"
|
||||
autils.ReturnedConnectionDetailsHTTP.XCsrfToken = "xcsrftoken"
|
||||
|
||||
dir, errDir := ioutil.TempDir("", "test read addon descriptor")
|
||||
if errDir != nil {
|
||||
t.Fatal("Failed to create temporary directory")
|
||||
}
|
||||
oldCWD, _ := os.Getwd()
|
||||
_ = os.Chdir(dir)
|
||||
// clean up tmp dir
|
||||
defer func() {
|
||||
_ = os.Chdir(oldCWD)
|
||||
_ = os.RemoveAll(dir)
|
||||
}()
|
||||
|
||||
body := `---
|
||||
addonVersion: "1.2.3"
|
||||
addonProduct: "/DMO/PRODUCT"
|
||||
repositories:
|
||||
- name: /DMO/SWC
|
||||
branch: main
|
||||
commitID: 1234abcd
|
||||
version: "4.5.6"
|
||||
`
|
||||
file, _ := os.Create("repo.yml")
|
||||
file.Write([]byte(body))
|
||||
config := &abapEnvironmentCreateTagOptions{
|
||||
Username: "dummy",
|
||||
Password: "dummy",
|
||||
Host: "https://test.com",
|
||||
Repositories: "repo.yml",
|
||||
TagName: "tag",
|
||||
TagDescription: "desc",
|
||||
GenerateTagForAddonProductVersion: true,
|
||||
GenerateTagForAddonComponentVersion: true,
|
||||
}
|
||||
client := &abaputils.ClientMock{
|
||||
BodyList: []string{
|
||||
`{"d" : { "Status" : "S" } }`,
|
||||
`{"d" : { "uuid" : "abc" } }`,
|
||||
`{"d" : { "Status" : "S" } }`,
|
||||
`{"d" : { "uuid" : "abc" } }`,
|
||||
`{"d" : { "Status" : "S" } }`,
|
||||
`{"d" : { "uuid" : "abc" } }`,
|
||||
`{"d" : { "empty" : "body" } }`,
|
||||
},
|
||||
Token: "myToken",
|
||||
StatusCode: 200,
|
||||
}
|
||||
|
||||
_, hook := test.NewNullLogger()
|
||||
log.RegisterHook(hook)
|
||||
|
||||
err := runAbapEnvironmentCreateTag(config, nil, autils, client)
|
||||
|
||||
assert.NoError(t, err, "Did not expect error")
|
||||
assert.Equal(t, 3, len(hook.Entries), "Expected a different number of entries")
|
||||
assert.Equal(t, `Created tag v4.5.6 for repository /DMO/SWC with commitID 1234abcd`, hook.AllEntries()[0].Message, "Expected a different message")
|
||||
assert.Equal(t, `Created tag -DMO-PRODUCT-1.2.3 for repository /DMO/SWC with commitID 1234abcd`, hook.AllEntries()[1].Message, "Expected a different message")
|
||||
assert.Equal(t, `Created tag tag for repository /DMO/SWC with commitID 1234abcd`, hook.AllEntries()[2].Message, "Expected a different message")
|
||||
hook.Reset()
|
||||
})
|
||||
|
||||
t.Run("backend error", func(t *testing.T) {
|
||||
|
||||
var autils = &abaputils.AUtilsMock{}
|
||||
defer autils.Cleanup()
|
||||
autils.ReturnedConnectionDetailsHTTP.Password = "password"
|
||||
autils.ReturnedConnectionDetailsHTTP.User = "user"
|
||||
autils.ReturnedConnectionDetailsHTTP.URL = "https://example.com"
|
||||
autils.ReturnedConnectionDetailsHTTP.XCsrfToken = "xcsrftoken"
|
||||
|
||||
dir, errDir := ioutil.TempDir("", "test read addon descriptor")
|
||||
if errDir != nil {
|
||||
t.Fatal("Failed to create temporary directory")
|
||||
}
|
||||
oldCWD, _ := os.Getwd()
|
||||
_ = os.Chdir(dir)
|
||||
// clean up tmp dir
|
||||
defer func() {
|
||||
_ = os.Chdir(oldCWD)
|
||||
_ = os.RemoveAll(dir)
|
||||
}()
|
||||
|
||||
body := `---
|
||||
addonVersion: "1.2.3"
|
||||
addonProduct: "/DMO/PRODUCT"
|
||||
repositories:
|
||||
- name: /DMO/SWC
|
||||
branch: main
|
||||
commitID: 1234abcd
|
||||
version: "4.5.6"
|
||||
`
|
||||
file, _ := os.Create("repo.yml")
|
||||
file.Write([]byte(body))
|
||||
config := &abapEnvironmentCreateTagOptions{
|
||||
Username: "dummy",
|
||||
Password: "dummy",
|
||||
Host: "https://test.com",
|
||||
Repositories: "repo.yml",
|
||||
TagName: "tag",
|
||||
TagDescription: "desc",
|
||||
GenerateTagForAddonProductVersion: true,
|
||||
GenerateTagForAddonComponentVersion: true,
|
||||
}
|
||||
client := &abaputils.ClientMock{
|
||||
BodyList: []string{
|
||||
`{"d" : { "Status" : "E" } }`,
|
||||
`{"d" : { "uuid" : "abc" } }`,
|
||||
`{"d" : { "Status" : "E" } }`,
|
||||
`{"d" : { "uuid" : "abc" } }`,
|
||||
`{"d" : { "Status" : "E" } }`,
|
||||
`{"d" : { "uuid" : "abc" } }`,
|
||||
`{"d" : { "empty" : "body" } }`,
|
||||
},
|
||||
Token: "myToken",
|
||||
StatusCode: 200,
|
||||
}
|
||||
|
||||
_, hook := test.NewNullLogger()
|
||||
log.RegisterHook(hook)
|
||||
|
||||
err := runAbapEnvironmentCreateTag(config, nil, autils, client)
|
||||
|
||||
assert.Error(t, err, "Did expect error")
|
||||
assert.Equal(t, 4, len(hook.Entries), "Expected a different number of entries")
|
||||
assert.Equal(t, `NOT created: Tag v4.5.6 for repository /DMO/SWC with commitID 1234abcd`, hook.AllEntries()[0].Message, "Expected a different message")
|
||||
assert.Equal(t, `NOT created: Tag -DMO-PRODUCT-1.2.3 for repository /DMO/SWC with commitID 1234abcd`, hook.AllEntries()[1].Message, "Expected a different message")
|
||||
assert.Equal(t, `NOT created: Tag tag for repository /DMO/SWC with commitID 1234abcd`, hook.AllEntries()[2].Message, "Expected a different message")
|
||||
assert.Equal(t, `At least one tag has not been created`, hook.AllEntries()[3].Message, "Expected a different message")
|
||||
hook.Reset()
|
||||
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func TestRunAbapEnvironmentCreateTagConfigurations(t *testing.T) {
|
||||
|
||||
t.Run("no repo.yml", func(t *testing.T) {
|
||||
|
||||
var autils = &abaputils.AUtilsMock{}
|
||||
defer autils.Cleanup()
|
||||
autils.ReturnedConnectionDetailsHTTP.Password = "password"
|
||||
autils.ReturnedConnectionDetailsHTTP.User = "user"
|
||||
autils.ReturnedConnectionDetailsHTTP.URL = "https://example.com"
|
||||
autils.ReturnedConnectionDetailsHTTP.XCsrfToken = "xcsrftoken"
|
||||
|
||||
config := &abapEnvironmentCreateTagOptions{
|
||||
Username: "dummy",
|
||||
Password: "dummy",
|
||||
Host: "https://test.com",
|
||||
RepositoryName: "/DMO/SWC",
|
||||
CommitID: "1234abcd",
|
||||
TagName: "tag",
|
||||
TagDescription: "desc",
|
||||
GenerateTagForAddonProductVersion: true,
|
||||
GenerateTagForAddonComponentVersion: true,
|
||||
}
|
||||
client := &abaputils.ClientMock{
|
||||
BodyList: []string{
|
||||
`{"d" : { "Status" : "S" } }`,
|
||||
`{"d" : { "uuid" : "abc" } }`,
|
||||
`{"d" : { "empty" : "body" } }`,
|
||||
},
|
||||
Token: "myToken",
|
||||
StatusCode: 200,
|
||||
}
|
||||
|
||||
_, hook := test.NewNullLogger()
|
||||
log.RegisterHook(hook)
|
||||
|
||||
err := runAbapEnvironmentCreateTag(config, nil, autils, client)
|
||||
|
||||
assert.NoError(t, err, "Did not expect error")
|
||||
assert.Equal(t, 1, len(hook.Entries), "Expected a different number of entries")
|
||||
assert.Equal(t, `Created tag tag for repository /DMO/SWC with commitID 1234abcd`, hook.AllEntries()[0].Message, "Expected a different message")
|
||||
hook.Reset()
|
||||
})
|
||||
|
||||
t.Run("backend error", func(t *testing.T) {
|
||||
|
||||
var autils = &abaputils.AUtilsMock{}
|
||||
defer autils.Cleanup()
|
||||
autils.ReturnedConnectionDetailsHTTP.Password = "password"
|
||||
autils.ReturnedConnectionDetailsHTTP.User = "user"
|
||||
autils.ReturnedConnectionDetailsHTTP.URL = "https://example.com"
|
||||
autils.ReturnedConnectionDetailsHTTP.XCsrfToken = "xcsrftoken"
|
||||
|
||||
dir, errDir := ioutil.TempDir("", "test read addon descriptor")
|
||||
if errDir != nil {
|
||||
t.Fatal("Failed to create temporary directory")
|
||||
}
|
||||
oldCWD, _ := os.Getwd()
|
||||
_ = os.Chdir(dir)
|
||||
// clean up tmp dir
|
||||
defer func() {
|
||||
_ = os.Chdir(oldCWD)
|
||||
_ = os.RemoveAll(dir)
|
||||
}()
|
||||
|
||||
body := `---
|
||||
addonVersion: "1.2.3"
|
||||
addonProduct: "/DMO/PRODUCT"
|
||||
repositories:
|
||||
- name: /DMO/SWC
|
||||
branch: main
|
||||
commitID: 1234abcd
|
||||
version: "4.5.6"
|
||||
`
|
||||
file, _ := os.Create("repo.yml")
|
||||
file.Write([]byte(body))
|
||||
config := &abapEnvironmentCreateTagOptions{
|
||||
Username: "dummy",
|
||||
Password: "dummy",
|
||||
Host: "https://test.com",
|
||||
Repositories: "repo.yml",
|
||||
RepositoryName: "/DMO/SWC2",
|
||||
CommitID: "1234abcde",
|
||||
TagName: "tag",
|
||||
TagDescription: "desc",
|
||||
GenerateTagForAddonProductVersion: true,
|
||||
GenerateTagForAddonComponentVersion: true,
|
||||
}
|
||||
client := &abaputils.ClientMock{
|
||||
BodyList: []string{
|
||||
`{"d" : { "Status" : "S" } }`,
|
||||
`{"d" : { "uuid" : "abc" } }`,
|
||||
`{"d" : { "Status" : "S" } }`,
|
||||
`{"d" : { "uuid" : "abc" } }`,
|
||||
`{"d" : { "Status" : "S" } }`,
|
||||
`{"d" : { "uuid" : "abc" } }`,
|
||||
`{"d" : { "Status" : "S" } }`,
|
||||
`{"d" : { "uuid" : "abc" } }`,
|
||||
`{"d" : { "Status" : "S" } }`,
|
||||
`{"d" : { "uuid" : "abc" } }`,
|
||||
`{"d" : { "empty" : "body" } }`,
|
||||
},
|
||||
Token: "myToken",
|
||||
StatusCode: 200,
|
||||
}
|
||||
|
||||
err := runAbapEnvironmentCreateTag(config, nil, autils, client)
|
||||
|
||||
assert.Error(t, err, "Did expect error")
|
||||
assert.Equal(t, "Something failed during the tag creation: Configuring the parameter repositories and the parameter repositoryName at the same time is not allowed", err.Error(), "Expected different error message")
|
||||
|
||||
})
|
||||
|
||||
t.Run("flags false", func(t *testing.T) {
|
||||
|
||||
var autils = &abaputils.AUtilsMock{}
|
||||
defer autils.Cleanup()
|
||||
autils.ReturnedConnectionDetailsHTTP.Password = "password"
|
||||
autils.ReturnedConnectionDetailsHTTP.User = "user"
|
||||
autils.ReturnedConnectionDetailsHTTP.URL = "https://example.com"
|
||||
autils.ReturnedConnectionDetailsHTTP.XCsrfToken = "xcsrftoken"
|
||||
|
||||
dir, errDir := ioutil.TempDir("", "test read addon descriptor")
|
||||
if errDir != nil {
|
||||
t.Fatal("Failed to create temporary directory")
|
||||
}
|
||||
oldCWD, _ := os.Getwd()
|
||||
_ = os.Chdir(dir)
|
||||
// clean up tmp dir
|
||||
defer func() {
|
||||
_ = os.Chdir(oldCWD)
|
||||
_ = os.RemoveAll(dir)
|
||||
}()
|
||||
|
||||
body := `---
|
||||
addonVersion: "1.2.3"
|
||||
addonProduct: "/DMO/PRODUCT"
|
||||
repositories:
|
||||
- name: /DMO/SWC
|
||||
branch: main
|
||||
commitID: 1234abcd
|
||||
version: "4.5.6"
|
||||
`
|
||||
file, _ := os.Create("repo.yml")
|
||||
file.Write([]byte(body))
|
||||
config := &abapEnvironmentCreateTagOptions{
|
||||
Username: "dummy",
|
||||
Password: "dummy",
|
||||
Host: "https://test.com",
|
||||
Repositories: "repo.yml",
|
||||
TagName: "tag",
|
||||
TagDescription: "desc",
|
||||
GenerateTagForAddonProductVersion: false,
|
||||
GenerateTagForAddonComponentVersion: false,
|
||||
}
|
||||
client := &abaputils.ClientMock{
|
||||
BodyList: []string{
|
||||
`{"d" : { "Status" : "S" } }`,
|
||||
`{"d" : { "uuid" : "abc" } }`,
|
||||
`{"d" : { "Status" : "S" } }`,
|
||||
`{"d" : { "uuid" : "abc" } }`,
|
||||
`{"d" : { "empty" : "body" } }`,
|
||||
},
|
||||
Token: "myToken",
|
||||
StatusCode: 200,
|
||||
}
|
||||
|
||||
_, hook := test.NewNullLogger()
|
||||
log.RegisterHook(hook)
|
||||
|
||||
err := runAbapEnvironmentCreateTag(config, nil, autils, client)
|
||||
|
||||
assert.NoError(t, err, "Did not expect error")
|
||||
assert.Equal(t, 1, len(hook.Entries), "Expected a different number of entries")
|
||||
assert.Equal(t, `Created tag tag for repository /DMO/SWC with commitID 1234abcd`, hook.AllEntries()[0].Message, "Expected a different message")
|
||||
hook.Reset()
|
||||
|
||||
})
|
||||
}
|
@ -20,6 +20,7 @@ func GetAllStepMetadata() map[string]config.StepData {
|
||||
"abapEnvironmentCheckoutBranch": abapEnvironmentCheckoutBranchMetadata(),
|
||||
"abapEnvironmentCloneGitRepo": abapEnvironmentCloneGitRepoMetadata(),
|
||||
"abapEnvironmentCreateSystem": abapEnvironmentCreateSystemMetadata(),
|
||||
"abapEnvironmentCreateTag": abapEnvironmentCreateTagMetadata(),
|
||||
"abapEnvironmentPullGitRepo": abapEnvironmentPullGitRepoMetadata(),
|
||||
"abapEnvironmentPushATCSystemConfig": abapEnvironmentPushATCSystemConfigMetadata(),
|
||||
"abapEnvironmentRunATCCheck": abapEnvironmentRunATCCheckMetadata(),
|
||||
|
@ -108,6 +108,7 @@ func Execute() {
|
||||
rootCmd.AddCommand(AbapEnvironmentPullGitRepoCommand())
|
||||
rootCmd.AddCommand(AbapEnvironmentCloneGitRepoCommand())
|
||||
rootCmd.AddCommand(AbapEnvironmentCheckoutBranchCommand())
|
||||
rootCmd.AddCommand(AbapEnvironmentCreateTagCommand())
|
||||
rootCmd.AddCommand(AbapEnvironmentCreateSystemCommand())
|
||||
rootCmd.AddCommand(CheckmarxExecuteScanCommand())
|
||||
rootCmd.AddCommand(FortifyExecuteScanCommand())
|
||||
|
@ -14,6 +14,8 @@ import (
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
const failureMessageClonePull = "Could not pull the Repository / Software Component "
|
||||
|
||||
// PollEntity periodically polls the pull/import entity to get the status. Check if the import is still running
|
||||
func PollEntity(repositoryName string, connectionDetails ConnectionDetailsHTTP, client piperhttp.Sender, pollIntervall time.Duration) (string, error) {
|
||||
|
||||
@ -21,7 +23,7 @@ func PollEntity(repositoryName string, connectionDetails ConnectionDetailsHTTP,
|
||||
var status string = "R"
|
||||
|
||||
for {
|
||||
pullEntity, responseStatus, err := GetPullStatus(repositoryName, connectionDetails, client)
|
||||
pullEntity, responseStatus, err := GetStatus(failureMessageClonePull+repositoryName, connectionDetails, client)
|
||||
if err != nil {
|
||||
return status, err
|
||||
}
|
||||
@ -78,7 +80,7 @@ func serviceContainsNewLogEntities(connectionDetails ConnectionDetailsHTTP, clie
|
||||
|
||||
func PrintLogs(repositoryName string, connectionDetails ConnectionDetailsHTTP, client piperhttp.Sender) {
|
||||
connectionDetails.URL = connectionDetails.URL + "?$expand=to_Log_Overview,to_Log_Overview/to_Log_Protocol"
|
||||
entity, _, err := GetPullStatus(repositoryName, connectionDetails, client)
|
||||
entity, _, err := GetStatus(failureMessageClonePull+repositoryName, connectionDetails, client)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@ -162,7 +164,7 @@ func printLog(logEntry LogResultsV2) {
|
||||
func PrintLegacyLogs(repositoryName string, connectionDetails ConnectionDetailsHTTP, client piperhttp.Sender, errorOnSystem bool) {
|
||||
|
||||
connectionDetails.URL = connectionDetails.URL + "?$expand=to_Transport_log,to_Execution_log"
|
||||
entity, _, err := GetPullStatus(repositoryName, connectionDetails, client)
|
||||
entity, _, err := GetStatus(failureMessageClonePull+repositoryName, connectionDetails, client)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
@ -212,11 +214,11 @@ func PrintLegacyLogs(repositoryName string, connectionDetails ConnectionDetailsH
|
||||
|
||||
}
|
||||
|
||||
func GetPullStatus(repositoryName string, connectionDetails ConnectionDetailsHTTP, client piperhttp.Sender) (body PullEntity, status string, err error) {
|
||||
func GetStatus(failureMessage string, connectionDetails ConnectionDetailsHTTP, client piperhttp.Sender) (body PullEntity, status string, err error) {
|
||||
resp, err := GetHTTPResponse("GET", connectionDetails, nil, client)
|
||||
if err != nil {
|
||||
log.SetErrorCategory(log.ErrorInfrastructure)
|
||||
err = HandleHTTPError(resp, err, "Could not pull the Repository / Software Component "+repositoryName, connectionDetails)
|
||||
err = HandleHTTPError(resp, err, failureMessage, connectionDetails)
|
||||
return body, resp.Status, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
@ -229,7 +231,7 @@ func GetPullStatus(repositoryName string, connectionDetails ConnectionDetailsHTT
|
||||
json.Unmarshal(*abapResp["d"], &body)
|
||||
|
||||
if reflect.DeepEqual(PullEntity{}, body) {
|
||||
log.Entry().WithField("StatusCode", resp.Status).WithField("repositoryName", repositoryName).Error("Could not pull the Repository / Software Component")
|
||||
log.Entry().WithField("StatusCode", resp.Status).Error(failureMessage)
|
||||
log.SetErrorCategory(log.ErrorInfrastructure)
|
||||
var err = errors.New("Request to ABAP System not successful")
|
||||
return body, resp.Status, err
|
||||
|
160
resources/metadata/abapEnvironmentCreateTag.yaml
Normal file
160
resources/metadata/abapEnvironmentCreateTag.yaml
Normal file
@ -0,0 +1,160 @@
|
||||
metadata:
|
||||
name: abapEnvironmentCreateTag
|
||||
description: Creates a tag for a git repository to a SAP BTP ABAP Environment system
|
||||
longDescription: |
|
||||
Creates tags for specific commits of one or multiple repositories / software components. The tag can be specified explicitly as well as being generated by an addon product version or an addon component version.
|
||||
Please provide either of the following options:
|
||||
|
||||
* The host and credentials the BTP ABAP Environment system itself. The credentials must be configured for the Communication Scenario [SAP_COM_0510](https://help.sap.com/viewer/65de2977205c403bbc107264b8eccf4b/Cloud/en-US/b04a9ae412894725a2fc539bfb1ca055.html).
|
||||
* The Cloud Foundry parameters (API endpoint, organization, space), credentials, the service instance for the ABAP service and the service key for the Communication Scenario SAP_COM_0510.
|
||||
* Only provide one of those options with the respective credentials. If all values are provided, the direct communication (via host) has priority.
|
||||
|
||||
spec:
|
||||
inputs:
|
||||
secrets:
|
||||
- name: abapCredentialsId
|
||||
description: Jenkins credentials ID containing user and password to authenticate to the BTP ABAP Environment system or the Cloud Foundry API
|
||||
type: jenkins
|
||||
aliases:
|
||||
- name: cfCredentialsId
|
||||
- name: credentialsId
|
||||
params:
|
||||
- name: username
|
||||
type: string
|
||||
description: User for either the Cloud Foundry API or the Communication Arrangement for SAP_COM_0510
|
||||
scope:
|
||||
- PARAMETERS
|
||||
- STAGES
|
||||
- STEPS
|
||||
mandatory: true
|
||||
secret: true
|
||||
resourceRef:
|
||||
- name: abapCredentialsId
|
||||
type: secret
|
||||
param: username
|
||||
- name: password
|
||||
type: string
|
||||
description: Password for either the Cloud Foundry API or the Communication Arrangement for SAP_COM_0510
|
||||
scope:
|
||||
- PARAMETERS
|
||||
- STAGES
|
||||
- STEPS
|
||||
mandatory: true
|
||||
secret: true
|
||||
resourceRef:
|
||||
- name: abapCredentialsId
|
||||
type: secret
|
||||
param: password
|
||||
- name: repositories
|
||||
type: string
|
||||
description: Specifies a YAML file containing the repositories configuration
|
||||
scope:
|
||||
- GENERAL
|
||||
- PARAMETERS
|
||||
- STAGES
|
||||
- STEPS
|
||||
- name: repositoryName
|
||||
type: string
|
||||
description: Specifies a repository (Software Components) on the SAP BTP ABAP Environment system
|
||||
scope:
|
||||
- PARAMETERS
|
||||
- STAGES
|
||||
- STEPS
|
||||
- name: commitID
|
||||
type: string
|
||||
description: Specifies a commitID, for which a tag will be created
|
||||
scope:
|
||||
- PARAMETERS
|
||||
- STAGES
|
||||
- STEPS
|
||||
- name: tagName
|
||||
type: string
|
||||
description: Specifies a tagName that will be created for the repositories on the SAP BTP ABAP Environment system
|
||||
scope:
|
||||
- PARAMETERS
|
||||
- STAGES
|
||||
- STEPS
|
||||
- name: tagDescription
|
||||
type: string
|
||||
description: Specifies a description for the created tag
|
||||
scope:
|
||||
- PARAMETERS
|
||||
- STAGES
|
||||
- STEPS
|
||||
- name: generateTagForAddonProductVersion
|
||||
type: bool
|
||||
description: Specifies if a tag will be created for the repositories on the SAP BTP ABAP Environment system
|
||||
scope:
|
||||
- PARAMETERS
|
||||
- STAGES
|
||||
- STEPS
|
||||
- name: generateTagForAddonComponentVersion
|
||||
type: bool
|
||||
description: Specifies if a tag will be created for the repositories on the SAP BTP ABAP Environment system
|
||||
scope:
|
||||
- PARAMETERS
|
||||
- STAGES
|
||||
- STEPS
|
||||
- name: host
|
||||
type: string
|
||||
description: Specifies the host address of the SAP BTP ABAP Environment system
|
||||
scope:
|
||||
- PARAMETERS
|
||||
- STAGES
|
||||
- STEPS
|
||||
- GENERAL
|
||||
- name: cfApiEndpoint
|
||||
type: string
|
||||
description: Cloud Foundry API Enpoint
|
||||
scope:
|
||||
- PARAMETERS
|
||||
- STAGES
|
||||
- STEPS
|
||||
- GENERAL
|
||||
aliases:
|
||||
- name: cloudFoundry/apiEndpoint
|
||||
- name: cfOrg
|
||||
type: string
|
||||
description: Cloud Foundry target organization
|
||||
scope:
|
||||
- PARAMETERS
|
||||
- STAGES
|
||||
- STEPS
|
||||
- GENERAL
|
||||
aliases:
|
||||
- name: cloudFoundry/org
|
||||
- name: cfSpace
|
||||
type: string
|
||||
description: Cloud Foundry target space
|
||||
scope:
|
||||
- PARAMETERS
|
||||
- STAGES
|
||||
- STEPS
|
||||
- GENERAL
|
||||
aliases:
|
||||
- name: cloudFoundry/space
|
||||
- name: cfServiceInstance
|
||||
type: string
|
||||
description: Cloud Foundry Service Instance
|
||||
scope:
|
||||
- PARAMETERS
|
||||
- STAGES
|
||||
- STEPS
|
||||
- GENERAL
|
||||
aliases:
|
||||
- name: cloudFoundry/serviceInstance
|
||||
- name: cfServiceKeyName
|
||||
type: string
|
||||
description: Cloud Foundry Service Key
|
||||
scope:
|
||||
- PARAMETERS
|
||||
- STAGES
|
||||
- STEPS
|
||||
- GENERAL
|
||||
aliases:
|
||||
- name: cloudFoundry/serviceKey
|
||||
- name: cloudFoundry/serviceKeyName
|
||||
- name: cfServiceKey
|
||||
containers:
|
||||
- name: cf
|
||||
image: ppiper/cf-cli:7
|
Loading…
Reference in New Issue
Block a user