You've already forked sap-jenkins-library
							
							
				mirror of
				https://github.com/SAP/jenkins-library.git
				synced 2025-10-30 23:57:50 +02:00 
			
		
		
		
	Add step abapEnvironmentPushATCSystemConfig (#3426)
* Checkin Go File - Push ATC Config * ATC Push Config - Testfile * Initial generated go files for ATC System Configuration * ApiProxyUpload Command (#3295) * ApiProxyUpload Command * Code Review Fixes * CodeReview Changes * CodeReview Fixes * YAML fixes * CodeReview Fix * Code Review Fixes * CodeReview Fixes * Code Climate Fixes * Code Review Fixes * Code Review Fixes Co-authored-by: Roland Stengel <r.stengel@sap.com> Co-authored-by: Oliver Feldmann <oliver.feldmann@sap.com> * Fetch Xcrsf-Token * Update abapEnvironmentPushATCSystemConfig.yaml * docs: fix urls (#3400) * fix stash and adapt unit tests accordingly (#3403) * Push ATC System Configuration - File read, send request, parse response * fetchATCXcsrfToken * fix(whitesourceExecuteScan): added missing credential declaration for the docker config (#3404) * insert command in piper.go * feat(cnbBuild): remove docker config after parsing (#3417) Co-authored-by: Philipp Stehle <philipp.stehle@sap.com> * more funcs * more funcs * Revert "feat: Add debug output to getConfig (#3341)" (#3396) This reverts commitb760bf48e7. Co-authored-by: Oliver Nocon <33484802+OliverNocon@users.noreply.github.com> * feat (kubernetesDeploy) allow secret creation in cluster with kubectl as deploy tool (#3398) * defaulting deocker config json location * function change * harmonising secret creation via json config apply * adding the env path to kaniko * env var * adding path * adding path * adding path * rolling back changes for path * adapting condition for secret creation * conditions based on username and password only * fix unit test as per new secret creation * update documentation with regards to secret creation * fixing yaml lint empty line * fixing trailing line from kaniko yaml * error condition when path of the docker config json file is not found Co-authored-by: anilkeshav27 <you@example.com> * readPipelineEnv -> Serialize Directly to os.Stdout (#3180) * Serialize CPE Directly to os.Stdout * Response Error Handling 1 * Add easy mode for AUnit & ATC (#3389) * remove mandatory flag from config files * Enable repo.yml as config * Adapt to merge * Refactoring * Refactoring * avoid panic * Add comments * Add easy mode for atc * Add tests * Add test * Refactor * Add test for MPS * Updates * Rename functions * Add files to gitignore * Rename * Renaming * Renaming * Renaming * Improve error messages * Update documentation * Add logging * Rename * Extend gitignore * fix(sonar): fix file patterns for gcs upload (#3406) Co-authored-by: Christopher Fenner <26137398+CCFenner@users.noreply.github.com> * testing piper forks (#3420) * developer doku update on how to test with forked repos Co-authored-by: rosemarieB <45030247+rosemarieB@users.noreply.github.com> * Error Messages parsing * Update yaml parameter * feat (npmExecuteScripts) create seperate npmrc file for publish to private repo (#3422) * creating new npm rc file * publishing to registry staging * exposing base64 version of env variables * changing encoding param * fixing unit test for the new path * debugging env var * remove debug message * update docu * changing new npmrc file name * adding new npmrc to ignore * adding new npmrc to ignore Co-authored-by: anilkeshav27 <you@example.com> * minor * small changes * small changes * UNIT Test * Unit Test 2 * Update .gitignore Co-authored-by: Daniel Mieg <56156797+DanielMieg@users.noreply.github.com> * Update abapEnvironmentAddons.md: Unable to update target vectors with unchanged SWC version (#3392) * Update abapEnvironmentAddons.md * Update documentation/docs/scenarios/abapEnvironmentAddons.md Co-authored-by: Daniel Mieg <56156797+DanielMieg@users.noreply.github.com> * Update abapEnvironmentAddons.md Co-authored-by: Daniel Mieg <56156797+DanielMieg@users.noreply.github.com> * Returning earlier & parseOdataResp 1 * new Parameter for overwrite existing * feat(cnbBuild): preserve maven test results in the workspace (#3429) Co-authored-by: Pavel Busko <pavel.busko@sap.com> Co-authored-by: Ralf Pannemans <ralf.pannemans@sap.com> * Update Introduction (#3433) * Check Existence of configuration * Quote strings in addon.yml (#3435) * including vaultSecretFile to parameter generator docu (#3436) Co-authored-by: anilkeshav27 <you@example.com> * fix: wrong command line format for multiple extension files (#3434) * feat(cnbBuild) containerImageName will be defaulted if possible (#3437) Co-authored-by: Ralf Pannemans <ralf.pannemans@sap.com> Co-authored-by: Johannes Dillmann <j.dillmann@sap.com> Co-authored-by: Sumit Kulhadia <sumit.kulhadia@sap.com> * Corr. check existence * check existence 2 * existence handling 2 * refinement existence handling & param rename * config yaml change - no mandatory for bool param * PATCH for existing Configuration * fix: correct typo in log message (#3439) Closes #3438 * feat(protecode): add versioning model (#3373) * changes to detectExec before master merge * changes for detectExecuteScan * self generated code added * fix syntax errors and update docu * added unit tests for fail and Group * fix failOn bug * add Groups as string array * add Groups as string array * tests and validation for groups, failOn * Updated docs and added more tests * documentation md files should not be changed * Handle merge conflicts from PR 1845 * fix merge errors * remove duplicate groups, merge error * adding buildCode and buildTool as params * switching build options * building maven modules * parameter correction * parameter correction * gnerate with new build parameter * adding comments * removing piper lib master and modifying goUtils to download 1.5.7 release * first cleaning then installing * multi module maven built * multi module maven built removing unwanted code * multi module maven built moving inside switch * testing * modifying the default use case to also call maven build * modifying the default use case to also call maven build wih -- * corrected maven build command * corrected maven build command with %v * skipping test runs * testing for MTA project with single pom * adding absolute path to m2 path * clean up * adding switch for mta and maven and removing env from containers * commiting changes for new detect step * correting log message * code clean up * unit tests changes to detectExecute * basic tests for new change * restoring piperGoUtils to download correct piper binary * code clean up * code clean up * protecodeExecuteScan :: versioning model draft - 1 * protecodeExecuteScan :: version model draft-2 * protecodeExecuteScan :: changing filename and version concatenation * protecodeExecuteScan :: update documentation * protecodeExecuteScan :: double URL encoding has been corrected & console messaging improved * protecodeExecuteScan :: fixed Go/generate validation fail * protecodeExecuteScan :: fixing failed unit tests * protecodeExecuteScan :: Version field added * protecodeExecuteScan :: Version field add => minor changes * protecodeExecuteScan :: Version field add => fixing tests Co-authored-by: D072410 <giridhar.shenoy@sap.com> Co-authored-by: Keshav <anil.keshav@sap.com> Co-authored-by: Oliver Nocon <33484802+OliverNocon@users.noreply.github.com> Co-authored-by: Christopher Fenner <26137398+CCFenner@users.noreply.github.com> Co-authored-by: Sven Merk <33895725+nevskrem@users.noreply.github.com> * GCS Upload fixes (#3387) * Fixed argument type in persist function * Fixed gcp upload to be usable in internal piper * Fixed import of packages * Updated logs Co-authored-by: Christopher Fenner <26137398+CCFenner@users.noreply.github.com> Co-authored-by: Oliver Nocon <33484802+OliverNocon@users.noreply.github.com> * Unit Test 2 * Unit Tests * Add gcs upload to mavenExecuteIntegration step (#3432) * Add gcs upload to mavenExecuteIntegration step * go generate Co-authored-by: Oliver Nocon <33484802+OliverNocon@users.noreply.github.com> * Check times refine * Permwrite 0644 * disable http retry (#3447) * Update maxWaitTime timeout for WhiteSource (#3284) * Update scanPolling.go Changing maxWaitTime from 15 to 30 to overcome WhiteSource results reflection in the backend issue. * Update configHelper.go * Reset configHelper changes to fix PR 3284 Committer: raghunathd8 Co-authored-by: Oliver Nocon <33484802+OliverNocon@users.noreply.github.com> Co-authored-by: raghunathd8 <root@docker-evaluation.openstack.eu-nl-1.cloud.sap> Co-authored-by: Sven Merk <33895725+nevskrem@users.noreply.github.com> * removed trailing spaces * yaml Update * minor mock for token & Unit Tests * rename Parameter Patch * lil refactor & Unit Test * fixes PATCH & more Unit Tests * add log at certain points * not writing configuration file back * feat(malwareExecuteScan): refactoring and docker support (#3421) * feat(malwareExecuteScan): add support for scanning docker images * refactoring * print out finding if available * generate toolrecord for malware scan * persist scan report * docs * fix * fix * rollback cmd/init_unix.go * auhenticated pull * fix * fix: report shall be consistent with the api model * gcs upload * fix linter * Fix potential nil reference (#3460) * Add gcs upload to karmaExecuteTests step (#3431) * Add gcs upload to karmaExecuteTests step * go generate Co-authored-by: Oliver Nocon <33484802+OliverNocon@users.noreply.github.com> * Add gcs upload to gaugeExecuteTests step (#3410) * Add gcs upload to gaugeExecuteTests step * go generate Co-authored-by: Oliver Nocon <33484802+OliverNocon@users.noreply.github.com> * Add gcs upload to newmanExecute step (#3408) * Add gcs upload to newmanExecute step * go generate Co-authored-by: Oliver Nocon <33484802+OliverNocon@users.noreply.github.com> * feat(GitHub): fetch commit statistics (#3381) * fetch GH statistics * move GH and Sonar integration tests to own files * fix imports * add integration test case * add result type * Apply suggestions from code review * feat: add command to fetch default files (#3445) * some ideas.. * Add getDefaults command (WIP) (#3444) * add getYAML function for configs * create getDefaults command(based on getConfig) * add getDefaults command to CLI * read defaults files, using github tokens as well * write defaults to stdout as JSON object with YAMLs embedded * catch case where no input files are given * actually write output to file if outputFile is specified * mark defaultsFile flag as required * add basic tests * add output (string) test * adapt generateDefaults() to return output (used for test of previous commit) * Changes to getDefaults() JSON output (#3449) * change JSON output to contain separate fields * filename -> filepath * Apply suggestions from code review * Apply suggestions from code review * Update pkg/config/config_test.go Co-authored-by: Jordi van Liempt <35920075+jliempt@users.noreply.github.com> * BATCH request preparation * Add gcs upload to mtaBuild step (#3405) * Add gcs upload to mtaBuild * Patterns was updated * go generate * removed patterns related to sapGenerateEnvironmentInfo step Co-authored-by: Oliver Nocon <33484802+OliverNocon@users.noreply.github.com> * Add gcs upload to mavenBuild step (#3394) * Add gcs upload to mavenBuild step * Patterns were updated * go generate * removed patterns related to sapGenerateEnvironmentInfo step Co-authored-by: Oliver Nocon <33484802+OliverNocon@users.noreply.github.com> * feat(gradleExecuteBuild): add stage scope to path parameter, fix project dir exist issue (#3401) * add stage scope to path parameter, fix project dir exist issue * fix unit test for gradleExecuteBuild Co-authored-by: Oliver Nocon <33484802+OliverNocon@users.noreply.github.com> * Add gcs upload to uiVeri5ExecuteTests step (#3409) * Add gcs upload to uiVeri5ExecuteTests step * go generate Co-authored-by: Oliver Nocon <33484802+OliverNocon@users.noreply.github.com> * Address further nil references (#3462) * Address further nil references * Message text * Final checks * fix (npmExecuteScripts) allow npm pack before npm publish (#3455) * adding config to piperNpmr * scope in cli * adding scope to repo url and npmrc * publish to scoped * removing scope * changing scope position * adding scope to userconfig * adding registry= * pack and then tar * not removing tmp folder * adding flag * pack before publish * adding log * debug * debug with change directory * publishing created tar ball * debug * üath * adding main npmrc * renaming old npmrc file * error renaming old npmrc file * renaming err * correcting npmrc file path * renaming file back to original * current working directory * renaming the npmrc file * avoiding change directory * with current working dir * adding dot * renaming npmrc and defer removal * rename files * Update pkg/npm/publish.go * Update pkg/npm/publish.go Co-authored-by: anilkeshav27 <you@example.com> Co-authored-by: Oliver Nocon <33484802+OliverNocon@users.noreply.github.com> * Add testing for helm during acceptance stage (#3402) * Add kubernetesDeploy to Acceptance * Add more kubernetesDeploy * Add helm tests * Change documentation * Fix docu * Change generated * Add tests * Add groovy tests * Fix tests * Change tests Co-authored-by: Thorsten Duda <thorsten.duda@sap.com> * Batch Request for Patches * Fix(gctsDeploy) : add client in config url, disable retry for create and pull (#3464) * minor Unit Test correction * lil cleanup * lil refactoring * removed nuneeded linebreaks * refactoring Command on Entity in Batch * some Unit Tests for Build Batch Request * more Unittests - Build Batch Request * fix(fortifyExecuteScan): User assignment based on PR ownership (#3472) * Debug PR user details * Check association * Change to login * Fix PR creator assignment * Improve docs * Fix test * Update gradle version (#3476) * Update gradle version * Update generated file * small correction Text & Test * chore(kubernetesDeploy): add telemetry for deployTool (#3469) * chore(kubernetesDeploy): add telemetry for deployTool * Update cmd/kubernetesDeploy.go Co-authored-by: Oliver Nocon <33484802+OliverNocon@users.noreply.github.com> * rename Parameter patchIfExisting * fix (mtaBuild) keep mtar artifact name in synch with maven gav (#3454) * keep mtar name in synch with maven gav * retaining slashes * keeping dots in artifact name Co-authored-by: anilkeshav27 <you@example.com> * Update image for gradle build (#3479) Co-authored-by: Oliver Nocon <33484802+OliverNocon@users.noreply.github.com> * Last Changed not Zero check added * Added pseudo_comment_policy in struct * Unit Test adaption * smaller refactoring, Unit Test, removed doubles * fix(cnbBuild) do not add complete path to telemetry (#3487) Co-authored-by: Ralf Pannemans <ralf.pannemans@sap.com> Co-authored-by: Philipp Stehle <philipp.stehle@sap.com> * Add limitation that table keys are exported generically (#3490) * Add limitation that table keys are exported generically * Fix formatting * Clarify delta calculation of different package types (#3482) Co-authored-by: tiloKo <70266685+tiloKo@users.noreply.github.com> * Add troubleshooting for missing add-on registration (#3491) Co-authored-by: tiloKo <70266685+tiloKo@users.noreply.github.com> * feat (Documentation) documentation for mavenBuild and npmExecuteScripts that consume dependencies from a private repo. (#3484) * build depdency docu for maven and npm * removing trailing white space in yaml * Update resources/metadata/mavenBuild.yaml * relative url for vault and mta docu * running go generate * keeping vault relative path * go generate * reverting to global paths * go generate * wild card for a higher level dir * searching on top folder only * relative level above * pointing to infrastructure * correcting links Co-authored-by: anilkeshav27 <you@example.com> Co-authored-by: Oliver Nocon <33484802+OliverNocon@users.noreply.github.com> * fix(kanikoExecute): tmp dir (#3478) Co-authored-by: Oliver Nocon <33484802+OliverNocon@users.noreply.github.com> * feat(golangBuild): add support for publishing binaries (#3495) * fix(golangBuild): keep track of the artifactversion in binary names (#3498) * fix(golangBuild): keep track of the artifactversion in binary names * improve the naming scheme * fix (build dependency) typo corrections (#3494) * typo corrections * trailing white space * go generate Co-authored-by: anilkeshav27 <you@example.com> * Revert "fix(golangBuild): keep track of the artifactversion in binary names (#3498)" (#3499) This reverts commitec783b0da6. * sonarqube coverage: additional metrics (#3465) * sonarqube coverage: additional metrics * sonarExecuteScan: add lines of code and language distribution to sonarscan.json * sonarExecuteScan: consider branch in componentService requests * SonarQube: Do not omit empty values in SonarCoverage * sonarExecuteScan: Add integration tests for ComponentService getLinesOfCode * fix tests * sonarExecuteScan: use pullRequest in componentService Co-authored-by: I550025 <r.kloe@sap.com> Co-authored-by: Marc Bormeth <marc.bormeth@sap.com> * fix(golangBuild): targetRepositoryUrl (#3502) * fix(golangBuild): targetRepositoryUrl * regen * fix(httpclient): folder permissions (#3506) * fix(golangBuild): use PUT instead of POST (#3504) Co-authored-by: Oliver Nocon <33484802+OliverNocon@users.noreply.github.com> * feat(golangBuild): publish to subfolder (#3503) * feat(golangBuild): publish to subfolder * edge case handling * fix * fix(golangBuild): expect status 201 instead of 200 (#3508) * feat(kanikoExecute): allow building multiple images (#3443) * feat(kanikoExecute): allow building multiple images * enhance tests * chore: allow running tests in parallel * small fixes * fix: fix destination bug * update formatting and defaults * fix yml formatting * chore: change cpe parameter names * chore: improve variable naming * Changes GetJobName value to repositoryname (#3509) * Update npmExecuteScripts step (#3211) * Update npmExecuteScripts step * Fixed failing build * Fixed path issue Co-authored-by: Oliver Nocon <33484802+OliverNocon@users.noreply.github.com> Co-authored-by: Christopher Fenner <26137398+CCFenner@users.noreply.github.com> Co-authored-by: Christian Volk <christian.volk@sap.com> * Ignore violations if failOn is NONE (#3513) * fix(sonarExecuteScan): error handling for report metrics (#3512) * Generic step input from addon descriptor (#3467) * enhance build step to run based on addon.yml in steampunk environment Co-authored-by: tiloKo <70266685+tiloKo@users.noreply.github.com> * feat(golangBuild): add BOM creation (#3496) * Added BOM creation * Fix cyclonedx install * undo config.yml changes * metadata was updated * Update golangBuild.go Co-authored-by: Oliver Nocon <33484802+OliverNocon@users.noreply.github.com> * If statement dearrangement Co-authored-by: Daniel Bernd <93763187+danManSAP@users.noreply.github.com> Co-authored-by: Mayur Belur Mohan <68264167+mayurmohan@users.noreply.github.com> Co-authored-by: Roland Stengel <r.stengel@sap.com> Co-authored-by: Oliver Feldmann <oliver.feldmann@sap.com> Co-authored-by: Jordi van Liempt <35920075+jliempt@users.noreply.github.com> Co-authored-by: Jesse Awan <jesse.awan@sap.com> Co-authored-by: Pavel Busko <pavel.busko@sap.com> Co-authored-by: Philipp Stehle <philipp.stehle@sap.com> Co-authored-by: Marc Bormeth <marc.bormeth@sap.com> Co-authored-by: Oliver Nocon <33484802+OliverNocon@users.noreply.github.com> Co-authored-by: Anil Keshav <anil.keshav@sap.com> Co-authored-by: anilkeshav27 <you@example.com> Co-authored-by: tiloKo <70266685+tiloKo@users.noreply.github.com> Co-authored-by: Daniel Mieg <56156797+DanielMieg@users.noreply.github.com> Co-authored-by: Siarhei Pazdniakou <siarhei.pazdniakou@sap.com> Co-authored-by: Christopher Fenner <26137398+CCFenner@users.noreply.github.com> Co-authored-by: Peter Persiel <6087940+peterpersiel@users.noreply.github.com> Co-authored-by: Ralf Pannemans <ralf.pannemans@sap.com> Co-authored-by: Marcus Holl <marcus.holl@sap.com> Co-authored-by: Johannes Dillmann <j.dillmann@sap.com> Co-authored-by: Sumit Kulhadia <sumit.kulhadia@sap.com> Co-authored-by: Nikolay Grechanov <nikolay.grechanov@sap.com> Co-authored-by: Umidjon Urunov <79094563+UmidjonUrunov@users.noreply.github.com> Co-authored-by: D072410 <giridhar.shenoy@sap.com> Co-authored-by: Sven Merk <33895725+nevskrem@users.noreply.github.com> Co-authored-by: Sarat Krishnan <78093145+sarat-krk@users.noreply.github.com> Co-authored-by: Raghunath Deshpande <raghunath.deshpande@sap.com> Co-authored-by: raghunathd8 <root@docker-evaluation.openstack.eu-nl-1.cloud.sap> Co-authored-by: Christian Volk <christian.volk@sap.com> Co-authored-by: Eugene Kortelyov <eugene.kortelyov@sap.com> Co-authored-by: Linda Siebert <39100394+LindaSieb@users.noreply.github.com> Co-authored-by: Thorsten Duda <thorsten.duda@sap.com> Co-authored-by: Matthias Scudlik <matthias.scudlik@gmail.com> Co-authored-by: I550025 <r.kloe@sap.com> Co-authored-by: ffeldmann <f.feldmann@sap.com> Co-authored-by: ManjunathMS35 <manjunathms35@gmail.com> Co-authored-by: Matthias Scudlik <matthias.scudlik@sap.com> Co-authored-by: rosemarieB <45030247+rosemarieB@users.noreply.github.com>
This commit is contained in:
		
							
								
								
									
										500
									
								
								cmd/abapEnvironmentPushATCSystemConfig.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										500
									
								
								cmd/abapEnvironmentPushATCSystemConfig.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,500 @@ | ||||
| package cmd | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"io/ioutil" | ||||
| 	"net/http" | ||||
| 	"net/http/cookiejar" | ||||
| 	"path/filepath" | ||||
| 	"reflect" | ||||
| 	"strconv" | ||||
| 	"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 abapEnvironmentPushATCSystemConfig(config abapEnvironmentPushATCSystemConfigOptions, telemetryData *telemetry.CustomData) { | ||||
| 	// for command execution use Command | ||||
| 	c := command.Command{} | ||||
| 	// reroute command output to logging framework | ||||
| 	c.Stdout(log.Writer()) | ||||
| 	c.Stderr(log.Writer()) | ||||
|  | ||||
| 	var autils = abaputils.AbapUtils{ | ||||
| 		Exec: &c, | ||||
| 	} | ||||
|  | ||||
| 	client := piperhttp.Client{} | ||||
|  | ||||
| 	err := runAbapEnvironmentPushATCSystemConfig(&config, telemetryData, &autils, &client) | ||||
| 	if err != nil { | ||||
| 		log.Entry().WithError(err).Fatal("step execution failed") | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func runAbapEnvironmentPushATCSystemConfig(config *abapEnvironmentPushATCSystemConfigOptions, telemetryData *telemetry.CustomData, autils abaputils.Communication, client piperhttp.Sender) error { | ||||
|  | ||||
| 	subOptions := convertATCSysOptions(config) | ||||
|  | ||||
| 	// Determine the host, user and password, either via the input parameters or via a cloud foundry service key | ||||
| 	connectionDetails, err := autils.GetAbapCommunicationArrangementInfo(subOptions, "/sap/opu/odata4/sap/satc_ci_cf_api/srvd_a2x/sap/satc_ci_cf_sv_api/0001") | ||||
| 	if err != nil { | ||||
| 		return errors.Wrap(err, "Parameters for the ABAP Connection not available") | ||||
| 	} | ||||
|  | ||||
| 	cookieJar, err := cookiejar.New(nil) | ||||
| 	if err != nil { | ||||
| 		return errors.Wrap(err, "could not create a Cookie Jar") | ||||
| 	} | ||||
| 	clientOptions := piperhttp.ClientOptions{ | ||||
| 		MaxRequestDuration: 180 * time.Second, | ||||
| 		CookieJar:          cookieJar, | ||||
| 		Username:           connectionDetails.User, | ||||
| 		Password:           connectionDetails.Password, | ||||
| 	} | ||||
| 	client.SetOptions(clientOptions) | ||||
|  | ||||
| 	return pushATCSystemConfig(config, connectionDetails, client) | ||||
|  | ||||
| } | ||||
|  | ||||
| func pushATCSystemConfig(config *abapEnvironmentPushATCSystemConfigOptions, connectionDetails abaputils.ConnectionDetailsHTTP, client piperhttp.Sender) error { | ||||
|  | ||||
| 	//check, if given ATC System configuration File | ||||
| 	parsedConfigurationJson, atcSystemConfiguartionJsonFile, err := checkATCSystemConfigurationFile(config) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	//check, if ATC configuration with given name already exists in Backend | ||||
| 	configDoesExist, configName, configUUID, configLastChangedBackend, err := checkConfigExistsInBackend(config, atcSystemConfiguartionJsonFile, connectionDetails, client) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	if !configDoesExist { | ||||
| 		//regular push of configuration | ||||
| 		configUUID = "" | ||||
| 		return handlePushConfiguration(config, configUUID, configDoesExist, atcSystemConfiguartionJsonFile, connectionDetails, client) | ||||
| 	} | ||||
| 	if configLastChangedBackend.Before(parsedConfigurationJson.LastChangedAt) && !parsedConfigurationJson.LastChangedAt.IsZero() && !config.PatchIfExisting { | ||||
| 		//config exists, is not recent but must NOT be patched | ||||
| 		log.Entry().Warn("pushing ATC System Configuration skipped. Reason: ATC System Configuration with name " + configName + " exists and is outdated (Backend: " + configLastChangedBackend.Local().String() + " vs. File: " + parsedConfigurationJson.LastChangedAt.Local().String() + ") but should not be overwritten (check step configuration parameter).") | ||||
| 		return nil | ||||
| 	} | ||||
| 	if !parsedConfigurationJson.LastChangedAt.IsZero() && (configLastChangedBackend.After(parsedConfigurationJson.LastChangedAt) || configLastChangedBackend == parsedConfigurationJson.LastChangedAt) { | ||||
| 		//configuration exists and is most recent | ||||
| 		log.Entry().Info("pushing ATC System Configuration skipped. Reason: ATC System Configuration with name " + configName + " exists and is most recent (Backend: " + configLastChangedBackend.Local().String() + " vs. File: " + parsedConfigurationJson.LastChangedAt.Local().String() + "). Therefore no update needed.") | ||||
| 		return nil | ||||
| 	} | ||||
| 	if config.PatchIfExisting && (configLastChangedBackend.Before(parsedConfigurationJson.LastChangedAt) || parsedConfigurationJson.LastChangedAt.IsZero()) { | ||||
| 		//configuration exists and is older than current config (or does not provide information about lastChanged) and should be patched | ||||
| 		return handlePushConfiguration(config, configUUID, configDoesExist, atcSystemConfiguartionJsonFile, connectionDetails, client) | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func checkATCSystemConfigurationFile(config *abapEnvironmentPushATCSystemConfigOptions) (parsedConfigJsonWithExpand, []byte, error) { | ||||
| 	var parsedConfigurationJson parsedConfigJsonWithExpand | ||||
| 	var emptyConfigurationJson parsedConfigJsonWithExpand | ||||
| 	var atcSystemConfiguartionJsonFile []byte | ||||
|  | ||||
| 	parsedConfigurationJson, atcSystemConfiguartionJsonFile, err := readATCSystemConfigurationFile(config) | ||||
| 	if err != nil { | ||||
| 		return parsedConfigurationJson, atcSystemConfiguartionJsonFile, err | ||||
| 	} | ||||
|  | ||||
| 	//check if parsedConfigurationJson is not initial or Configuration Name not supplied | ||||
| 	if reflect.DeepEqual(parsedConfigurationJson, emptyConfigurationJson) || | ||||
| 		parsedConfigurationJson.ConfName == "" { | ||||
| 		return parsedConfigurationJson, atcSystemConfiguartionJsonFile, fmt.Errorf("pushing ATC System Configuration failed. Reason: Configured File does not contain required ATC System Configuration attributes (File: " + config.AtcSystemConfigFilePath + ")") | ||||
| 	} | ||||
|  | ||||
| 	return parsedConfigurationJson, atcSystemConfiguartionJsonFile, nil | ||||
| } | ||||
|  | ||||
| func readATCSystemConfigurationFile(config *abapEnvironmentPushATCSystemConfigOptions) (parsedConfigJsonWithExpand, []byte, error) { | ||||
| 	var parsedConfigurationJson parsedConfigJsonWithExpand | ||||
| 	var emptyConfigurationJson parsedConfigJsonWithExpand | ||||
| 	var atcSystemConfiguartionJsonFile []byte | ||||
| 	var filename string | ||||
|  | ||||
| 	filelocation, err := filepath.Glob(config.AtcSystemConfigFilePath) | ||||
| 	if err != nil { | ||||
| 		return parsedConfigurationJson, atcSystemConfiguartionJsonFile, err | ||||
| 	} | ||||
|  | ||||
| 	if len(filelocation) == 0 { | ||||
| 		return parsedConfigurationJson, atcSystemConfiguartionJsonFile, fmt.Errorf("pushing ATC System Configuration failed. Reason: Configured Filelocation is empty (File: " + config.AtcSystemConfigFilePath + ")") | ||||
| 	} | ||||
|  | ||||
| 	filename, err = filepath.Abs(filelocation[0]) | ||||
| 	if err != nil { | ||||
| 		return parsedConfigurationJson, atcSystemConfiguartionJsonFile, err | ||||
| 	} | ||||
| 	atcSystemConfiguartionJsonFile, err = ioutil.ReadFile(filename) | ||||
| 	if err != nil { | ||||
| 		return parsedConfigurationJson, atcSystemConfiguartionJsonFile, err | ||||
| 	} | ||||
| 	if len(atcSystemConfiguartionJsonFile) == 0 { | ||||
| 		return parsedConfigurationJson, atcSystemConfiguartionJsonFile, fmt.Errorf("pushing ATC System Configuration failed. Reason: Configured File is empty (File: " + config.AtcSystemConfigFilePath + ")") | ||||
| 	} | ||||
|  | ||||
| 	err = json.Unmarshal(atcSystemConfiguartionJsonFile, &parsedConfigurationJson) | ||||
| 	if err != nil { | ||||
| 		return emptyConfigurationJson, atcSystemConfiguartionJsonFile, err | ||||
| 	} | ||||
|  | ||||
| 	return parsedConfigurationJson, atcSystemConfiguartionJsonFile, err | ||||
| } | ||||
|  | ||||
| func handlePushConfiguration(config *abapEnvironmentPushATCSystemConfigOptions, confUUID string, configDoesExist bool, atcSystemConfiguartionJsonFile []byte, connectionDetails abaputils.ConnectionDetailsHTTP, client piperhttp.Sender) error { | ||||
|  | ||||
| 	var err error | ||||
| 	connectionDetails.XCsrfToken, err = fetchXcsrfTokenFromHead(connectionDetails, client) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	if configDoesExist { | ||||
| 		err = doPatchATCSystemConfig(config, confUUID, atcSystemConfiguartionJsonFile, connectionDetails, client) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		log.Entry().Info("ATC System Configuration successfully pushed from file " + config.AtcSystemConfigFilePath + " and patched in system") | ||||
| 	} | ||||
| 	if !configDoesExist { | ||||
| 		err = doPushATCSystemConfig(config, atcSystemConfiguartionJsonFile, connectionDetails, client) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		log.Entry().Info("ATC System Configuration successfully pushed from file " + config.AtcSystemConfigFilePath + " and created in system") | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
|  | ||||
| } | ||||
|  | ||||
| func fetchXcsrfTokenFromHead(connectionDetails abaputils.ConnectionDetailsHTTP, client piperhttp.Sender) (string, error) { | ||||
|  | ||||
| 	log.Entry().WithField("ABAP Endpoint: ", connectionDetails.URL).Debug("Fetching Xcrsf-Token") | ||||
| 	uriConnectionDetails := connectionDetails | ||||
| 	uriConnectionDetails.URL = "" | ||||
| 	connectionDetails.XCsrfToken = "fetch" | ||||
|  | ||||
| 	// Loging into the ABAP System - getting the x-csrf-token and cookies | ||||
| 	resp, err := abaputils.GetHTTPResponse("HEAD", connectionDetails, nil, client) | ||||
| 	if err != nil { | ||||
| 		err = abaputils.HandleHTTPError(resp, err, "authentication on the ABAP system failed", connectionDetails) | ||||
| 		return connectionDetails.XCsrfToken, err | ||||
| 	} | ||||
| 	defer resp.Body.Close() | ||||
|  | ||||
| 	log.Entry().WithField("StatusCode", resp.Status).WithField("ABAP Endpoint", connectionDetails.URL).Debug("Authentication on the ABAP system successful") | ||||
| 	uriConnectionDetails.XCsrfToken = resp.Header.Get("X-Csrf-Token") | ||||
| 	connectionDetails.XCsrfToken = uriConnectionDetails.XCsrfToken | ||||
|  | ||||
| 	return connectionDetails.XCsrfToken, err | ||||
| } | ||||
|  | ||||
| func doPatchATCSystemConfig(config *abapEnvironmentPushATCSystemConfigOptions, confUUID string, atcSystemConfiguartionJsonFile []byte, connectionDetails abaputils.ConnectionDetailsHTTP, client piperhttp.Sender) error { | ||||
|  | ||||
| 	batchATCSystemConfigFile, err := buildATCSystemConfigBatchRequest(confUUID, atcSystemConfiguartionJsonFile) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	return doBatchATCSystemConfig(config, batchATCSystemConfigFile, connectionDetails, client) | ||||
|  | ||||
| } | ||||
|  | ||||
| func buildATCSystemConfigBatchRequest(confUUID string, atcSystemConfiguartionJsonFile []byte) (string, error) { | ||||
|  | ||||
| 	var batchRequestString string | ||||
|  | ||||
| 	//splitting json into configuration base and configuration properties & build a batch request for oData - patch config & patch priorities | ||||
| 	var configBaseJson parsedConfigJsonBase | ||||
| 	err := json.Unmarshal(atcSystemConfiguartionJsonFile, &configBaseJson) | ||||
| 	if err != nil { | ||||
| 		return batchRequestString, err | ||||
| 	} | ||||
| 	var parsedConfigPriorities parsedConfigPriorities | ||||
| 	err = json.Unmarshal(atcSystemConfiguartionJsonFile, &parsedConfigPriorities) | ||||
| 	if err != nil { | ||||
| 		return batchRequestString, err | ||||
| 	} | ||||
|  | ||||
| 	//build the Batch request string | ||||
| 	contentID := 1 | ||||
|  | ||||
| 	batchRequestString = addBeginOfBatch(batchRequestString) | ||||
| 	//now adding opening Changeset as at least config base is to be patched | ||||
| 	batchRequestString = addChangesetBegin(batchRequestString, contentID) | ||||
|  | ||||
| 	configBaseJsonBody, err := json.Marshal(&configBaseJson) | ||||
| 	if err != nil { | ||||
| 		return batchRequestString, err | ||||
| 	} | ||||
| 	batchRequestString = addPatchConfigBaseChangeset(batchRequestString, confUUID, configBaseJsonBody) | ||||
|  | ||||
| 	if len(parsedConfigPriorities.Priorities) > 0 { | ||||
| 		// in case Priorities need patches too | ||||
| 		var priority priorityJson | ||||
| 		for i, priorityLine := range parsedConfigPriorities.Priorities { | ||||
|  | ||||
| 			//for each line, add content id | ||||
| 			contentID += 1 | ||||
| 			priority.Priority = priorityLine.Priority | ||||
| 			priorityJsonBody, err := json.Marshal(&priority) | ||||
| 			if err != nil { | ||||
| 				log.Entry().Errorf("problem with marshall of single priority in line "+strconv.Itoa(i), err) | ||||
| 				continue | ||||
| 			} | ||||
| 			batchRequestString = addChangesetBegin(batchRequestString, contentID) | ||||
|  | ||||
| 			//now PATCH command for priority | ||||
| 			batchRequestString = addPatchSinglePriorityChangeset(batchRequestString, confUUID, priorityLine.Test, priorityLine.MessageId, priorityJsonBody) | ||||
|  | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	//at the end, add closing inner and outer boundary tags | ||||
| 	batchRequestString = addEndOfBatch(batchRequestString) | ||||
|  | ||||
| 	log.Entry().Info("Batch Request String: " + batchRequestString) | ||||
|  | ||||
| 	return batchRequestString, nil | ||||
|  | ||||
| } | ||||
|  | ||||
| func addPatchConfigBaseChangeset(inputString string, confUUID string, configBaseJsonBody []byte) string { | ||||
|  | ||||
| 	entityIdString := `(root_id='1',conf_id=` + confUUID + `)` | ||||
| 	newString := addCommandEntityChangeset("PATCH", "configuration", entityIdString, inputString, configBaseJsonBody) | ||||
|  | ||||
| 	return newString | ||||
| } | ||||
|  | ||||
| func addPatchSinglePriorityChangeset(inputString string, confUUID string, test string, messageId string, priorityJsonBody []byte) string { | ||||
|  | ||||
| 	entityIdString := `(root_id='1',conf_id=` + confUUID + `,test='` + test + `',message_id='` + messageId + `')` | ||||
| 	newString := addCommandEntityChangeset("PATCH", "priority", entityIdString, inputString, priorityJsonBody) | ||||
|  | ||||
| 	return newString | ||||
| } | ||||
|  | ||||
| func addChangesetBegin(inputString string, contentID int) string { | ||||
|  | ||||
| 	newString := inputString + ` | ||||
| --changeset | ||||
| Content-Type: application/http | ||||
| Content-Transfer-Encoding: binary | ||||
| Content-ID: ` + strconv.Itoa(contentID) + ` | ||||
| ` | ||||
| 	return newString | ||||
| } | ||||
|  | ||||
| func addBeginOfBatch(inputString string) string { | ||||
| 	//Starting always with outer boundary - followed by mandatory Contenttype and boundary for changeset | ||||
| 	newString := inputString + ` | ||||
| --request-separator | ||||
| Content-Type: multipart/mixed;boundary=changeset | ||||
| ` | ||||
| 	return newString | ||||
| } | ||||
|  | ||||
| func addEndOfBatch(inputString string) string { | ||||
| 	//Starting always with outer boundary - followed by mandatory Contenttype and boundary for changeset | ||||
| 	newString := inputString + ` | ||||
| --changeset-- | ||||
|  | ||||
| --request-separator--` | ||||
|  | ||||
| 	return newString | ||||
| } | ||||
|  | ||||
| func addCommandEntityChangeset(command string, entity string, entityIdString string, inputString string, jsonBody []byte) string { | ||||
|  | ||||
| 	newString := inputString + ` | ||||
| ` + command + ` ` + entity + entityIdString + ` HTTP/1.1 | ||||
| Content-Type: application/json | ||||
|  | ||||
| ` | ||||
| 	if len(jsonBody) > 0 { | ||||
| 		newString += string(jsonBody) + ` | ||||
| ` | ||||
| 	} | ||||
|  | ||||
| 	return newString | ||||
|  | ||||
| } | ||||
|  | ||||
| func doPushATCSystemConfig(config *abapEnvironmentPushATCSystemConfigOptions, atcSystemConfiguartionJsonFile []byte, connectionDetails abaputils.ConnectionDetailsHTTP, client piperhttp.Sender) error { | ||||
| 	abapEndpoint := connectionDetails.URL | ||||
| 	connectionDetails.URL = abapEndpoint + "/configuration" | ||||
|  | ||||
| 	resp, err := abaputils.GetHTTPResponse("POST", connectionDetails, atcSystemConfiguartionJsonFile, client) | ||||
| 	return parseOdataResponse(resp, err, connectionDetails, config) | ||||
| } | ||||
|  | ||||
| func doBatchATCSystemConfig(config *abapEnvironmentPushATCSystemConfigOptions, batchRequestBodyFile string, connectionDetails abaputils.ConnectionDetailsHTTP, client piperhttp.Sender) error { | ||||
| 	abapEndpoint := connectionDetails.URL | ||||
| 	connectionDetails.URL = abapEndpoint + "/$batch" | ||||
|  | ||||
| 	header := make(map[string][]string) | ||||
| 	header["X-Csrf-Token"] = []string{connectionDetails.XCsrfToken} | ||||
| 	header["Content-Type"] = []string{"multipart/mixed;boundary=request-separator"} | ||||
|  | ||||
| 	batchRequestBodyFileByte := []byte(batchRequestBodyFile) | ||||
| 	resp, err := client.SendRequest("POST", connectionDetails.URL, bytes.NewBuffer(batchRequestBodyFileByte), header, nil) | ||||
|  | ||||
| 	return parseOdataResponse(resp, err, connectionDetails, config) | ||||
| } | ||||
|  | ||||
| func checkConfigExistsInBackend(config *abapEnvironmentPushATCSystemConfigOptions, atcSystemConfiguartionJsonFile []byte, connectionDetails abaputils.ConnectionDetailsHTTP, client piperhttp.Sender) (bool, string, string, time.Time, error) { | ||||
| 	var configName string | ||||
| 	var configUUID string | ||||
| 	var configLastChangedAt time.Time | ||||
|  | ||||
| 	//extract Configuration Name from atcSystemConfiguartionJsonFile | ||||
| 	var parsedConfigurationJson parsedConfigJsonWithExpand | ||||
| 	err := json.Unmarshal(atcSystemConfiguartionJsonFile, &parsedConfigurationJson) | ||||
| 	if err != nil { | ||||
| 		return false, configName, configUUID, configLastChangedAt, err | ||||
| 	} | ||||
|  | ||||
| 	//call a get on config with filter on given name | ||||
| 	configName = parsedConfigurationJson.ConfName | ||||
| 	abapEndpoint := connectionDetails.URL | ||||
| 	connectionDetails.URL = abapEndpoint + "/configuration" + "?$filter=conf_name%20eq%20" + "'" + configName + "'" | ||||
| 	if err != nil { | ||||
| 		return false, configName, configUUID, configLastChangedAt, err | ||||
| 	} | ||||
| 	resp, err := abaputils.GetHTTPResponse("GET", connectionDetails, nil, client) | ||||
| 	if err != nil { | ||||
| 		return false, configName, configUUID, configLastChangedAt, err | ||||
| 	} | ||||
| 	var body []byte | ||||
| 	body, err = ioutil.ReadAll(resp.Body) | ||||
| 	if err != nil { | ||||
| 		return false, configName, configUUID, configLastChangedAt, err | ||||
| 	} | ||||
|  | ||||
| 	var parsedoDataResponse parsedOdataResp | ||||
| 	err = json.Unmarshal(body, &parsedoDataResponse) | ||||
| 	if err != nil { | ||||
| 		return false, configName, configUUID, configLastChangedAt, err | ||||
| 	} | ||||
| 	if len(parsedoDataResponse.Value) > 0 { | ||||
| 		configUUID = parsedoDataResponse.Value[0].ConfUUID | ||||
| 		configLastChangedAt = parsedoDataResponse.Value[0].LastChangedAt | ||||
| 		log.Entry().Info("ATC System Configuration " + configName + " does exist and last changed at " + configLastChangedAt.Local().String()) | ||||
| 		return true, configName, configUUID, configLastChangedAt, nil | ||||
| 	} else { | ||||
| 		//response value is empty, so NOT found entity with this name! | ||||
| 		log.Entry().Info("ATC System Configuration " + configName + " does not exist!") | ||||
| 		return false, configName, "", configLastChangedAt, nil | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func parseOdataResponse(resp *http.Response, errorIn error, connectionDetails abaputils.ConnectionDetailsHTTP, config *abapEnvironmentPushATCSystemConfigOptions) error { | ||||
|  | ||||
| 	if resp == nil { | ||||
| 		return errorIn | ||||
| 	} | ||||
|  | ||||
| 	log.Entry().Info("parsedResp: StatusCode: " + resp.Status) | ||||
|  | ||||
| 	var err error | ||||
| 	var body []byte | ||||
| 	body, err = ioutil.ReadAll(resp.Body) | ||||
| 	if err != nil { | ||||
| 		defer resp.Body.Close() | ||||
| 		return fmt.Errorf("parsing response failed: %w", err) | ||||
| 	} | ||||
| 	defer resp.Body.Close() | ||||
|  | ||||
| 	switch resp.StatusCode { | ||||
| 	case 200: //Retrieved entities & OK in Patch & OK in Batch | ||||
| 		log.Entry().Infof("parsedRespBody: " + string(body)) | ||||
|  | ||||
| 	case 201: //CREATED | ||||
| 		log.Entry().Infof("parsedRespBody: " + string(body)) | ||||
|  | ||||
| 	case 400: //BAD REQUEST | ||||
| 		//no errorIn, Error in Body | ||||
| 		if err != nil { | ||||
| 			return fmt.Errorf("parsing oData response failed: %w", err) | ||||
| 		} | ||||
| 		if len(body) == 0 { | ||||
| 			return fmt.Errorf("parsing oData response failed: %w", errors.New("body is empty, can't parse empty body")) | ||||
| 		} | ||||
| 		var parsedOdataErrors interface{} | ||||
| 		err = json.Unmarshal(body, &parsedOdataErrors) | ||||
| 		if err != nil { | ||||
| 			return fmt.Errorf("unmarshal oData response json failed: %w", err) | ||||
| 		} | ||||
| 		return fmt.Errorf("bad Request Errors: %v", parsedOdataErrors) | ||||
|  | ||||
| 	default: //unhandled OK Code | ||||
| 		return fmt.Errorf("unhandled StatusCode: "+resp.Status, errorIn) | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| func convertATCSysOptions(options *abapEnvironmentPushATCSystemConfigOptions) abaputils.AbapEnvironmentOptions { | ||||
| 	subOptions := abaputils.AbapEnvironmentOptions{} | ||||
|  | ||||
| 	subOptions.CfAPIEndpoint = options.CfAPIEndpoint | ||||
| 	subOptions.CfServiceInstance = options.CfServiceInstance | ||||
| 	subOptions.CfServiceKeyName = options.CfServiceKeyName | ||||
| 	subOptions.CfOrg = options.CfOrg | ||||
| 	subOptions.CfSpace = options.CfSpace | ||||
| 	subOptions.Host = options.Host | ||||
| 	subOptions.Password = options.Password | ||||
| 	subOptions.Username = options.Username | ||||
|  | ||||
| 	return subOptions | ||||
| } | ||||
|  | ||||
| type parsedOdataResp struct { | ||||
| 	Value []parsedConfigJsonWithExpand `json:"value"` | ||||
| } | ||||
|  | ||||
| type parsedConfigJsonWithExpand struct { | ||||
| 	ConfName      string                 `json:"conf_name"` | ||||
| 	ConfUUID      string                 `json:"conf_id"` | ||||
| 	LastChangedAt time.Time              `json:"last_changed_at"` | ||||
| 	Priorities    []parsedConfigPriority `json:"_priorities"` | ||||
| } | ||||
|  | ||||
| type parsedConfigJsonBase struct { | ||||
| 	ConfName            string `json:"conf_name"` | ||||
| 	ConfUUID            string `json:"conf_id"` | ||||
| 	Checkvariant        string `json:"checkvariant"` | ||||
| 	PseudoCommentPolicy string `json:"pseudo_comment_policy"` | ||||
| 	BlockFindings       string `json:"block_findings"` | ||||
| 	InformFindings      string `json:"inform_findings"` | ||||
| 	IsDefault           bool   `json:"is_default"` | ||||
| 	IsProxyVariant      bool   `json:"is_proxy_variant"` | ||||
| } | ||||
|  | ||||
| type parsedConfigPriorities struct { | ||||
| 	Priorities []parsedConfigPriority `json:"_priorities"` | ||||
| } | ||||
|  | ||||
| type parsedConfigPriority struct { | ||||
| 	Test      string      `json:"test"` | ||||
| 	MessageId string      `json:"message_id"` | ||||
| 	Priority  json.Number `json:"priority"` | ||||
| } | ||||
|  | ||||
| type priorityJson struct { | ||||
| 	Priority json.Number `json:"priority"` | ||||
| } | ||||
							
								
								
									
										267
									
								
								cmd/abapEnvironmentPushATCSystemConfig_generated.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										267
									
								
								cmd/abapEnvironmentPushATCSystemConfig_generated.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,267 @@ | ||||
| // 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 abapEnvironmentPushATCSystemConfigOptions struct { | ||||
| 	AtcSystemConfigFilePath string `json:"atcSystemConfigFilePath,omitempty"` | ||||
| 	PatchIfExisting         bool   `json:"patchIfExisting,omitempty"` | ||||
| 	CfAPIEndpoint           string `json:"cfApiEndpoint,omitempty"` | ||||
| 	CfOrg                   string `json:"cfOrg,omitempty"` | ||||
| 	CfServiceInstance       string `json:"cfServiceInstance,omitempty"` | ||||
| 	CfServiceKeyName        string `json:"cfServiceKeyName,omitempty"` | ||||
| 	CfSpace                 string `json:"cfSpace,omitempty"` | ||||
| 	Username                string `json:"username,omitempty"` | ||||
| 	Password                string `json:"password,omitempty"` | ||||
| 	Host                    string `json:"host,omitempty"` | ||||
| } | ||||
|  | ||||
| // AbapEnvironmentPushATCSystemConfigCommand Create/Update ATC System Configuration | ||||
| func AbapEnvironmentPushATCSystemConfigCommand() *cobra.Command { | ||||
| 	const STEP_NAME = "abapEnvironmentPushATCSystemConfig" | ||||
|  | ||||
| 	metadata := abapEnvironmentPushATCSystemConfigMetadata() | ||||
| 	var stepConfig abapEnvironmentPushATCSystemConfigOptions | ||||
| 	var startTime time.Time | ||||
| 	var logCollector *log.CollectorHook | ||||
| 	var splunkClient *splunk.Splunk | ||||
| 	telemetryClient := &telemetry.Telemetry{} | ||||
|  | ||||
| 	var createAbapEnvironmentPushATCSystemConfigCmd = &cobra.Command{ | ||||
| 		Use:   STEP_NAME, | ||||
| 		Short: "Create/Update ATC System Configuration", | ||||
| 		Long: `This step is for creating/updating an [ATC](https://help.sap.com/products/BTP/65de2977205c403bbc107264b8eccf4b/657285a09f7148d894c27bb8e17827cf.html?version=Cloud) system configurationon on an SAP BTP, ABAP Environment system. | ||||
| Please provide either of the following options: | ||||
|  | ||||
| * The host and credentials the SAP BTP, ABAP Environment system itself. The credentials must be configured for the Communication Scenario [SAP_COM_0763] (https://help.sap.com/products/BTP/65de2977205c403bbc107264b8eccf4b/657285a09f7148d894c27bb8e17827cf.html?version=Cloud). | ||||
| * 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_0763. | ||||
| * 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) | ||||
| 			} | ||||
| 			abapEnvironmentPushATCSystemConfig(stepConfig, &stepTelemetryData) | ||||
| 			stepTelemetryData.ErrorCode = "0" | ||||
| 			log.Entry().Info("SUCCESS") | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	addAbapEnvironmentPushATCSystemConfigFlags(createAbapEnvironmentPushATCSystemConfigCmd, &stepConfig) | ||||
| 	return createAbapEnvironmentPushATCSystemConfigCmd | ||||
| } | ||||
|  | ||||
| func addAbapEnvironmentPushATCSystemConfigFlags(cmd *cobra.Command, stepConfig *abapEnvironmentPushATCSystemConfigOptions) { | ||||
| 	cmd.Flags().StringVar(&stepConfig.AtcSystemConfigFilePath, "atcSystemConfigFilePath", os.Getenv("PIPER_atcSystemConfigFilePath"), "Path to a JSON file with ATC System Configuration") | ||||
| 	cmd.Flags().BoolVar(&stepConfig.PatchIfExisting, "patchIfExisting", true, "In case an configuration under the given name already exists in the system. Should the step update/patch the existing ATC Systm Configuration from the provided ATC System Configuration file?") | ||||
| 	cmd.Flags().StringVar(&stepConfig.CfAPIEndpoint, "cfApiEndpoint", os.Getenv("PIPER_cfApiEndpoint"), "Cloud Foundry API endpoint") | ||||
| 	cmd.Flags().StringVar(&stepConfig.CfOrg, "cfOrg", os.Getenv("PIPER_cfOrg"), "CF org") | ||||
| 	cmd.Flags().StringVar(&stepConfig.CfServiceInstance, "cfServiceInstance", os.Getenv("PIPER_cfServiceInstance"), "Parameter of ServiceInstance Name to delete CloudFoundry Service") | ||||
| 	cmd.Flags().StringVar(&stepConfig.CfServiceKeyName, "cfServiceKeyName", os.Getenv("PIPER_cfServiceKeyName"), "Parameter of CloudFoundry Service Key to be created") | ||||
| 	cmd.Flags().StringVar(&stepConfig.CfSpace, "cfSpace", os.Getenv("PIPER_cfSpace"), "CF Space") | ||||
| 	cmd.Flags().StringVar(&stepConfig.Username, "username", os.Getenv("PIPER_username"), "User for either the Cloud Foundry API or the Communication Arrangement for SAP_COM_0763") | ||||
| 	cmd.Flags().StringVar(&stepConfig.Password, "password", os.Getenv("PIPER_password"), "Password for either the Cloud Foundry API or the Communication Arrangement for SAP_COM_0763") | ||||
| 	cmd.Flags().StringVar(&stepConfig.Host, "host", os.Getenv("PIPER_host"), "Specifies the host address of the SAP SAP BTP, ABAP Environment system") | ||||
|  | ||||
| 	cmd.MarkFlagRequired("atcSystemConfigFilePath") | ||||
| 	cmd.MarkFlagRequired("username") | ||||
| 	cmd.MarkFlagRequired("password") | ||||
| } | ||||
|  | ||||
| // retrieve step metadata | ||||
| func abapEnvironmentPushATCSystemConfigMetadata() config.StepData { | ||||
| 	var theMetaData = config.StepData{ | ||||
| 		Metadata: config.StepMetadata{ | ||||
| 			Name:        "abapEnvironmentPushATCSystemConfig", | ||||
| 			Aliases:     []config.Alias{}, | ||||
| 			Description: "Create/Update ATC System Configuration", | ||||
| 		}, | ||||
| 		Spec: config.StepSpec{ | ||||
| 			Inputs: config.StepInputs{ | ||||
| 				Secrets: []config.StepSecrets{ | ||||
| 					{Name: "abapCredentialsId", Description: "Jenkins credentials ID containing user and password to authenticate to the SAP BTP, ABAP Environment system or the Cloud Foundry API", Type: "jenkins", Aliases: []config.Alias{{Name: "cfCredentialsId", Deprecated: false}}}, | ||||
| 				}, | ||||
| 				Parameters: []config.StepParameters{ | ||||
| 					{ | ||||
| 						Name:        "atcSystemConfigFilePath", | ||||
| 						ResourceRef: []config.ResourceReference{}, | ||||
| 						Scope:       []string{"PARAMETERS", "STAGES", "STEPS"}, | ||||
| 						Type:        "string", | ||||
| 						Mandatory:   true, | ||||
| 						Aliases:     []config.Alias{}, | ||||
| 						Default:     os.Getenv("PIPER_atcSystemConfigFilePath"), | ||||
| 					}, | ||||
| 					{ | ||||
| 						Name:        "patchIfExisting", | ||||
| 						ResourceRef: []config.ResourceReference{}, | ||||
| 						Scope:       []string{"PARAMETERS", "STAGES", "STEPS"}, | ||||
| 						Type:        "bool", | ||||
| 						Mandatory:   false, | ||||
| 						Aliases:     []config.Alias{}, | ||||
| 						Default:     true, | ||||
| 					}, | ||||
| 					{ | ||||
| 						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:        "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"), | ||||
| 					}, | ||||
| 					{ | ||||
| 						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: "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:        "host", | ||||
| 						ResourceRef: []config.ResourceReference{}, | ||||
| 						Scope:       []string{"PARAMETERS", "STAGES", "STEPS", "GENERAL"}, | ||||
| 						Type:        "string", | ||||
| 						Mandatory:   false, | ||||
| 						Aliases:     []config.Alias{}, | ||||
| 						Default:     os.Getenv("PIPER_host"), | ||||
| 					}, | ||||
| 				}, | ||||
| 			}, | ||||
| 			Containers: []config.Container{ | ||||
| 				{Name: "cf", Image: "ppiper/cf-cli:7"}, | ||||
| 			}, | ||||
| 		}, | ||||
| 	} | ||||
| 	return theMetaData | ||||
| } | ||||
							
								
								
									
										17
									
								
								cmd/abapEnvironmentPushATCSystemConfig_generated_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								cmd/abapEnvironmentPushATCSystemConfig_generated_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| package cmd | ||||
|  | ||||
| import ( | ||||
| 	"testing" | ||||
|  | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
|  | ||||
| func TestAbapEnvironmentPushATCSystemConfigCommand(t *testing.T) { | ||||
| 	t.Parallel() | ||||
|  | ||||
| 	testCmd := AbapEnvironmentPushATCSystemConfigCommand() | ||||
|  | ||||
| 	// only high level testing performed - details are tested in step generation procedure | ||||
| 	assert.Equal(t, "abapEnvironmentPushATCSystemConfig", testCmd.Use, "command name incorrect") | ||||
|  | ||||
| } | ||||
							
								
								
									
										499
									
								
								cmd/abapEnvironmentPushATCSystemConfig_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										499
									
								
								cmd/abapEnvironmentPushATCSystemConfig_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,499 @@ | ||||
| package cmd | ||||
|  | ||||
| import ( | ||||
| 	"io/ioutil" | ||||
| 	"os" | ||||
| 	"testing" | ||||
|  | ||||
| 	"github.com/SAP/jenkins-library/pkg/abaputils" | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
|  | ||||
| func TestFetchXcsrfTokenFromHead(t *testing.T) { | ||||
| 	t.Parallel() | ||||
| 	t.Run("FetchXcsrfToken Test", func(t *testing.T) { | ||||
| 		tokenExpected := "myToken" | ||||
|  | ||||
| 		client := &abaputils.ClientMock{ | ||||
| 			Body:  `Xcsrf Token test`, | ||||
| 			Token: tokenExpected, | ||||
| 		} | ||||
|  | ||||
| 		con := abaputils.ConnectionDetailsHTTP{ | ||||
| 			User:     "Test", | ||||
| 			Password: "Test", | ||||
| 			URL:      "https://api.endpoint.com/Entity/", | ||||
| 		} | ||||
| 		token, error := fetchXcsrfTokenFromHead(con, client) | ||||
| 		if error == nil { | ||||
| 			assert.Equal(t, tokenExpected, token) | ||||
| 		} | ||||
| 	}) | ||||
| 	t.Run("failure case: fetch token", func(t *testing.T) { | ||||
| 		tokenExpected := "" | ||||
|  | ||||
| 		client := &abaputils.ClientMock{ | ||||
| 			Body:  `Xcsrf Token test`, | ||||
| 			Token: "", | ||||
| 		} | ||||
|  | ||||
| 		con := abaputils.ConnectionDetailsHTTP{ | ||||
| 			User:     "Test", | ||||
| 			Password: "Test", | ||||
| 			URL:      "https://api.endpoint.com/Entity/", | ||||
| 		} | ||||
| 		token, error := fetchXcsrfTokenFromHead(con, client) | ||||
| 		if error == nil { | ||||
| 			assert.Equal(t, tokenExpected, token) | ||||
| 		} | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func TestBuildATCSystemConfigBatchRequest(t *testing.T) { | ||||
| 	t.Parallel() | ||||
|  | ||||
| 	t.Run("success case: BuildATCSystemConfigBatch - Config Base & 1 Priority", func(t *testing.T) { | ||||
|  | ||||
| 		batchATCSystemConfigFileExpected := ` | ||||
| --request-separator | ||||
| Content-Type: multipart/mixed;boundary=changeset | ||||
|  | ||||
| --changeset | ||||
| Content-Type: application/http | ||||
| Content-Transfer-Encoding: binary | ||||
| Content-ID: 1 | ||||
|  | ||||
| PATCH configuration(root_id='1',conf_id=4711) HTTP/1.1 | ||||
| Content-Type: application/json | ||||
|  | ||||
| {"conf_name":"UNITTEST_PIPERSTEP","conf_id":"","checkvariant":"SAP_CLOUD_PLATFORM_ATC_DEFAULT","pseudo_comment_policy":"MK","block_findings":"0","inform_findings":"1","is_default":false,"is_proxy_variant":false} | ||||
|  | ||||
| --changeset | ||||
| Content-Type: application/http | ||||
| Content-Transfer-Encoding: binary | ||||
| Content-ID: 2 | ||||
|  | ||||
| PATCH priority(root_id='1',conf_id=4711,test='CL_CI_TEST_AMDP_HDB_MIGRATION',message_id='FAIL_ABAP') HTTP/1.1 | ||||
| Content-Type: application/json | ||||
|  | ||||
| {"priority":1} | ||||
|  | ||||
| --changeset-- | ||||
|  | ||||
| --request-separator--` | ||||
|  | ||||
| 		//no Configuration name supplied | ||||
| 		atcSystemConfigFileString := `{ | ||||
| 			"conf_name": "UNITTEST_PIPERSTEP", | ||||
| 			"checkvariant": "SAP_CLOUD_PLATFORM_ATC_DEFAULT", | ||||
| 			"pseudo_comment_policy": "MK", | ||||
| 			"block_findings": "0", | ||||
| 			"inform_findings": "1", | ||||
| 			"is_default": false, | ||||
| 			"is_proxy_variant": false, | ||||
| 			"_priorities": [ | ||||
| 				{ | ||||
| 					"test": "CL_CI_TEST_AMDP_HDB_MIGRATION", | ||||
| 					"message_id": "FAIL_ABAP", | ||||
| 					"default_priority": 3, | ||||
| 					"priority": 1 | ||||
| 				} | ||||
| 			] | ||||
| 		} | ||||
| 		` | ||||
|  | ||||
| 		confUUID := "4711" | ||||
| 		batchATCSystemConfigFile, err := buildATCSystemConfigBatchRequest(confUUID, []byte(atcSystemConfigFileString)) | ||||
| 		if err != nil { | ||||
| 			t.Fatal("Failed to Build ATC System Config Batch") | ||||
| 		} | ||||
| 		assert.Equal(t, batchATCSystemConfigFileExpected, batchATCSystemConfigFile) | ||||
|  | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("success case: BuildATCSystemConfigBatch - Config Base & 2 Priorities", func(t *testing.T) { | ||||
|  | ||||
| 		batchATCSystemConfigFileExpected := ` | ||||
| --request-separator | ||||
| Content-Type: multipart/mixed;boundary=changeset | ||||
|  | ||||
| --changeset | ||||
| Content-Type: application/http | ||||
| Content-Transfer-Encoding: binary | ||||
| Content-ID: 1 | ||||
|  | ||||
| PATCH configuration(root_id='1',conf_id=4711) HTTP/1.1 | ||||
| Content-Type: application/json | ||||
|  | ||||
| {"conf_name":"UNITTEST_PIPERSTEP","conf_id":"","checkvariant":"SAP_CLOUD_PLATFORM_ATC_DEFAULT","pseudo_comment_policy":"MK","block_findings":"0","inform_findings":"1","is_default":false,"is_proxy_variant":false} | ||||
|  | ||||
| --changeset | ||||
| Content-Type: application/http | ||||
| Content-Transfer-Encoding: binary | ||||
| Content-ID: 2 | ||||
|  | ||||
| PATCH priority(root_id='1',conf_id=4711,test='CL_CI_TEST_AMDP_HDB_MIGRATION',message_id='FAIL_ABAP') HTTP/1.1 | ||||
| Content-Type: application/json | ||||
|  | ||||
| {"priority":1} | ||||
|  | ||||
| --changeset | ||||
| Content-Type: application/http | ||||
| Content-Transfer-Encoding: binary | ||||
| Content-ID: 3 | ||||
|  | ||||
| PATCH priority(root_id='1',conf_id=4711,test='CL_CI_TEST_AMDP_HDB_MIGRATION',message_id='FAIL_AMDP') HTTP/1.1 | ||||
| Content-Type: application/json | ||||
|  | ||||
| {"priority":2} | ||||
|  | ||||
| --changeset-- | ||||
|  | ||||
| --request-separator--` | ||||
|  | ||||
| 		//no Configuration name supplied | ||||
| 		atcSystemConfigFileString := `{ | ||||
| 			"conf_name": "UNITTEST_PIPERSTEP", | ||||
| 			"checkvariant": "SAP_CLOUD_PLATFORM_ATC_DEFAULT", | ||||
| 			"pseudo_comment_policy": "MK", | ||||
| 			"block_findings": "0", | ||||
| 			"inform_findings": "1", | ||||
| 			"is_default": false, | ||||
| 			"is_proxy_variant": false, | ||||
| 			"_priorities": [ | ||||
| 				{ | ||||
| 					"test": "CL_CI_TEST_AMDP_HDB_MIGRATION", | ||||
| 					"message_id": "FAIL_ABAP", | ||||
| 					"default_priority": 3, | ||||
| 					"priority": 1 | ||||
| 				}, | ||||
| 				{ | ||||
| 					"test": "CL_CI_TEST_AMDP_HDB_MIGRATION", | ||||
| 					"message_id": "FAIL_AMDP", | ||||
| 					"priority": 2 | ||||
| 				} | ||||
| 			] | ||||
| 		} | ||||
| 		` | ||||
|  | ||||
| 		confUUID := "4711" | ||||
| 		batchATCSystemConfigFile, err := buildATCSystemConfigBatchRequest(confUUID, []byte(atcSystemConfigFileString)) | ||||
| 		if err != nil { | ||||
| 			t.Fatal("Failed to Build ATC System Config Batch  Request") | ||||
| 		} | ||||
| 		assert.Equal(t, batchATCSystemConfigFileExpected, batchATCSystemConfigFile) | ||||
|  | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("success case: BuildATCSystemConfigBatch - Config Base only (no existing _priorities)", func(t *testing.T) { | ||||
|  | ||||
| 		batchATCSystemConfigFileExpected := ` | ||||
| --request-separator | ||||
| Content-Type: multipart/mixed;boundary=changeset | ||||
|  | ||||
| --changeset | ||||
| Content-Type: application/http | ||||
| Content-Transfer-Encoding: binary | ||||
| Content-ID: 1 | ||||
|  | ||||
| PATCH configuration(root_id='1',conf_id=4711) HTTP/1.1 | ||||
| Content-Type: application/json | ||||
|  | ||||
| {"conf_name":"UNITTEST_PIPERSTEP","conf_id":"","checkvariant":"SAP_CLOUD_PLATFORM_ATC_DEFAULT","pseudo_comment_policy":"MK","block_findings":"0","inform_findings":"1","is_default":false,"is_proxy_variant":false} | ||||
|  | ||||
| --changeset-- | ||||
|  | ||||
| --request-separator--` | ||||
|  | ||||
| 		//no Configuration name supplied | ||||
| 		atcSystemConfigFileString := `{ | ||||
| 			"conf_name": "UNITTEST_PIPERSTEP", | ||||
| 			"checkvariant": "SAP_CLOUD_PLATFORM_ATC_DEFAULT", | ||||
| 			"pseudo_comment_policy": "MK", | ||||
| 			"block_findings": "0", | ||||
| 			"inform_findings": "1", | ||||
| 			"is_default": false, | ||||
| 			"is_proxy_variant": false | ||||
| 		} | ||||
| 		` | ||||
|  | ||||
| 		confUUID := "4711" | ||||
| 		batchATCSystemConfigFile, err := buildATCSystemConfigBatchRequest(confUUID, []byte(atcSystemConfigFileString)) | ||||
| 		if err != nil { | ||||
| 			t.Fatal("Failed to Build ATC System Config Batch") | ||||
| 		} | ||||
| 		assert.Equal(t, batchATCSystemConfigFileExpected, batchATCSystemConfigFile) | ||||
|  | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("success case: BuildATCSystemConfigBatch - Config Base only (empty expand _priorities)", func(t *testing.T) { | ||||
|  | ||||
| 		batchATCSystemConfigFileExpected := ` | ||||
| --request-separator | ||||
| Content-Type: multipart/mixed;boundary=changeset | ||||
|  | ||||
| --changeset | ||||
| Content-Type: application/http | ||||
| Content-Transfer-Encoding: binary | ||||
| Content-ID: 1 | ||||
|  | ||||
| PATCH configuration(root_id='1',conf_id=4711) HTTP/1.1 | ||||
| Content-Type: application/json | ||||
|  | ||||
| {"conf_name":"UNITTEST_PIPERSTEP","conf_id":"","checkvariant":"SAP_CLOUD_PLATFORM_ATC_DEFAULT","pseudo_comment_policy":"MK","block_findings":"0","inform_findings":"1","is_default":false,"is_proxy_variant":false} | ||||
|  | ||||
| --changeset-- | ||||
|  | ||||
| --request-separator--` | ||||
|  | ||||
| 		//no Configuration name supplied | ||||
| 		atcSystemConfigFileString := `{ | ||||
| 			"conf_name": "UNITTEST_PIPERSTEP", | ||||
| 			"checkvariant": "SAP_CLOUD_PLATFORM_ATC_DEFAULT", | ||||
| 			"pseudo_comment_policy": "MK", | ||||
| 			"block_findings": "0", | ||||
| 			"inform_findings": "1", | ||||
| 			"is_default": false, | ||||
| 			"is_proxy_variant": false, | ||||
| 			"_priorities": [ | ||||
| 			] | ||||
| 		} | ||||
| 		` | ||||
|  | ||||
| 		confUUID := "4711" | ||||
| 		batchATCSystemConfigFile, err := buildATCSystemConfigBatchRequest(confUUID, []byte(atcSystemConfigFileString)) | ||||
| 		if err != nil { | ||||
| 			t.Fatal("Failed to Build ATC System Config Batch") | ||||
| 		} | ||||
| 		assert.Equal(t, batchATCSystemConfigFileExpected, batchATCSystemConfigFile) | ||||
|  | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("failure case: BuildATCSystemConfigBatch", func(t *testing.T) { | ||||
|  | ||||
| 		batchATCSystemConfigFileExpected := `` | ||||
|  | ||||
| 		//no Configuration name supplied | ||||
| 		atcSystemConfigFileString := `{ | ||||
| 			"conf_name": "UNITTEST_PIPERSTEP", | ||||
| 			"checkvariant": "SAP_CLOUD_PLATFORM_ATC_DEFAULT", | ||||
| 			"pseudo_comment_policy": "MK", | ||||
| 			"block_findings": "0", | ||||
| 			"inform_findings": "1", | ||||
| 			"is_default": false, | ||||
| 			"is_proxy_variant": false, | ||||
| 			"_priorities": [ | ||||
| 				{ | ||||
| 					"test": "CL_CI_TEST_AMDP_HDB_MIGRATION", | ||||
| 					"message_id": "FAIL_ABAP", | ||||
| 					"default_priority": 3, | ||||
| 					"priority": 1 | ||||
| 				} | ||||
| 			] | ||||
| 		} | ||||
| 		` | ||||
|  | ||||
| 		confUUID := "4711" | ||||
| 		batchATCSystemConfigFile, err := buildATCSystemConfigBatchRequest(confUUID, []byte(atcSystemConfigFileString)) | ||||
| 		if err != nil { | ||||
| 			t.Fatal("Failed to Build ATC System Config Batch") | ||||
| 		} | ||||
| 		assert.NotEqual(t, batchATCSystemConfigFileExpected, batchATCSystemConfigFile) | ||||
|  | ||||
| 	}) | ||||
| } | ||||
| func TestRunAbapEnvironmentPushATCSystemConfig(t *testing.T) { | ||||
| 	t.Parallel() | ||||
|  | ||||
| 	t.Run("run Step Failure - ATC System Configuration File empty", 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" | ||||
|  | ||||
| 		receivedURI := "example.com/Entity" | ||||
| 		tokenExpected := "myToken" | ||||
|  | ||||
| 		client := &abaputils.ClientMock{ | ||||
| 			Body:       `{"d" : { "__metadata" : { "uri" : "` + receivedURI + `" } } }`, | ||||
| 			Token:      tokenExpected, | ||||
| 			StatusCode: 200, | ||||
| 		} | ||||
|  | ||||
| 		dir, err := ioutil.TempDir("", "test dir for test file with ATC System Configuration") | ||||
| 		if err != 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) | ||||
| 		}() | ||||
|  | ||||
| 		config := abapEnvironmentPushATCSystemConfigOptions{AtcSystemConfigFilePath: "atcSystemConfig.json"} | ||||
|  | ||||
| 		atcSystemConfigFileString := `` | ||||
|  | ||||
| 		err = ioutil.WriteFile(config.AtcSystemConfigFilePath, []byte(atcSystemConfigFileString), 0644) | ||||
| 		if err != nil { | ||||
| 			t.Fatal("Failed to write File: " + config.AtcSystemConfigFilePath) | ||||
| 		} | ||||
|  | ||||
| 		expectedErrorMessage := "pushing ATC System Configuration failed. Reason: Configured File is empty (File: " + config.AtcSystemConfigFilePath + ")" | ||||
|  | ||||
| 		err = runAbapEnvironmentPushATCSystemConfig(&config, nil, &autils, client) | ||||
| 		assert.Equal(t, expectedErrorMessage, err.Error(), "Different error message expected") | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("run Step Failure - ATC System Configuration invalid", 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" | ||||
|  | ||||
| 		receivedURI := "example.com/Entity" | ||||
| 		tokenExpected := "myToken" | ||||
|  | ||||
| 		client := &abaputils.ClientMock{ | ||||
| 			Body:       `{"d" : { "__metadata" : { "uri" : "` + receivedURI + `" } } }`, | ||||
| 			Token:      tokenExpected, | ||||
| 			StatusCode: 200, | ||||
| 		} | ||||
|  | ||||
| 		dir, err := ioutil.TempDir("", "test dir for test file with ATC System Configuration") | ||||
| 		if err != 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) | ||||
| 		}() | ||||
|  | ||||
| 		config := abapEnvironmentPushATCSystemConfigOptions{AtcSystemConfigFilePath: "atcSystemConfig.json"} | ||||
|  | ||||
| 		//no Configuration name supplied | ||||
| 		atcSystemConfigFileString := `{ | ||||
| 			"conf_name": "", | ||||
| 			"checkvariant": "SAP_CLOUD_PLATFORM_ATC_DEFAULT", | ||||
| 			"pseudo_comment_policy": "MK", | ||||
| 			"block_findings": "0", | ||||
| 			"inform_findings": "1", | ||||
| 			"is_default": false, | ||||
| 			"is_proxy_variant": false, | ||||
| 			"_priorities": [ | ||||
| 				{ | ||||
| 					"test": "CL_CI_TEST_AMDP_HDB_MIGRATION", | ||||
| 					"message_id": "FAIL_ABAP", | ||||
| 					"default_priority": 3, | ||||
| 					"priority": 1 | ||||
| 				} | ||||
| 			] | ||||
| 		} | ||||
| 		` | ||||
| 		err = ioutil.WriteFile(config.AtcSystemConfigFilePath, []byte(atcSystemConfigFileString), 0644) | ||||
| 		if err != nil { | ||||
| 			t.Fatal("Failed to write File: " + config.AtcSystemConfigFilePath) | ||||
| 		} | ||||
|  | ||||
| 		expectedErrorMessage := "pushing ATC System Configuration failed. Reason: Configured File does not contain required ATC System Configuration attributes (File: " + config.AtcSystemConfigFilePath + ")" | ||||
|  | ||||
| 		err = runAbapEnvironmentPushATCSystemConfig(&config, nil, &autils, client) | ||||
| 		assert.Equal(t, expectedErrorMessage, err.Error(), "Different error message expected") | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("run Step Successful - Push ATC System Configuration", 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" | ||||
|  | ||||
| 		receivedURI := "example.com/Entity" | ||||
| 		tokenExpected := "myToken" | ||||
|  | ||||
| 		client := &abaputils.ClientMock{ | ||||
| 			Body:       `{"d" : { "__metadata" : { "uri" : "` + receivedURI + `" } } }`, | ||||
| 			Token:      tokenExpected, | ||||
| 			StatusCode: 200, | ||||
| 		} | ||||
|  | ||||
| 		dir, err := ioutil.TempDir("", "test dir for test file with ATC System Configuration") | ||||
| 		if err != 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) | ||||
| 		}() | ||||
|  | ||||
| 		config := abapEnvironmentPushATCSystemConfigOptions{AtcSystemConfigFilePath: "atcSystemConfig.json"} | ||||
|  | ||||
| 		//valid ATC System Configuration File | ||||
| 		atcSystemConfigFileString := `{ | ||||
| 			"conf_name": "UNITTEST_PIPERSTEP", | ||||
| 			"checkvariant": "SAP_CLOUD_PLATFORM_ATC_DEFAULT", | ||||
| 			"pseudo_comment_policy": "MK", | ||||
| 			"block_findings": "0", | ||||
| 			"inform_findings": "1", | ||||
| 			"is_default": false, | ||||
| 			"is_proxy_variant": false, | ||||
| 			"_priorities": [ | ||||
| 				{ | ||||
| 					"test": "CL_SOMECLASS", | ||||
| 					"message_id": "SOME_MESSAGE_ID", | ||||
| 					"default_priority": 3, | ||||
| 					"priority": 1 | ||||
| 				} | ||||
| 			] | ||||
| 		} | ||||
| 		` | ||||
| 		err = ioutil.WriteFile(config.AtcSystemConfigFilePath, []byte(atcSystemConfigFileString), 0644) | ||||
| 		if err != nil { | ||||
| 			t.Fatal("Failed to write File: " + config.AtcSystemConfigFilePath) | ||||
| 		} | ||||
|  | ||||
| 		err = runAbapEnvironmentPushATCSystemConfig(&config, nil, &autils, client) | ||||
| 		assert.NoError(t, err, "No error expected") | ||||
| 	}) | ||||
|  | ||||
| 	t.Run("run Step Failure - ATC System Configuration File does not exist", 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" | ||||
|  | ||||
| 		receivedURI := "example.com/Entity" | ||||
| 		tokenExpected := "myToken" | ||||
|  | ||||
| 		client := &abaputils.ClientMock{ | ||||
| 			Body:       `{"d" : { "__metadata" : { "uri" : "` + receivedURI + `" } } }`, | ||||
| 			Token:      tokenExpected, | ||||
| 			StatusCode: 200, | ||||
| 		} | ||||
|  | ||||
| 		config := abapEnvironmentPushATCSystemConfigOptions{AtcSystemConfigFilePath: "test.json"} | ||||
|  | ||||
| 		expectedErrorMessage := "pushing ATC System Configuration failed. Reason: Configured Filelocation is empty (File: " + config.AtcSystemConfigFilePath + ")" | ||||
|  | ||||
| 		err := runAbapEnvironmentPushATCSystemConfig(&config, nil, &autils, client) | ||||
| 		assert.Equal(t, expectedErrorMessage, err.Error(), "Different error message expected") | ||||
| 	}) | ||||
| } | ||||
| @@ -21,6 +21,7 @@ func GetAllStepMetadata() map[string]config.StepData { | ||||
| 		"abapEnvironmentCloneGitRepo":               abapEnvironmentCloneGitRepoMetadata(), | ||||
| 		"abapEnvironmentCreateSystem":               abapEnvironmentCreateSystemMetadata(), | ||||
| 		"abapEnvironmentPullGitRepo":                abapEnvironmentPullGitRepoMetadata(), | ||||
| 		"abapEnvironmentPushATCSystemConfig":        abapEnvironmentPushATCSystemConfigMetadata(), | ||||
| 		"abapEnvironmentRunATCCheck":                abapEnvironmentRunATCCheckMetadata(), | ||||
| 		"abapEnvironmentRunAUnitTest":               abapEnvironmentRunAUnitTestMetadata(), | ||||
| 		"apiKeyValueMapDownload":                    apiKeyValueMapDownloadMetadata(), | ||||
|   | ||||
| @@ -118,6 +118,7 @@ func Execute() { | ||||
| 	rootCmd.AddCommand(MavenExecuteIntegrationCommand()) | ||||
| 	rootCmd.AddCommand(MavenExecuteStaticCodeChecksCommand()) | ||||
| 	rootCmd.AddCommand(NexusUploadCommand()) | ||||
| 	rootCmd.AddCommand(AbapEnvironmentPushATCSystemConfigCommand()) | ||||
| 	rootCmd.AddCommand(AbapEnvironmentRunATCCheckCommand()) | ||||
| 	rootCmd.AddCommand(NpmExecuteScriptsCommand()) | ||||
| 	rootCmd.AddCommand(NpmExecuteLintCommand()) | ||||
|   | ||||
							
								
								
									
										132
									
								
								resources/metadata/abapEnvironmentPushATCSystemConfig.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								resources/metadata/abapEnvironmentPushATCSystemConfig.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,132 @@ | ||||
| metadata: | ||||
|   name: abapEnvironmentPushATCSystemConfig | ||||
|   description: Create/Update ATC System Configuration | ||||
|   longDescription: | | ||||
|     This step is for creating/updating an [ATC](https://help.sap.com/products/BTP/65de2977205c403bbc107264b8eccf4b/657285a09f7148d894c27bb8e17827cf.html?version=Cloud) system configurationon on an SAP BTP, ABAP Environment system. | ||||
|     Please provide either of the following options: | ||||
|  | ||||
|     * The host and credentials the SAP BTP, ABAP Environment system itself. The credentials must be configured for the Communication Scenario [SAP_COM_0763] (https://help.sap.com/products/BTP/65de2977205c403bbc107264b8eccf4b/657285a09f7148d894c27bb8e17827cf.html?version=Cloud). | ||||
|     * 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_0763. | ||||
|     * 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 | ||||
|         aliases: | ||||
|           - name: cfCredentialsId | ||||
|         description: Jenkins credentials ID containing user and password to authenticate to the SAP BTP, ABAP Environment system or the Cloud Foundry API | ||||
|         type: jenkins | ||||
|     params: | ||||
|       - name: atcSystemConfigFilePath | ||||
|         type: string | ||||
|         description: Path to a JSON file with ATC System Configuration | ||||
|         scope: | ||||
|           - PARAMETERS | ||||
|           - STAGES | ||||
|           - STEPS | ||||
|         mandatory: true | ||||
|       - name: patchIfExisting | ||||
|         type: bool | ||||
|         description: In case an configuration under the given name already exists in the system. Should the step update/patch the existing ATC Systm Configuration from the provided ATC System Configuration file? | ||||
|         scope: | ||||
|           - PARAMETERS | ||||
|           - STAGES | ||||
|           - STEPS | ||||
|         default: true | ||||
|       - name: cfApiEndpoint | ||||
|         type: string | ||||
|         description: Cloud Foundry API endpoint | ||||
|         scope: | ||||
|           - PARAMETERS | ||||
|           - STAGES | ||||
|           - STEPS | ||||
|           - GENERAL | ||||
|         mandatory: false | ||||
|         aliases: | ||||
|           - name: cloudFoundry/apiEndpoint | ||||
|       - name: cfOrg | ||||
|         type: string | ||||
|         description: CF org | ||||
|         scope: | ||||
|           - PARAMETERS | ||||
|           - STAGES | ||||
|           - STEPS | ||||
|           - GENERAL | ||||
|         mandatory: false | ||||
|         aliases: | ||||
|           - name: cloudFoundry/org | ||||
|       - name: cfServiceInstance | ||||
|         type: string | ||||
|         description: Parameter of ServiceInstance Name to delete CloudFoundry Service | ||||
|         scope: | ||||
|           - PARAMETERS | ||||
|           - STAGES | ||||
|           - STEPS | ||||
|           - GENERAL | ||||
|         mandatory: false | ||||
|         aliases: | ||||
|           - name: cloudFoundry/serviceInstance | ||||
|       - name: cfServiceKeyName | ||||
|         type: string | ||||
|         description: Parameter of CloudFoundry Service Key to be created | ||||
|         scope: | ||||
|           - PARAMETERS | ||||
|           - STAGES | ||||
|           - STEPS | ||||
|           - GENERAL | ||||
|         mandatory: false | ||||
|         aliases: | ||||
|           - name: cloudFoundry/serviceKey | ||||
|           - name: cloudFoundry/serviceKeyName | ||||
|           - name: cfServiceKey | ||||
|       - name: cfSpace | ||||
|         type: string | ||||
|         description: CF Space | ||||
|         scope: | ||||
|           - PARAMETERS | ||||
|           - STAGES | ||||
|           - STEPS | ||||
|           - GENERAL | ||||
|         mandatory: false | ||||
|         aliases: | ||||
|           - name: cloudFoundry/space | ||||
|       - name: username | ||||
|         type: string | ||||
|         description: User for either the Cloud Foundry API or the Communication Arrangement for SAP_COM_0763 | ||||
|         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_0763 | ||||
|         scope: | ||||
|           - PARAMETERS | ||||
|           - STAGES | ||||
|           - STEPS | ||||
|         mandatory: true | ||||
|         secret: true | ||||
|         resourceRef: | ||||
|           - name: abapCredentialsId | ||||
|             type: secret | ||||
|             param: password | ||||
|       - name: host | ||||
|         type: string | ||||
|         description: Specifies the host address of the SAP SAP BTP, ABAP Environment system | ||||
|         scope: | ||||
|           - PARAMETERS | ||||
|           - STAGES | ||||
|           - STEPS | ||||
|           - GENERAL | ||||
|         mandatory: false | ||||
|  | ||||
|   containers: | ||||
|     - name: cf | ||||
|       image: ppiper/cf-cli:7 | ||||
		Reference in New Issue
	
	Block a user