From eecddf689c1102755eeddffede3aaa0409c2ffb7 Mon Sep 17 00:00:00 2001 From: Rinita Asani Date: Tue, 14 Feb 2023 11:38:46 +0100 Subject: [PATCH] New Configuration Parameters for gCTS steps (#4214) * Adding new query configuration parameter for gCTS Piper steps * Add skipSSLVerification parameter to gCTSExecuteQualityChecks * Add skipSSLVerification to gCTSDeploy * Add SkipSSLVerification for pull by commit * Add SkipSSLVerification to rollback * Add SkipSSLVerification parameter to rollback * Handling maximum number of charachter for the queryParameter * Remove extra new lines in yaml files * Add new line yaml files --- cmd/gctsCloneRepository.go | 6 + cmd/gctsCloneRepository_generated.go | 31 +++- cmd/gctsCreateRepository.go | 7 + cmd/gctsCreateRepository_generated.go | 39 +++-- cmd/gctsDeploy.go | 144 +++++++++++++++--- cmd/gctsDeploy_generated.go | 21 +++ cmd/gctsExecuteABAPQualityChecks.go | 103 ++++++++++++- cmd/gctsExecuteABAPQualityChecks_generated.go | 47 ++++-- cmd/gctsExecuteABAPUnitTests_generated.go | 47 ++++-- cmd/gctsRollback.go | 65 ++++++-- cmd/gctsRollback_generated.go | 35 ++++- resources/metadata/gctsCloneRepository.yaml | 17 +++ resources/metadata/gctsCreateRepository.yaml | 17 +++ resources/metadata/gctsDeploy.yaml | 17 +++ .../gctsExecuteABAPQualityChecks.yaml | 17 +++ .../metadata/gctsExecuteABAPUnitTests.yaml | 17 +++ resources/metadata/gctsRollback.yaml | 17 +++ 17 files changed, 558 insertions(+), 89 deletions(-) diff --git a/cmd/gctsCloneRepository.go b/cmd/gctsCloneRepository.go index bc26f88903..14d4b77c96 100644 --- a/cmd/gctsCloneRepository.go +++ b/cmd/gctsCloneRepository.go @@ -47,6 +47,12 @@ func cloneRepository(config *gctsCloneRepositoryOptions, telemetryData *telemetr "/sap/bc/cts_abapvcs/repository/" + config.Repository + "/clone?sap-client=" + config.Client + url, urlErr := addQueryToURL(url, config.QueryParameters) + + if urlErr != nil { + + return urlErr + } resp, httpErr := httpClient.SendRequest("POST", url, nil, header, nil) defer func() { diff --git a/cmd/gctsCloneRepository_generated.go b/cmd/gctsCloneRepository_generated.go index f2fdd185b1..fc70eb2519 100644 --- a/cmd/gctsCloneRepository_generated.go +++ b/cmd/gctsCloneRepository_generated.go @@ -16,11 +16,13 @@ import ( ) type gctsCloneRepositoryOptions struct { - Username string `json:"username,omitempty"` - Password string `json:"password,omitempty"` - Repository string `json:"repository,omitempty"` - Host string `json:"host,omitempty"` - Client string `json:"client,omitempty"` + Username string `json:"username,omitempty"` + Password string `json:"password,omitempty"` + Repository string `json:"repository,omitempty"` + Host string `json:"host,omitempty"` + Client string `json:"client,omitempty"` + QueryParameters map[string]interface{} `json:"queryParameters,omitempty"` + SkipSSLVerification bool `json:"skipSSLVerification,omitempty"` } // GctsCloneRepositoryCommand Clones a Git repository @@ -124,6 +126,8 @@ func addGctsCloneRepositoryFlags(cmd *cobra.Command, stepConfig *gctsCloneReposi cmd.Flags().StringVar(&stepConfig.Host, "host", os.Getenv("PIPER_host"), "Specifies the protocol and host address, including the port. Please provide in the format `://:`. Supported protocols are `http` and `https`.") cmd.Flags().StringVar(&stepConfig.Client, "client", os.Getenv("PIPER_client"), "Specifies the client of the ABAP system to be addressed") + cmd.Flags().BoolVar(&stepConfig.SkipSSLVerification, "skipSSLVerification", false, "You can skip the SSL (Secure Socket Layer) verification for the http client") + cmd.MarkFlagRequired("username") cmd.MarkFlagRequired("password") cmd.MarkFlagRequired("repository") @@ -202,6 +206,23 @@ func gctsCloneRepositoryMetadata() config.StepData { Aliases: []config.Alias{}, Default: os.Getenv("PIPER_client"), }, + { + Name: "queryParameters", + ResourceRef: []config.ResourceReference{}, + Scope: []string{"PARAMETERS", "STAGES", "STEPS"}, + Type: "map[string]interface{}", + Mandatory: false, + Aliases: []config.Alias{}, + }, + { + Name: "skipSSLVerification", + ResourceRef: []config.ResourceReference{}, + Scope: []string{"PARAMETERS", "STAGES", "STEPS"}, + Type: "bool", + Mandatory: false, + Aliases: []config.Alias{}, + Default: false, + }, }, }, }, diff --git a/cmd/gctsCreateRepository.go b/cmd/gctsCreateRepository.go index 8fea9e3ac6..23ce9bbc42 100644 --- a/cmd/gctsCreateRepository.go +++ b/cmd/gctsCreateRepository.go @@ -84,6 +84,13 @@ func createRepository(config *gctsCreateRepositoryOptions, telemetryData *teleme url := config.Host + "/sap/bc/cts_abapvcs/repository?sap-client=" + config.Client + url, urlErr := addQueryToURL(url, config.QueryParameters) + + if urlErr != nil { + + return urlErr + } + resp, httpErr := httpClient.SendRequest("POST", url, bytes.NewBuffer(jsonBody), header, nil) defer func() { diff --git a/cmd/gctsCreateRepository_generated.go b/cmd/gctsCreateRepository_generated.go index 8ebc67b887..9924d5f290 100644 --- a/cmd/gctsCreateRepository_generated.go +++ b/cmd/gctsCreateRepository_generated.go @@ -16,15 +16,17 @@ import ( ) type gctsCreateRepositoryOptions struct { - Username string `json:"username,omitempty"` - Password string `json:"password,omitempty"` - Repository string `json:"repository,omitempty"` - Host string `json:"host,omitempty"` - Client string `json:"client,omitempty"` - RemoteRepositoryURL string `json:"remoteRepositoryURL,omitempty"` - Role string `json:"role,omitempty" validate:"possible-values=SOURCE TARGET"` - VSID string `json:"vSID,omitempty"` - Type string `json:"type,omitempty" validate:"possible-values=GIT"` + Username string `json:"username,omitempty"` + Password string `json:"password,omitempty"` + Repository string `json:"repository,omitempty"` + Host string `json:"host,omitempty"` + Client string `json:"client,omitempty"` + RemoteRepositoryURL string `json:"remoteRepositoryURL,omitempty"` + Role string `json:"role,omitempty" validate:"possible-values=SOURCE TARGET"` + VSID string `json:"vSID,omitempty"` + Type string `json:"type,omitempty" validate:"possible-values=GIT"` + QueryParameters map[string]interface{} `json:"queryParameters,omitempty"` + SkipSSLVerification bool `json:"skipSSLVerification,omitempty"` } // GctsCreateRepositoryCommand Creates a Git repository on an ABAP system @@ -132,6 +134,8 @@ func addGctsCreateRepositoryFlags(cmd *cobra.Command, stepConfig *gctsCreateRepo cmd.Flags().StringVar(&stepConfig.VSID, "vSID", os.Getenv("PIPER_vSID"), "Virtual SID of the local repository. The vSID corresponds to the transport route that delivers content to the remote Git repository") cmd.Flags().StringVar(&stepConfig.Type, "type", `GIT`, "Type of the used source code management tool") + cmd.Flags().BoolVar(&stepConfig.SkipSSLVerification, "skipSSLVerification", false, "You can skip the SSL (Secure Socket Layer) verification for the http client") + cmd.MarkFlagRequired("username") cmd.MarkFlagRequired("password") cmd.MarkFlagRequired("repository") @@ -246,6 +250,23 @@ func gctsCreateRepositoryMetadata() config.StepData { Aliases: []config.Alias{}, Default: `GIT`, }, + { + Name: "queryParameters", + ResourceRef: []config.ResourceReference{}, + Scope: []string{"PARAMETERS", "STAGES", "STEPS"}, + Type: "map[string]interface{}", + Mandatory: false, + Aliases: []config.Alias{}, + }, + { + Name: "skipSSLVerification", + ResourceRef: []config.ResourceReference{}, + Scope: []string{"PARAMETERS", "STAGES", "STEPS"}, + Type: "bool", + Mandatory: false, + Aliases: []config.Alias{}, + Default: false, + }, }, }, }, diff --git a/cmd/gctsDeploy.go b/cmd/gctsDeploy.go index 2314d8dec6..81b9ce2349 100644 --- a/cmd/gctsDeploy.go +++ b/cmd/gctsDeploy.go @@ -49,10 +49,11 @@ func gctsDeployRepository(config *gctsDeployOptions, telemetryData *telemetry.Cu return errors.Wrap(cookieErr, "creating a cookie jar failed") } clientOptions := piperhttp.ClientOptions{ - CookieJar: cookieJar, - Username: config.Username, - Password: config.Password, - MaxRetries: maxRetries, + CookieJar: cookieJar, + Username: config.Username, + Password: config.Password, + MaxRetries: maxRetries, + TransportSkipVerification: config.SkipSSLVerification, } httpClient.SetOptions(clientOptions) log.Entry().Infof("Start of gCTS Deploy Step with Configuration Values: %v", config) @@ -73,6 +74,8 @@ func gctsDeployRepository(config *gctsDeployOptions, telemetryData *telemetry.Cu Role: config.Role, VSID: config.VSID, Type: config.Type, + QueryParameters: config.QueryParameters, + SkipSSLVerification: config.SkipSSLVerification, } log.Entry().Infof("gCTS Deploy : Checking if repository %v already exists", config.Repository) repoMetadataInitState, getRepositoryErr := getRepository(config, httpClient) @@ -97,11 +100,13 @@ func gctsDeployRepository(config *gctsDeployOptions, telemetryData *telemetry.Cu } cloneRepoOptions := gctsCloneRepositoryOptions{ - Username: config.Username, - Password: config.Password, - Repository: config.Repository, - Host: config.Host, - Client: config.Client, + Username: config.Username, + Password: config.Password, + Repository: config.Repository, + Host: config.Host, + Client: config.Client, + QueryParameters: config.QueryParameters, + SkipSSLVerification: config.SkipSSLVerification, } // No Import has to be set when there is a commit or branch parameter set // This is required so that during the clone of the repo it is not imported into the system @@ -236,11 +241,12 @@ func pullByCommitWithRollback(config *gctsDeployOptions, telemetryData *telemetr if config.Rollback { //Rollback to last commit. rollbackOptions := gctsRollbackOptions{ - Username: config.Username, - Password: config.Password, - Repository: config.Repository, - Host: config.Host, - Client: config.Client, + Username: config.Username, + Password: config.Password, + Repository: config.Repository, + Host: config.Host, + Client: config.Client, + SkipSSLVerification: config.SkipSSLVerification, } rollbackErr := rollback(&rollbackOptions, telemetryData, command, httpClient) if rollbackErr != nil { @@ -308,6 +314,14 @@ func switchBranch(config *gctsDeployOptions, httpClient piperhttp.Sender, curren requestURL := config.Host + "/sap/bc/cts_abapvcs/repository/" + config.Repository + "/branches/" + currentBranch + "/switch?branch=" + targetBranch + "&sap-client=" + config.Client + + requestURL, urlErr := addQueryToURL(requestURL, config.QueryParameters) + + if urlErr != nil { + + return nil, urlErr + } + resp, httpErr := httpClient.SendRequest("GET", requestURL, nil, nil, nil) defer func() { if resp != nil && resp.Body != nil { @@ -340,6 +354,14 @@ func deployCommitToAbapSystem(config *gctsDeployOptions, httpClient piperhttp.Se requestURL := config.Host + "/sap/bc/cts_abapvcs/repository/" + config.Repository + "/deploy?sap-client=" + config.Client + + requestURL, urlErr := addQueryToURL(requestURL, config.QueryParameters) + + if urlErr != nil { + + return urlErr + } + reqBody := deployRequestBody jsonBody, marshalErr := json.Marshal(reqBody) if marshalErr != nil { @@ -377,6 +399,13 @@ func getRepository(config *gctsDeployOptions, httpClient piperhttp.Sender) (*get "/sap/bc/cts_abapvcs/repository/" + config.Repository + "?sap-client=" + config.Client + requestURL, urlErr := addQueryToURL(requestURL, config.QueryParameters) + + if urlErr != nil { + + return nil, urlErr + } + resp, httpErr := httpClient.SendRequest("GET", requestURL, nil, nil, nil) defer func() { if resp != nil && resp.Body != nil { @@ -407,6 +436,14 @@ func deleteConfigKey(deployConfig *gctsDeployOptions, httpClient piperhttp.Sende requestURL := deployConfig.Host + "/sap/bc/cts_abapvcs/repository/" + deployConfig.Repository + "/config/" + configToDelete + "?sap-client=" + deployConfig.Client + + requestURL, urlErr := addQueryToURL(requestURL, deployConfig.QueryParameters) + + if urlErr != nil { + + return urlErr + } + header := make(http.Header) header.Set("Content-Type", "application/json") header.Add("Accept", "application/json") @@ -435,6 +472,13 @@ func setConfigKey(deployConfig *gctsDeployOptions, httpClient piperhttp.Sender, "/sap/bc/cts_abapvcs/repository/" + deployConfig.Repository + "/config?sap-client=" + deployConfig.Client + requestURL, urlErr := addQueryToURL(requestURL, deployConfig.QueryParameters) + + if urlErr != nil { + + return urlErr + } + reqBody := configToSet jsonBody, marshalErr := json.Marshal(reqBody) if marshalErr != nil { @@ -470,10 +514,11 @@ func pullByCommit(config *gctsDeployOptions, telemetryData *telemetry.CustomData return errors.Wrap(cookieErr, "creating a cookie jar failed") } clientOptions := piperhttp.ClientOptions{ - CookieJar: cookieJar, - Username: config.Username, - Password: config.Password, - MaxRetries: -1, + CookieJar: cookieJar, + Username: config.Username, + Password: config.Password, + MaxRetries: -1, + TransportSkipVerification: config.SkipSSLVerification, } httpClient.SetOptions(clientOptions) @@ -481,6 +526,13 @@ func pullByCommit(config *gctsDeployOptions, telemetryData *telemetry.CustomData "/sap/bc/cts_abapvcs/repository/" + config.Repository + "/pullByCommit?sap-client=" + config.Client + "&request=" + config.Commit + requestURL, urlErr := addQueryToURL(requestURL, config.QueryParameters) + + if urlErr != nil { + + return urlErr + } + if config.Commit != "" { log.Entry().Infof("preparing to deploy specified commit %v", config.Commit) params := url.Values{} @@ -531,10 +583,11 @@ func createRepositoryForDeploy(config *gctsCreateRepositoryOptions, telemetryDat return errors.Wrapf(cookieErr, "creating repository on the ABAP system %v failed", config.Host) } clientOptions := piperhttp.ClientOptions{ - CookieJar: cookieJar, - Username: config.Username, - Password: config.Password, - MaxRetries: -1, + CookieJar: cookieJar, + Username: config.Username, + Password: config.Password, + MaxRetries: -1, + TransportSkipVerification: config.SkipSSLVerification, } httpClient.SetOptions(clientOptions) @@ -577,6 +630,13 @@ func createRepositoryForDeploy(config *gctsCreateRepositoryOptions, telemetryDat url := config.Host + "/sap/bc/cts_abapvcs/repository?sap-client=" + config.Client + url, urlErr := addQueryToURL(url, config.QueryParameters) + + if urlErr != nil { + + return urlErr + } + resp, httpErr := httpClient.SendRequest("POST", url, bytes.NewBuffer(jsonBody), header, nil) defer func() { @@ -618,6 +678,13 @@ func getConfigurationMetadata(config *gctsDeployOptions, httpClient piperhttp.Se requestURL := config.Host + "/sap/bc/cts_abapvcs/config?sap-client=" + config.Client + requestURL, urlErr := addQueryToURL(requestURL, config.QueryParameters) + + if urlErr != nil { + + return nil, urlErr + } + resp, httpErr := httpClient.SendRequest("GET", requestURL, nil, nil, nil) defer func() { if resp != nil && resp.Body != nil { @@ -705,6 +772,39 @@ func parseErrorDumpFromResponseBody(responseBody *http.Response) (*errorLogBody, return &errorDump, nil } +func addQueryToURL(requestURL string, keyValue map[string]interface{}) (string, error) { + + var formattedURL string + formattedURL = requestURL + if keyValue != nil { + if strings.Contains(requestURL, "?") { + for key, value := range keyValue { + configValue := fmt.Sprint(value) + formattedURL = formattedURL + "&" + key + "=" + configValue + } + } else { + i := 0 + for key, value := range keyValue { + configValue := fmt.Sprint(value) + if i == 0 { + formattedURL = requestURL + "?" + key + "=" + configValue + } else { + formattedURL = formattedURL + "&" + key + "=" + configValue + } + i++ + } + } + } + if strings.Count(formattedURL, "") > 2001 { + + log.Entry().Error("Url endpoint is longer than 2000 characters!") + return formattedURL, errors.New("Url endpoint is longer than 2000 characters!") + + } + + return formattedURL, nil +} + type repositoryConfiguration struct { Key string `json:"key"` Value string `json:"value"` diff --git a/cmd/gctsDeploy_generated.go b/cmd/gctsDeploy_generated.go index 65c72c930a..e148a09a5d 100644 --- a/cmd/gctsDeploy_generated.go +++ b/cmd/gctsDeploy_generated.go @@ -30,6 +30,8 @@ type gctsDeployOptions struct { Scope string `json:"scope,omitempty"` Rollback bool `json:"rollback,omitempty"` Configuration map[string]interface{} `json:"configuration,omitempty"` + QueryParameters map[string]interface{} `json:"queryParameters,omitempty"` + SkipSSLVerification bool `json:"skipSSLVerification,omitempty"` } // GctsDeployCommand Deploys a Git Repository to a local Repository and then to an ABAP System @@ -145,6 +147,8 @@ func addGctsDeployFlags(cmd *cobra.Command, stepConfig *gctsDeployOptions) { cmd.Flags().StringVar(&stepConfig.Scope, "scope", os.Getenv("PIPER_scope"), "Scope of objects to be deployed. Possible values are CRNTCOMMIT (current commit - Default) and LASTACTION (last repository action). The default option deploys all objects that existed in the repository when the commit was created. LASTACTION only deploys the object difference of the last action in the repository.") cmd.Flags().BoolVar(&stepConfig.Rollback, "rollback", false, "Indication whether you want to roll back to the last working state of the repository, if any of the step actions *switch branch* or *pull commit* fail.") + cmd.Flags().BoolVar(&stepConfig.SkipSSLVerification, "skipSSLVerification", false, "You can skip the SSL (Secure Socket Layer) verification for the http client") + cmd.MarkFlagRequired("username") cmd.MarkFlagRequired("password") cmd.MarkFlagRequired("repository") @@ -304,6 +308,23 @@ func gctsDeployMetadata() config.StepData { Mandatory: false, Aliases: []config.Alias{{Name: "gctsRepositoryConfigurations"}}, }, + { + Name: "queryParameters", + ResourceRef: []config.ResourceReference{}, + Scope: []string{"PARAMETERS", "STAGES", "STEPS"}, + Type: "map[string]interface{}", + Mandatory: false, + Aliases: []config.Alias{}, + }, + { + Name: "skipSSLVerification", + ResourceRef: []config.ResourceReference{}, + Scope: []string{"PARAMETERS", "STAGES", "STEPS"}, + Type: "bool", + Mandatory: false, + Aliases: []config.Alias{}, + Default: false, + }, }, }, }, diff --git a/cmd/gctsExecuteABAPQualityChecks.go b/cmd/gctsExecuteABAPQualityChecks.go index f971eb8f02..cf51aa7060 100644 --- a/cmd/gctsExecuteABAPQualityChecks.go +++ b/cmd/gctsExecuteABAPQualityChecks.go @@ -31,6 +31,7 @@ func gctsExecuteABAPQualityChecks(config gctsExecuteABAPQualityChecksOptions, te c.Stderr(log.Writer()) httpClient := &piperhttp.Client{} + // error situations should stop execution through log.Entry().Fatal() call which leads to an os.Exit(1) in the end err := rungctsExecuteABAPQualityChecks(&config, httpClient) if err != nil { @@ -61,10 +62,11 @@ func rungctsExecuteABAPQualityChecks(config *gctsExecuteABAPQualityChecksOptions maxRetries := -1 clientOptions := piperhttp.ClientOptions{ - CookieJar: cookieJar, - Username: config.Username, - Password: config.Password, - MaxRetries: maxRetries, + CookieJar: cookieJar, + Username: config.Username, + Password: config.Password, + MaxRetries: maxRetries, + TransportSkipVerification: config.SkipSSLVerification, } httpClient.SetOptions(clientOptions) @@ -377,6 +379,13 @@ func getRepositoryObjects(config *gctsExecuteABAPQualityChecksOptions, client pi "/sap/bc/cts_abapvcs/repository/" + config.Repository + "/objects?sap-client=" + config.Client + url, urlErr := addQueryToURL(url, config.QueryParameters) + + if urlErr != nil { + + return nil, urlErr + } + resp, httpErr := client.SendRequest("GET", url, nil, nil, nil) defer func() { @@ -426,6 +435,13 @@ func getPackages(config *gctsExecuteABAPQualityChecksOptions, client piperhttp.S "/sap/bc/cts_abapvcs/repository/" + config.Repository + "/objects?sap-client=" + config.Client + url, urlErr := addQueryToURL(url, config.QueryParameters) + + if urlErr != nil { + + return nil, urlErr + } + resp, httpErr := client.SendRequest("GET", url, nil, nil, nil) defer func() { @@ -462,6 +478,13 @@ func discoverServer(config *gctsExecuteABAPQualityChecksOptions, client piperhtt url := config.Host + "/sap/bc/adt/core/discovery?sap-client=" + config.Client + url, urlErr := addQueryToURL(url, config.QueryParameters) + + if urlErr != nil { + + return nil, urlErr + } + header := make(http.Header) header.Add("Accept", "application/atomsvc+xml") header.Add("x-csrf-token", "fetch") @@ -553,6 +576,13 @@ func runAUnitTest(config *gctsExecuteABAPQualityChecksOptions, client piperhttp. url := config.Host + "/sap/bc/adt/abapunit/testruns?sap-client=" + config.Client + url, urlErr := addQueryToURL(url, config.QueryParameters) + + if urlErr != nil { + + return nil, urlErr + } + discHeader, discError := discoverServer(config, client) if discError != nil { @@ -731,7 +761,7 @@ func executeATCCheck(config *gctsExecuteABAPQualityChecksOptions, client piperht case "INTF": innerXml = innerXml + `` case "DEVC": - innerXml = innerXml + `` + innerXml = innerXml + `` case "FUGR": innerXml = innerXml + `` case "TABL": @@ -817,6 +847,13 @@ func startATCRun(config *gctsExecuteABAPQualityChecksOptions, client piperhttp.S url := config.Host + "/sap/bc/adt/atc/runs?worklistId=" + worklistID + "&sap-client=" + config.Client + url, urlErr := addQueryToURL(url, config.QueryParameters) + + if urlErr != nil { + + return urlErr + } + resp, httpErr := client.SendRequest("POST", url, bytes.NewBuffer(xml), header, nil) defer func() { @@ -846,6 +883,13 @@ func getATCRun(config *gctsExecuteABAPQualityChecksOptions, client piperhttp.Sen url := config.Host + "/sap/bc/adt/atc/worklists/" + worklistID + "?sap-client=" + config.Client + url, urlErr := addQueryToURL(url, config.QueryParameters) + + if urlErr != nil { + + return nil, urlErr + } + header.Add("Accept", "application/atc.worklist.v1+xml") resp, httpErr := client.SendRequest("GET", url, nil, header, nil) @@ -866,6 +910,13 @@ func getWorklist(config *gctsExecuteABAPQualityChecksOptions, client piperhttp.S "/sap/bc/adt/atc/worklists?checkVariant=" + config.AtcVariant + "&sap-client=" + config.Client discHeader, discError := discoverServer(config, client) + url, urlErr := addQueryToURL(url, config.QueryParameters) + + if urlErr != nil { + + return worklistID, urlErr + } + if discError != nil { return worklistID, errors.Wrap(discError, "get worklist failed") } @@ -1417,6 +1468,14 @@ func getRepo(config *gctsExecuteABAPQualityChecksOptions, client piperhttp.Sende url := config.Host + "/sap/bc/cts_abapvcs/repository/" + config.Repository + "?sap-client=" + config.Client + + url, urlErr := addQueryToURL(url, config.QueryParameters) + + if urlErr != nil { + + return repositoryResp, urlErr + } + resp, httpErr := client.SendRequest("GET", url, nil, nil, nil) defer func() { if resp != nil && resp.Body != nil { @@ -1446,6 +1505,13 @@ func getRepositoryLayout(config *gctsExecuteABAPQualityChecksOptions, client pip "/sap/bc/cts_abapvcs/repository/" + config.Repository + "/layout?sap-client=" + config.Client + url, urlErr := addQueryToURL(url, config.QueryParameters) + + if urlErr != nil { + + return repoLayoutResponse, urlErr + } + resp, httpErr := client.SendRequest("GET", url, nil, nil, nil) defer func() { @@ -1475,6 +1541,12 @@ func getCommitList(config *gctsExecuteABAPQualityChecksOptions, client piperhttp "/sap/bc/cts_abapvcs/repository/" + config.Repository + "/getCommit?sap-client=" + config.Client + url, urlErr := addQueryToURL(url, config.QueryParameters) + if urlErr != nil { + + return commitResp, urlErr + } + resp, httpErr := client.SendRequest("GET", url, nil, nil, nil) defer func() { @@ -1504,6 +1576,13 @@ func getObjectDifference(config *gctsExecuteABAPQualityChecksOptions, fromCommit "/sap/bc/cts_abapvcs/repository/" + config.Repository + "/compareCommits?fromCommit=" + fromCommit + "&toCommit=" + toCommit + "&sap-client=" + config.Client + url, urlErr := addQueryToURL(url, config.QueryParameters) + + if urlErr != nil { + + return objectResponse, urlErr + } + resp, httpErr := client.SendRequest("GET", url, nil, nil, nil) defer func() { @@ -1533,6 +1612,13 @@ func getObjectInfo(config *gctsExecuteABAPQualityChecksOptions, client piperhttp "/sap/bc/cts_abapvcs/objects/" + objectType + "/" + objectName + "?sap-client=" + config.Client + url, urlErr := addQueryToURL(url, config.QueryParameters) + + if urlErr != nil { + + return objectMetInfoResponse, urlErr + } + resp, httpErr := client.SendRequest("GET", url, nil, nil, nil) defer func() { @@ -1561,6 +1647,13 @@ func getHistory(config *gctsExecuteABAPQualityChecksOptions, client piperhttp.Se url := config.Host + "/sap/bc/cts_abapvcs/repository/" + config.Repository + "/getHistory?sap-client=" + config.Client + url, urlErr := addQueryToURL(url, config.QueryParameters) + + if urlErr != nil { + + return historyResp, urlErr + } + resp, httpErr := client.SendRequest("GET", url, nil, nil, nil) defer func() { diff --git a/cmd/gctsExecuteABAPQualityChecks_generated.go b/cmd/gctsExecuteABAPQualityChecks_generated.go index a042fd2b02..42c8bbf0da 100644 --- a/cmd/gctsExecuteABAPQualityChecks_generated.go +++ b/cmd/gctsExecuteABAPQualityChecks_generated.go @@ -16,19 +16,21 @@ import ( ) type gctsExecuteABAPQualityChecksOptions struct { - Username string `json:"username,omitempty"` - Password string `json:"password,omitempty"` - Host string `json:"host,omitempty"` - Repository string `json:"repository,omitempty"` - Client string `json:"client,omitempty"` - AUnitTest bool `json:"aUnitTest,omitempty"` - AtcCheck bool `json:"atcCheck,omitempty"` - AtcVariant string `json:"atcVariant,omitempty"` - Scope string `json:"scope,omitempty"` - Commit string `json:"commit,omitempty"` - Workspace string `json:"workspace,omitempty"` - AtcResultsFileName string `json:"atcResultsFileName,omitempty"` - AUnitResultsFileName string `json:"aUnitResultsFileName,omitempty"` + Username string `json:"username,omitempty"` + Password string `json:"password,omitempty"` + Host string `json:"host,omitempty"` + Repository string `json:"repository,omitempty"` + Client string `json:"client,omitempty"` + AUnitTest bool `json:"aUnitTest,omitempty"` + AtcCheck bool `json:"atcCheck,omitempty"` + AtcVariant string `json:"atcVariant,omitempty"` + Scope string `json:"scope,omitempty"` + Commit string `json:"commit,omitempty"` + Workspace string `json:"workspace,omitempty"` + AtcResultsFileName string `json:"atcResultsFileName,omitempty"` + AUnitResultsFileName string `json:"aUnitResultsFileName,omitempty"` + QueryParameters map[string]interface{} `json:"queryParameters,omitempty"` + SkipSSLVerification bool `json:"skipSSLVerification,omitempty"` } // GctsExecuteABAPQualityChecksCommand Runs ABAP unit tests and ATC (ABAP Test Cockpit) checks for a specified object scope. @@ -147,6 +149,8 @@ func addGctsExecuteABAPQualityChecksFlags(cmd *cobra.Command, stepConfig *gctsEx cmd.Flags().StringVar(&stepConfig.AtcResultsFileName, "atcResultsFileName", `ATCResults.xml`, "Specifies an output file name for the results of the ATC checks.") cmd.Flags().StringVar(&stepConfig.AUnitResultsFileName, "aUnitResultsFileName", `AUnitResults.xml`, "Specifies an output file name for the results of the ABAP Unit tests.") + cmd.Flags().BoolVar(&stepConfig.SkipSSLVerification, "skipSSLVerification", false, "You can skip the SSL (Secure Socket Layer) verification for the http client") + cmd.MarkFlagRequired("username") cmd.MarkFlagRequired("password") cmd.MarkFlagRequired("host") @@ -298,6 +302,23 @@ func gctsExecuteABAPQualityChecksMetadata() config.StepData { Aliases: []config.Alias{}, Default: `AUnitResults.xml`, }, + { + Name: "queryParameters", + ResourceRef: []config.ResourceReference{}, + Scope: []string{"PARAMETERS", "STAGES", "STEPS"}, + Type: "map[string]interface{}", + Mandatory: false, + Aliases: []config.Alias{}, + }, + { + Name: "skipSSLVerification", + ResourceRef: []config.ResourceReference{}, + Scope: []string{"PARAMETERS", "STAGES", "STEPS"}, + Type: "bool", + Mandatory: false, + Aliases: []config.Alias{}, + Default: false, + }, }, }, }, diff --git a/cmd/gctsExecuteABAPUnitTests_generated.go b/cmd/gctsExecuteABAPUnitTests_generated.go index dae86e8b07..988b9a824c 100644 --- a/cmd/gctsExecuteABAPUnitTests_generated.go +++ b/cmd/gctsExecuteABAPUnitTests_generated.go @@ -16,19 +16,21 @@ import ( ) type gctsExecuteABAPUnitTestsOptions struct { - Username string `json:"username,omitempty"` - Password string `json:"password,omitempty"` - Host string `json:"host,omitempty"` - Repository string `json:"repository,omitempty"` - Client string `json:"client,omitempty"` - AUnitTest bool `json:"aUnitTest,omitempty"` - AtcCheck bool `json:"atcCheck,omitempty"` - AtcVariant string `json:"atcVariant,omitempty"` - Scope string `json:"scope,omitempty"` - Commit string `json:"commit,omitempty"` - Workspace string `json:"workspace,omitempty"` - AtcResultsFileName string `json:"atcResultsFileName,omitempty"` - AUnitResultsFileName string `json:"aUnitResultsFileName,omitempty"` + Username string `json:"username,omitempty"` + Password string `json:"password,omitempty"` + Host string `json:"host,omitempty"` + Repository string `json:"repository,omitempty"` + Client string `json:"client,omitempty"` + AUnitTest bool `json:"aUnitTest,omitempty"` + AtcCheck bool `json:"atcCheck,omitempty"` + AtcVariant string `json:"atcVariant,omitempty"` + Scope string `json:"scope,omitempty"` + Commit string `json:"commit,omitempty"` + Workspace string `json:"workspace,omitempty"` + AtcResultsFileName string `json:"atcResultsFileName,omitempty"` + AUnitResultsFileName string `json:"aUnitResultsFileName,omitempty"` + QueryParameters map[string]interface{} `json:"queryParameters,omitempty"` + SkipSSLVerification bool `json:"skipSSLVerification,omitempty"` } // GctsExecuteABAPUnitTestsCommand Runs ABAP unit tests and ATC (ABAP Test Cockpit) checks for a specified object scope. @@ -140,6 +142,8 @@ func addGctsExecuteABAPUnitTestsFlags(cmd *cobra.Command, stepConfig *gctsExecut cmd.Flags().StringVar(&stepConfig.AtcResultsFileName, "atcResultsFileName", `ATCResults.xml`, "Specifies an output file name for the results of the ATC checks.") cmd.Flags().StringVar(&stepConfig.AUnitResultsFileName, "aUnitResultsFileName", `AUnitResults.xml`, "Specifies an output file name for the results of the ABAP Unit tests.") + cmd.Flags().BoolVar(&stepConfig.SkipSSLVerification, "skipSSLVerification", false, "You can skip the SSL (Secure Socket Layer) verification for the http client") + cmd.MarkFlagRequired("username") cmd.MarkFlagRequired("password") cmd.MarkFlagRequired("host") @@ -291,6 +295,23 @@ func gctsExecuteABAPUnitTestsMetadata() config.StepData { Aliases: []config.Alias{}, Default: `AUnitResults.xml`, }, + { + Name: "queryParameters", + ResourceRef: []config.ResourceReference{}, + Scope: []string{"PARAMETERS", "STAGES", "STEPS"}, + Type: "map[string]interface{}", + Mandatory: false, + Aliases: []config.Alias{}, + }, + { + Name: "skipSSLVerification", + ResourceRef: []config.ResourceReference{}, + Scope: []string{"PARAMETERS", "STAGES", "STEPS"}, + Type: "bool", + Mandatory: false, + Aliases: []config.Alias{}, + Default: false, + }, }, }, }, diff --git a/cmd/gctsRollback.go b/cmd/gctsRollback.go index 18eed05b64..6e6bb47b1d 100644 --- a/cmd/gctsRollback.go +++ b/cmd/gctsRollback.go @@ -34,14 +34,19 @@ func gctsRollback(config gctsRollbackOptions, telemetryData *telemetry.CustomDat func rollback(config *gctsRollbackOptions, telemetryData *telemetry.CustomData, command command.ExecRunner, httpClient piperhttp.Sender) error { + maxRetries := -1 + cookieJar, cookieErr := cookiejar.New(nil) if cookieErr != nil { return cookieErr } + clientOptions := piperhttp.ClientOptions{ - CookieJar: cookieJar, - Username: config.Username, - Password: config.Password, + CookieJar: cookieJar, + Username: config.Username, + Password: config.Password, + MaxRetries: maxRetries, + TransportSkipVerification: config.SkipSSLVerification, } httpClient.SetOptions(clientOptions) @@ -64,12 +69,13 @@ func rollback(config *gctsRollbackOptions, telemetryData *telemetry.CustomData, log.Entry().Infof("rolling back to specified commit %v", config.Commit) deployOptions = gctsDeployOptions{ - Username: config.Username, - Password: config.Password, - Host: config.Host, - Repository: config.Repository, - Client: config.Client, - Commit: config.Commit, + Username: config.Username, + Password: config.Password, + Host: config.Host, + Repository: config.Repository, + Client: config.Client, + Commit: config.Commit, + SkipSSLVerification: config.SkipSSLVerification, } } else { @@ -81,12 +87,13 @@ func rollback(config *gctsRollbackOptions, telemetryData *telemetry.CustomData, log.Entry().WithField("repository", config.Repository).Infof("rolling back to last active commit %v", repoHistory.Result[0].FromCommit) deployOptions = gctsDeployOptions{ - Username: config.Username, - Password: config.Password, - Host: config.Host, - Repository: config.Repository, - Client: config.Client, - Commit: repoHistory.Result[0].FromCommit, + Username: config.Username, + Password: config.Password, + Host: config.Host, + Repository: config.Repository, + Client: config.Client, + Commit: repoHistory.Result[0].FromCommit, + SkipSSLVerification: config.SkipSSLVerification, } } else { @@ -128,6 +135,13 @@ func getLastSuccessfullCommit(config *gctsRollbackOptions, telemetryData *teleme url := githubURL.Scheme + "://api." + githubURL.Host + "/repos" + githubURL.Path + "/commits/" + commit + "/status" + url, urlErr := addQueryToURL(url, config.QueryParameters) + + if urlErr != nil { + + return "", urlErr + } + resp, httpErr := httpClient.SendRequest("GET", url, nil, nil, nil) defer func() { @@ -171,6 +185,13 @@ func getCommits(config *gctsRollbackOptions, telemetryData *telemetry.CustomData "/sap/bc/cts_abapvcs/repository/" + config.Repository + "/getCommit?sap-client=" + config.Client + url, urlErr := addQueryToURL(url, config.QueryParameters) + + if urlErr != nil { + + return nil, urlErr + } + type commitsResponseBody struct { Commits []struct { ID string `json:"id"` @@ -218,6 +239,13 @@ func getRepoInfo(config *gctsRollbackOptions, telemetryData *telemetry.CustomDat "/sap/bc/cts_abapvcs/repository/" + config.Repository + "?sap-client=" + config.Client + url, urlErr := addQueryToURL(url, config.QueryParameters) + + if urlErr != nil { + + return nil, urlErr + } + resp, httpErr := httpClient.SendRequest("GET", url, nil, nil, nil) defer func() { @@ -269,6 +297,13 @@ func getRepoHistory(config *gctsRollbackOptions, telemetryData *telemetry.Custom "/sap/bc/cts_abapvcs/repository/" + config.Repository + "/getHistory?sap-client=" + config.Client + url, urlErr := addQueryToURL(url, config.QueryParameters) + + if urlErr != nil { + + return nil, urlErr + } + resp, httpErr := httpClient.SendRequest("GET", url, nil, nil, nil) defer func() { diff --git a/cmd/gctsRollback_generated.go b/cmd/gctsRollback_generated.go index a5025224bc..e2dd8cee76 100644 --- a/cmd/gctsRollback_generated.go +++ b/cmd/gctsRollback_generated.go @@ -16,13 +16,15 @@ import ( ) type gctsRollbackOptions struct { - Username string `json:"username,omitempty"` - Password string `json:"password,omitempty"` - Repository string `json:"repository,omitempty"` - Host string `json:"host,omitempty"` - Client string `json:"client,omitempty"` - Commit string `json:"commit,omitempty"` - GithubPersonalAccessToken string `json:"githubPersonalAccessToken,omitempty"` + Username string `json:"username,omitempty"` + Password string `json:"password,omitempty"` + Repository string `json:"repository,omitempty"` + Host string `json:"host,omitempty"` + Client string `json:"client,omitempty"` + Commit string `json:"commit,omitempty"` + GithubPersonalAccessToken string `json:"githubPersonalAccessToken,omitempty"` + QueryParameters map[string]interface{} `json:"queryParameters,omitempty"` + SkipSSLVerification bool `json:"skipSSLVerification,omitempty"` } // GctsRollbackCommand Perfoms a rollback of one (default) or several commits @@ -131,6 +133,8 @@ func addGctsRollbackFlags(cmd *cobra.Command, stepConfig *gctsRollbackOptions) { cmd.Flags().StringVar(&stepConfig.Commit, "commit", os.Getenv("PIPER_commit"), "Specifies the target commit for the rollback") cmd.Flags().StringVar(&stepConfig.GithubPersonalAccessToken, "githubPersonalAccessToken", os.Getenv("PIPER_githubPersonalAccessToken"), "GitHub personal access token with at least read permissions for the remote repository") + cmd.Flags().BoolVar(&stepConfig.SkipSSLVerification, "skipSSLVerification", false, "You can skip the SSL (Secure Socket Layer) verification for the http client") + cmd.MarkFlagRequired("username") cmd.MarkFlagRequired("password") cmd.MarkFlagRequired("repository") @@ -233,6 +237,23 @@ func gctsRollbackMetadata() config.StepData { Aliases: []config.Alias{}, Default: os.Getenv("PIPER_githubPersonalAccessToken"), }, + { + Name: "queryParameters", + ResourceRef: []config.ResourceReference{}, + Scope: []string{"PARAMETERS", "STAGES", "STEPS"}, + Type: "map[string]interface{}", + Mandatory: false, + Aliases: []config.Alias{}, + }, + { + Name: "skipSSLVerification", + ResourceRef: []config.ResourceReference{}, + Scope: []string{"PARAMETERS", "STAGES", "STEPS"}, + Type: "bool", + Mandatory: false, + Aliases: []config.Alias{}, + Default: false, + }, }, }, }, diff --git a/resources/metadata/gctsCloneRepository.yaml b/resources/metadata/gctsCloneRepository.yaml index ef9f0d8a67..3bf6259e2a 100644 --- a/resources/metadata/gctsCloneRepository.yaml +++ b/resources/metadata/gctsCloneRepository.yaml @@ -61,3 +61,20 @@ spec: - STAGES - STEPS mandatory: true + - name: queryParameters + type: "map[string]interface{}" + description: Specifies pairs of key and value query parameters for the api requests + scope: + - PARAMETERS + - STAGES + - STEPS + mandatory: false + - name: skipSSLVerification + type: bool + description: You can skip the SSL (Secure Socket Layer) verification for the http client + scope: + - PARAMETERS + - STAGES + - STEPS + mandatory: false + default: false diff --git a/resources/metadata/gctsCreateRepository.yaml b/resources/metadata/gctsCreateRepository.yaml index a455bfe74d..f6a1ef0f6f 100644 --- a/resources/metadata/gctsCreateRepository.yaml +++ b/resources/metadata/gctsCreateRepository.yaml @@ -96,3 +96,20 @@ spec: default: GIT possibleValues: - GIT + - name: queryParameters + type: "map[string]interface{}" + description: Specifies pairs of key and value query parameters for the api requests + scope: + - PARAMETERS + - STAGES + - STEPS + mandatory: false + - name: skipSSLVerification + type: bool + description: You can skip the SSL (Secure Socket Layer) verification for the http client + scope: + - PARAMETERS + - STAGES + - STEPS + mandatory: false + default: false diff --git a/resources/metadata/gctsDeploy.yaml b/resources/metadata/gctsDeploy.yaml index 78b63db152..6434cce01c 100644 --- a/resources/metadata/gctsDeploy.yaml +++ b/resources/metadata/gctsDeploy.yaml @@ -142,3 +142,20 @@ spec: mandatory: false aliases: - name: gctsRepositoryConfigurations + - name: queryParameters + type: "map[string]interface{}" + description: Specifies pairs of key and value query parameters for the api requests + scope: + - PARAMETERS + - STAGES + - STEPS + mandatory: false + - name: skipSSLVerification + type: bool + description: You can skip the SSL (Secure Socket Layer) verification for the http client + scope: + - PARAMETERS + - STAGES + - STEPS + mandatory: false + default: false diff --git a/resources/metadata/gctsExecuteABAPQualityChecks.yaml b/resources/metadata/gctsExecuteABAPQualityChecks.yaml index 41c2ee98d4..e4795156b3 100644 --- a/resources/metadata/gctsExecuteABAPQualityChecks.yaml +++ b/resources/metadata/gctsExecuteABAPQualityChecks.yaml @@ -166,3 +166,20 @@ spec: - STEPS mandatory: false default: "AUnitResults.xml" + - name: queryParameters + type: "map[string]interface{}" + description: Specifies pairs of key and value query parameters for the api requests + scope: + - PARAMETERS + - STAGES + - STEPS + mandatory: false + - name: skipSSLVerification + type: bool + description: You can skip the SSL (Secure Socket Layer) verification for the http client + scope: + - PARAMETERS + - STAGES + - STEPS + mandatory: false + default: false diff --git a/resources/metadata/gctsExecuteABAPUnitTests.yaml b/resources/metadata/gctsExecuteABAPUnitTests.yaml index b22f986536..66a9e74019 100644 --- a/resources/metadata/gctsExecuteABAPUnitTests.yaml +++ b/resources/metadata/gctsExecuteABAPUnitTests.yaml @@ -159,3 +159,20 @@ spec: - STEPS mandatory: false default: "AUnitResults.xml" + - name: queryParameters + type: "map[string]interface{}" + description: Specifies pairs of key and value query parameters for the api requests + scope: + - PARAMETERS + - STAGES + - STEPS + mandatory: false + - name: skipSSLVerification + type: bool + description: You can skip the SSL (Secure Socket Layer) verification for the http client + scope: + - PARAMETERS + - STAGES + - STEPS + mandatory: false + default: false diff --git a/resources/metadata/gctsRollback.yaml b/resources/metadata/gctsRollback.yaml index 7f9f78365d..0acb7c33a5 100644 --- a/resources/metadata/gctsRollback.yaml +++ b/resources/metadata/gctsRollback.yaml @@ -84,3 +84,20 @@ spec: resourceRef: - name: githubPersonalAccessTokenId type: secret + - name: queryParameters + type: "map[string]interface{}" + description: Specifies pairs of key and value query parameters for the api requests + scope: + - PARAMETERS + - STAGES + - STEPS + mandatory: false + - name: skipSSLVerification + type: bool + description: You can skip the SSL (Secure Socket Layer) verification for the http client + scope: + - PARAMETERS + - STAGES + - STEPS + mandatory: false + default: false