From de6c002be443f01e7896fbc2a3ac66726e1e6b19 Mon Sep 17 00:00:00 2001 From: Akramdzhon Azamov <MY_NAME@example.com> Date: Thu, 21 Sep 2023 00:00:35 +0500 Subject: [PATCH 1/8] added logic of fetching golang private packages for whitesource step and detectExecuteScan step --- cmd/detectExecuteScan.go | 8 +++++ cmd/detectExecuteScan_generated.go | 36 +++++++++++++++++++ cmd/golangBuild_generated.go | 2 +- cmd/utils.go | 24 +++++++++++++ cmd/whitesourceExecuteScan.go | 7 ++++ cmd/whitesourceExecuteScan_generated.go | 36 +++++++++++++++++++ resources/metadata/detectExecuteScan.yaml | 29 +++++++++++++++ resources/metadata/golangBuild.yaml | 1 + .../metadata/whitesourceExecuteScan.yaml | 29 +++++++++++++++ vars/detectExecuteScan.groovy | 3 +- vars/whitesourceExecuteScan.groovy | 1 + 11 files changed, 174 insertions(+), 2 deletions(-) diff --git a/cmd/detectExecuteScan.go b/cmd/detectExecuteScan.go index 5527b28ed8..7e62549ab9 100644 --- a/cmd/detectExecuteScan.go +++ b/cmd/detectExecuteScan.go @@ -138,6 +138,14 @@ func detectExecuteScan(config detectExecuteScanOptions, _ *telemetry.CustomData, if err != nil { log.Entry().WithError(err).Warning("Failed to get GitHub client") } + + if config.BuildTool == golangBuildTool { + //configuring go private packages + if err := prepareGolangPrivatePackages(config.PrivateModules, config.PrivateModulesGitToken); err != nil { + log.Entry().Warningf("couldn't set private packages for golang, error: %s", err.Error()) + } + } + utils := newDetectUtils(client) if err := runDetect(ctx, config, utils, influx); err != nil { log.Entry(). diff --git a/cmd/detectExecuteScan_generated.go b/cmd/detectExecuteScan_generated.go index f4cb28a62f..2b4a424cff 100644 --- a/cmd/detectExecuteScan_generated.go +++ b/cmd/detectExecuteScan_generated.go @@ -62,6 +62,8 @@ type detectExecuteScanOptions struct { ExcludedDirectories []string `json:"excludedDirectories,omitempty"` NpmDependencyTypesExcluded []string `json:"npmDependencyTypesExcluded,omitempty" validate:"possible-values=NONE DEV PEER"` NpmArguments []string `json:"npmArguments,omitempty"` + PrivateModules string `json:"privateModules,omitempty"` + PrivateModulesGitToken string `json:"privateModulesGitToken,omitempty"` } type detectExecuteScanInflux struct { @@ -195,6 +197,7 @@ Please configure your BlackDuck server Url using the serverUrl parameter and the } log.RegisterSecret(stepConfig.Token) log.RegisterSecret(stepConfig.GithubToken) + log.RegisterSecret(stepConfig.PrivateModulesGitToken) if len(GeneralConfig.HookConfig.SentryConfig.Dsn) > 0 { sentryHook := log.NewSentryHook(GeneralConfig.HookConfig.SentryConfig.Dsn, GeneralConfig.CorrelationID) @@ -305,6 +308,8 @@ func addDetectExecuteScanFlags(cmd *cobra.Command, stepConfig *detectExecuteScan cmd.Flags().StringSliceVar(&stepConfig.ExcludedDirectories, "excludedDirectories", []string{}, "List of directories which should be excluded from the scan.") cmd.Flags().StringSliceVar(&stepConfig.NpmDependencyTypesExcluded, "npmDependencyTypesExcluded", []string{}, "List of npm dependency types which Detect should exclude from the BOM.") cmd.Flags().StringSliceVar(&stepConfig.NpmArguments, "npmArguments", []string{}, "List of additional arguments that Detect will add at then end of the npm ls command line when Detect executes the NPM CLI Detector on an NPM project.") + cmd.Flags().StringVar(&stepConfig.PrivateModules, "privateModules", os.Getenv("PIPER_privateModules"), "Tells go which modules shall be considered to be private (by setting [GOPRIVATE](https://pkg.go.dev/cmd/go#hdr-Configuration_for_downloading_non_public_code)).") + cmd.Flags().StringVar(&stepConfig.PrivateModulesGitToken, "privateModulesGitToken", os.Getenv("PIPER_privateModulesGitToken"), "GitHub personal access token as per https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line.") cmd.MarkFlagRequired("token") cmd.MarkFlagRequired("projectName") @@ -324,6 +329,7 @@ func detectExecuteScanMetadata() config.StepData { Secrets: []config.StepSecrets{ {Name: "detectTokenCredentialsId", Description: "Jenkins 'Secret text' credentials ID containing the API token used to authenticate with the Synopsis Detect (formerly BlackDuck) Server.", Type: "jenkins", Aliases: []config.Alias{{Name: "apiTokenCredentialsId", Deprecated: false}}}, {Name: "githubTokenCredentialsId", Description: "Jenkins 'Secret text' credentials ID containing token to authenticate to GitHub.", Type: "jenkins"}, + {Name: "golangPrivateModulesGitTokenCredentialsId", Description: "Jenkins 'Username with password' credentials ID containing username/password for http access to your git repos where your go private modules are stored.", Type: "jenkins"}, }, Resources: []config.StepResources{ {Name: "buildDescriptor", Type: "stash"}, @@ -737,6 +743,36 @@ func detectExecuteScanMetadata() config.StepData { Aliases: []config.Alias{{Name: "detect/npmArguments"}}, Default: []string{}, }, + { + Name: "privateModules", + ResourceRef: []config.ResourceReference{}, + Scope: []string{"GENERAL", "STEPS", "STAGES", "PARAMETERS"}, + Type: "string", + Mandatory: false, + Aliases: []config.Alias{}, + Default: os.Getenv("PIPER_privateModules"), + }, + { + Name: "privateModulesGitToken", + ResourceRef: []config.ResourceReference{ + { + Name: "golangPrivateModulesGitTokenCredentialsId", + Param: "password", + Type: "secret", + }, + + { + Name: "golangPrivateModulesGitTokenVaultSecret", + Type: "vaultSecret", + Default: "golang", + }, + }, + Scope: []string{"GENERAL", "PARAMETERS", "STAGES", "STEPS"}, + Type: "string", + Mandatory: false, + Aliases: []config.Alias{}, + Default: os.Getenv("PIPER_privateModulesGitToken"), + }, }, }, Containers: []config.Container{ diff --git a/cmd/golangBuild_generated.go b/cmd/golangBuild_generated.go index 676a0539ea..6ef805e447 100644 --- a/cmd/golangBuild_generated.go +++ b/cmd/golangBuild_generated.go @@ -498,7 +498,7 @@ func golangBuildMetadata() config.StepData { { Name: "privateModules", ResourceRef: []config.ResourceReference{}, - Scope: []string{"STEPS", "STAGES", "PARAMETERS"}, + Scope: []string{"GENERAL", "STEPS", "STAGES", "PARAMETERS"}, Type: "string", Mandatory: false, Aliases: []config.Alias{}, diff --git a/cmd/utils.go b/cmd/utils.go index 685b043bd7..9c148e1f08 100644 --- a/cmd/utils.go +++ b/cmd/utils.go @@ -12,3 +12,27 @@ func fileExists(filename string) bool { } return !info.IsDir() } + +const golangBuildTool = "golang" + +// prepare golang private packages for whitesource and blackduck(detectExecuteScan) +func prepareGolangPrivatePackages(privateModules, privateModulesGitToken string) error { + + goConfig := golangBuildOptions{ + PrivateModules: privateModules, + PrivateModulesGitToken: privateModulesGitToken, + } // only these parameters are enough to configure + + utils := newGolangBuildUtils(goConfig) + + goModFile, err := readGoModFile(utils) // returns nil if go.mod doesnt exist + if err != nil { + return err + } + + if err = prepareGolangEnvironment(&goConfig, goModFile, utils); err != nil { + return err + } + + return nil +} diff --git a/cmd/whitesourceExecuteScan.go b/cmd/whitesourceExecuteScan.go index 11b1c42051..9169dd34e1 100644 --- a/cmd/whitesourceExecuteScan.go +++ b/cmd/whitesourceExecuteScan.go @@ -157,6 +157,13 @@ func whitesourceExecuteScan(config ScanOptions, _ *telemetry.CustomData, commonP } func runWhitesourceExecuteScan(ctx context.Context, config *ScanOptions, scan *ws.Scan, utils whitesourceUtils, sys whitesource, commonPipelineEnvironment *whitesourceExecuteScanCommonPipelineEnvironment, influx *whitesourceExecuteScanInflux) error { + if config.BuildTool == golangBuildTool && config != nil { + //configuring go private packages + if err := prepareGolangPrivatePackages(config.PrivateModules, config.PrivateModulesGitToken); err != nil { + log.Entry().Warningf("couldn't set private packages for golang, error: %s", err.Error()) + } + } + if err := resolveAggregateProjectName(config, scan, sys); err != nil { return errors.Wrapf(err, "failed to resolve and aggregate project name") } diff --git a/cmd/whitesourceExecuteScan_generated.go b/cmd/whitesourceExecuteScan_generated.go index 673f7ee6d0..cf8a78700c 100644 --- a/cmd/whitesourceExecuteScan_generated.go +++ b/cmd/whitesourceExecuteScan_generated.go @@ -74,6 +74,8 @@ type whitesourceExecuteScanOptions struct { Repository string `json:"repository,omitempty"` Assignees []string `json:"assignees,omitempty"` CustomTLSCertificateLinks []string `json:"customTlsCertificateLinks,omitempty"` + PrivateModules string `json:"privateModules,omitempty"` + PrivateModulesGitToken string `json:"privateModulesGitToken,omitempty"` } type whitesourceExecuteScanCommonPipelineEnvironment struct { @@ -243,6 +245,7 @@ The step uses the so-called Mend Unified Agent. For details please refer to the log.RegisterSecret(stepConfig.OrgToken) log.RegisterSecret(stepConfig.UserToken) log.RegisterSecret(stepConfig.GithubToken) + log.RegisterSecret(stepConfig.PrivateModulesGitToken) if len(GeneralConfig.HookConfig.SentryConfig.Dsn) > 0 { sentryHook := log.NewSentryHook(GeneralConfig.HookConfig.SentryConfig.Dsn, GeneralConfig.CorrelationID) @@ -366,6 +369,8 @@ func addWhitesourceExecuteScanFlags(cmd *cobra.Command, stepConfig *whitesourceE cmd.Flags().StringVar(&stepConfig.Repository, "repository", os.Getenv("PIPER_repository"), "Set the GitHub repository.") cmd.Flags().StringSliceVar(&stepConfig.Assignees, "assignees", []string{``}, "Defines the assignees for the Github Issue created/updated with the results of the scan as a list of login names.") cmd.Flags().StringSliceVar(&stepConfig.CustomTLSCertificateLinks, "customTlsCertificateLinks", []string{}, "List of download links to custom TLS certificates. This is required to ensure trusted connections to instances with repositories (like nexus) when publish flag is set to true.") + cmd.Flags().StringVar(&stepConfig.PrivateModules, "privateModules", os.Getenv("PIPER_privateModules"), "Tells go which modules shall be considered to be private (by setting [GOPRIVATE](https://pkg.go.dev/cmd/go#hdr-Configuration_for_downloading_non_public_code)).") + cmd.Flags().StringVar(&stepConfig.PrivateModulesGitToken, "privateModulesGitToken", os.Getenv("PIPER_privateModulesGitToken"), "GitHub personal access token as per https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line.") cmd.MarkFlagRequired("buildTool") cmd.MarkFlagRequired("orgToken") @@ -387,6 +392,7 @@ func whitesourceExecuteScanMetadata() config.StepData { {Name: "orgAdminUserTokenCredentialsId", Description: "Jenkins 'Secret text' credentials ID containing Whitesource org admin token.", Type: "jenkins", Aliases: []config.Alias{{Name: "whitesourceOrgAdminUserTokenCredentialsId", Deprecated: false}, {Name: "whitesource/orgAdminUserTokenCredentialsId", Deprecated: true}}}, {Name: "dockerConfigJsonCredentialsId", Description: "Jenkins 'Secret file' credentials ID containing Docker config.json (with registry credential(s)). You can find more details about the Docker credentials in the [Docker documentation](https://docs.docker.com/engine/reference/commandline/login/).", Type: "jenkins", Aliases: []config.Alias{{Name: "dockerCredentialsId", Deprecated: true}}}, {Name: "githubTokenCredentialsId", Description: "Jenkins 'Secret text' credentials ID containing token to authenticate to GitHub.", Type: "jenkins"}, + {Name: "golangPrivateModulesGitTokenCredentialsId", Description: "Jenkins 'Username with password' credentials ID containing username/password for http access to your git repos where your go private modules are stored.", Type: "jenkins"}, }, Resources: []config.StepResources{ {Name: "buildDescriptor", Type: "stash"}, @@ -967,6 +973,36 @@ func whitesourceExecuteScanMetadata() config.StepData { Aliases: []config.Alias{}, Default: []string{}, }, + { + Name: "privateModules", + ResourceRef: []config.ResourceReference{}, + Scope: []string{"GENERAL", "STEPS", "STAGES", "PARAMETERS"}, + Type: "string", + Mandatory: false, + Aliases: []config.Alias{}, + Default: os.Getenv("PIPER_privateModules"), + }, + { + Name: "privateModulesGitToken", + ResourceRef: []config.ResourceReference{ + { + Name: "golangPrivateModulesGitTokenCredentialsId", + Param: "password", + Type: "secret", + }, + + { + Name: "golangPrivateModulesGitTokenVaultSecret", + Type: "vaultSecret", + Default: "golang", + }, + }, + Scope: []string{"GENERAL", "PARAMETERS", "STAGES", "STEPS"}, + Type: "string", + Mandatory: false, + Aliases: []config.Alias{}, + Default: os.Getenv("PIPER_privateModulesGitToken"), + }, }, }, Containers: []config.Container{ diff --git a/resources/metadata/detectExecuteScan.yaml b/resources/metadata/detectExecuteScan.yaml index 35c10a9f90..06cd929967 100644 --- a/resources/metadata/detectExecuteScan.yaml +++ b/resources/metadata/detectExecuteScan.yaml @@ -21,6 +21,9 @@ spec: - name: githubTokenCredentialsId description: Jenkins 'Secret text' credentials ID containing token to authenticate to GitHub. type: jenkins + - name: golangPrivateModulesGitTokenCredentialsId + description: Jenkins 'Username with password' credentials ID containing username/password for http access to your git repos where your go private modules are stored. + type: jenkins params: - name: token aliases: @@ -489,6 +492,32 @@ spec: - PARAMETERS - STAGES - STEPS + - name: privateModules + type: "string" + description: Tells go which modules shall be considered to be private (by setting [GOPRIVATE](https://pkg.go.dev/cmd/go#hdr-Configuration_for_downloading_non_public_code)). + scope: + - GENERAL + - STEPS + - STAGES + - PARAMETERS + alias: + - goprivate + - name: privateModulesGitToken + description: GitHub personal access token as per https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line. + scope: + - GENERAL + - PARAMETERS + - STAGES + - STEPS + type: string + secret: true + resourceRef: + - name: golangPrivateModulesGitTokenCredentialsId + type: secret + param: password + - type: vaultSecret + name: golangPrivateModulesGitTokenVaultSecret + default: golang outputs: resources: - name: influx diff --git a/resources/metadata/golangBuild.yaml b/resources/metadata/golangBuild.yaml index 58bedb1f8f..6eb6ebe1c1 100644 --- a/resources/metadata/golangBuild.yaml +++ b/resources/metadata/golangBuild.yaml @@ -209,6 +209,7 @@ spec: type: "string" description: Tells go which modules shall be considered to be private (by setting [GOPRIVATE](https://pkg.go.dev/cmd/go#hdr-Configuration_for_downloading_non_public_code)). scope: + - GENERAL - STEPS - STAGES - PARAMETERS diff --git a/resources/metadata/whitesourceExecuteScan.yaml b/resources/metadata/whitesourceExecuteScan.yaml index 1b450e3ffa..2be99d7ecb 100644 --- a/resources/metadata/whitesourceExecuteScan.yaml +++ b/resources/metadata/whitesourceExecuteScan.yaml @@ -38,6 +38,9 @@ spec: - name: githubTokenCredentialsId description: Jenkins 'Secret text' credentials ID containing token to authenticate to GitHub. type: jenkins + - name: golangPrivateModulesGitTokenCredentialsId + description: Jenkins 'Username with password' credentials ID containing username/password for http access to your git repos where your go private modules are stored. + type: jenkins params: - name: agentDownloadUrl type: string @@ -597,6 +600,32 @@ spec: - PARAMETERS - STAGES - STEPS + - name: privateModules + type: "string" + description: Tells go which modules shall be considered to be private (by setting [GOPRIVATE](https://pkg.go.dev/cmd/go#hdr-Configuration_for_downloading_non_public_code)). + scope: + - GENERAL + - STEPS + - STAGES + - PARAMETERS + alias: + - goprivate + - name: privateModulesGitToken + description: GitHub personal access token as per https://help.github.com/en/github/authenticating-to-github/creating-a-personal-access-token-for-the-command-line. + scope: + - GENERAL + - PARAMETERS + - STAGES + - STEPS + type: string + secret: true + resourceRef: + - name: golangPrivateModulesGitTokenCredentialsId + type: secret + param: password + - type: vaultSecret + name: golangPrivateModulesGitTokenVaultSecret + default: golang resources: - name: buildDescriptor type: stash diff --git a/vars/detectExecuteScan.groovy b/vars/detectExecuteScan.groovy index 6587c18ba7..3bb58fb3d4 100644 --- a/vars/detectExecuteScan.groovy +++ b/vars/detectExecuteScan.groovy @@ -12,7 +12,8 @@ void call(Map parameters = [:]) { parameters = DownloadCacheUtils.injectDownloadCacheInParameters(script, parameters, BuildTool.MAVEN) List credentials = [ [type: 'token', id: 'detectTokenCredentialsId', env: ['PIPER_token']], - [type: 'token', id: 'githubTokenCredentialsId', env: ['PIPER_githubToken']] + [type: 'token', id: 'githubTokenCredentialsId', env: ['PIPER_githubToken']], + [type: 'usernamePassword', id: 'golangPrivateModulesGitTokenCredentialsId', env: ['PIPER_privateModulesGitUsername', 'PIPER_privateModulesGitToken']] ] piperExecuteBin(parameters, STEP_NAME, METADATA_FILE, credentials) } diff --git a/vars/whitesourceExecuteScan.groovy b/vars/whitesourceExecuteScan.groovy index 818c4004a6..36cf2321ba 100644 --- a/vars/whitesourceExecuteScan.groovy +++ b/vars/whitesourceExecuteScan.groovy @@ -18,6 +18,7 @@ void call(Map parameters = [:]) { [type: 'token', id: 'userTokenCredentialsId', env: ['PIPER_userToken']], [type: 'token', id: 'githubTokenCredentialsId', env: ['PIPER_githubToken']], [type: 'file', id: 'dockerConfigJsonCredentialsId', env: ['PIPER_dockerConfigJSON']], + [type: 'usernamePassword', id: 'golangPrivateModulesGitTokenCredentialsId', env: ['PIPER_privateModulesGitUsername', 'PIPER_privateModulesGitToken']] ] piperExecuteBin(parameters, STEP_NAME, METADATA_FILE, credentials) } From 3787de677961de4ed4e54d92b88dc4c78bc7ee0e Mon Sep 17 00:00:00 2001 From: akram8008 <900658008.akram@gmail.com> Date: Wed, 4 Oct 2023 12:47:50 +0500 Subject: [PATCH 2/8] changed logic of checking by config.PrivateModulesGitToken --- cmd/detectExecuteScan.go | 2 +- cmd/utils.go | 2 -- cmd/whitesourceExecuteScan.go | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/cmd/detectExecuteScan.go b/cmd/detectExecuteScan.go index 7e62549ab9..6eb858e052 100644 --- a/cmd/detectExecuteScan.go +++ b/cmd/detectExecuteScan.go @@ -139,7 +139,7 @@ func detectExecuteScan(config detectExecuteScanOptions, _ *telemetry.CustomData, log.Entry().WithError(err).Warning("Failed to get GitHub client") } - if config.BuildTool == golangBuildTool { + if config.PrivateModulesGitToken != "" { //configuring go private packages if err := prepareGolangPrivatePackages(config.PrivateModules, config.PrivateModulesGitToken); err != nil { log.Entry().Warningf("couldn't set private packages for golang, error: %s", err.Error()) diff --git a/cmd/utils.go b/cmd/utils.go index 9c148e1f08..b81a7b3d44 100644 --- a/cmd/utils.go +++ b/cmd/utils.go @@ -13,8 +13,6 @@ func fileExists(filename string) bool { return !info.IsDir() } -const golangBuildTool = "golang" - // prepare golang private packages for whitesource and blackduck(detectExecuteScan) func prepareGolangPrivatePackages(privateModules, privateModulesGitToken string) error { diff --git a/cmd/whitesourceExecuteScan.go b/cmd/whitesourceExecuteScan.go index 9169dd34e1..65f7f68b0f 100644 --- a/cmd/whitesourceExecuteScan.go +++ b/cmd/whitesourceExecuteScan.go @@ -157,7 +157,7 @@ func whitesourceExecuteScan(config ScanOptions, _ *telemetry.CustomData, commonP } func runWhitesourceExecuteScan(ctx context.Context, config *ScanOptions, scan *ws.Scan, utils whitesourceUtils, sys whitesource, commonPipelineEnvironment *whitesourceExecuteScanCommonPipelineEnvironment, influx *whitesourceExecuteScanInflux) error { - if config.BuildTool == golangBuildTool && config != nil { + if config != nil && config.PrivateModulesGitToken != "" { //configuring go private packages if err := prepareGolangPrivatePackages(config.PrivateModules, config.PrivateModulesGitToken); err != nil { log.Entry().Warningf("couldn't set private packages for golang, error: %s", err.Error()) From e3045d1fc5f53eb3fa007c11ebd92ab0a9587a5a Mon Sep 17 00:00:00 2001 From: akram8008 <900658008.akram@gmail.com> Date: Thu, 5 Oct 2023 13:57:21 +0500 Subject: [PATCH 3/8] moved func prepareGolangPrivatePackages to golangBuild.go --- cmd/golangBuild.go | 22 ++++++++++++++++++++++ cmd/utils.go | 22 ---------------------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/cmd/golangBuild.go b/cmd/golangBuild.go index 8d3cf68783..22fec60ca2 100644 --- a/cmd/golangBuild.go +++ b/cmd/golangBuild.go @@ -600,3 +600,25 @@ func gitConfigurationForPrivateModules(privateMod string, token string, utils go return nil } + +// prepare golang private packages for whitesource and blackduck(detectExecuteScan) +func prepareGolangPrivatePackages(privateModules, privateModulesGitToken string) error { + + goConfig := golangBuildOptions{ + PrivateModules: privateModules, + PrivateModulesGitToken: privateModulesGitToken, + } // only these parameters are enough to configure + + utils := newGolangBuildUtils(goConfig) + + goModFile, err := readGoModFile(utils) // returns nil if go.mod doesnt exist + if err != nil { + return err + } + + if err = prepareGolangEnvironment(&goConfig, goModFile, utils); err != nil { + return err + } + + return nil +} diff --git a/cmd/utils.go b/cmd/utils.go index b81a7b3d44..685b043bd7 100644 --- a/cmd/utils.go +++ b/cmd/utils.go @@ -12,25 +12,3 @@ func fileExists(filename string) bool { } return !info.IsDir() } - -// prepare golang private packages for whitesource and blackduck(detectExecuteScan) -func prepareGolangPrivatePackages(privateModules, privateModulesGitToken string) error { - - goConfig := golangBuildOptions{ - PrivateModules: privateModules, - PrivateModulesGitToken: privateModulesGitToken, - } // only these parameters are enough to configure - - utils := newGolangBuildUtils(goConfig) - - goModFile, err := readGoModFile(utils) // returns nil if go.mod doesnt exist - if err != nil { - return err - } - - if err = prepareGolangEnvironment(&goConfig, goModFile, utils); err != nil { - return err - } - - return nil -} From aa09f5b5d3cf85af647ec11da4cb34e275094379 Mon Sep 17 00:00:00 2001 From: Anil Keshav <anil.keshav@sap.com> Date: Thu, 28 Sep 2023 11:31:51 +0200 Subject: [PATCH 4/8] fix (gitOpsUpdateDeployment) add CA bundle options to plain clone and commit to trust enterprise github instances (#4602) * downloading ca cert bundle when added as config * adding logging statements * allowing bats test to handle ca cert * adding info message * hard coding file names * including correct http client util bundle * removing logging message not needed * adding cert bundle to commit and push * improving the condition to add ca cert in commit and push * fixing unit test * fixing unit test * fixing unit test * fixing unit test * fixing unit test --- cmd/batsExecuteTests.go | 4 +- cmd/gitopsUpdateDeployment.go | 90 +++++++++++++++---- cmd/gitopsUpdateDeployment_generated.go | 39 +++++--- cmd/gitopsUpdateDeployment_test.go | 12 ++- pkg/git/git.go | 24 +++-- pkg/git/git_test.go | 8 +- .../metadata/gitopsUpdateDeployment.yaml | 7 ++ 7 files changed, 138 insertions(+), 46 deletions(-) diff --git a/cmd/batsExecuteTests.go b/cmd/batsExecuteTests.go index 6bd28f704f..aa4251ebfa 100644 --- a/cmd/batsExecuteTests.go +++ b/cmd/batsExecuteTests.go @@ -108,7 +108,9 @@ func runBatsExecuteTests(config *batsExecuteTestsOptions, telemetryData *telemet } func (b *batsExecuteTestsUtilsBundle) CloneRepo(URL string) error { - _, err := pipergit.PlainClone("", "", URL, "bats-core") + // ToDo: BatsExecute test needs to check if the repo can come from a + // enterprise github instance and needs ca-cert handelling seperately + _, err := pipergit.PlainClone("", "", URL, "bats-core", []byte{}) return err } diff --git a/cmd/gitopsUpdateDeployment.go b/cmd/gitopsUpdateDeployment.go index 6695019418..7220025de8 100644 --- a/cmd/gitopsUpdateDeployment.go +++ b/cmd/gitopsUpdateDeployment.go @@ -3,9 +3,19 @@ package cmd import ( "bytes" "fmt" + "io" + "net/http" + "os" + "path" + "path/filepath" + "regexp" + "strings" + "time" + "github.com/SAP/jenkins-library/pkg/command" "github.com/SAP/jenkins-library/pkg/docker" gitUtil "github.com/SAP/jenkins-library/pkg/git" + piperhttp "github.com/SAP/jenkins-library/pkg/http" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/piperutils" "github.com/SAP/jenkins-library/pkg/telemetry" @@ -13,12 +23,6 @@ import ( "github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/plumbing/object" "github.com/pkg/errors" - "io" - "os" - "path/filepath" - "regexp" - "strings" - "time" ) const toolKubectl = "kubectl" @@ -27,8 +31,8 @@ const toolKustomize = "kustomize" type iGitopsUpdateDeploymentGitUtils interface { CommitFiles(filePaths []string, commitMessage, author string) (plumbing.Hash, error) - PushChangesToRepository(username, password string, force *bool) error - PlainClone(username, password, serverURL, directory string) error + PushChangesToRepository(username, password string, force *bool, caCerts []byte) error + PlainClone(username, password, serverURL, directory string, caCerts []byte) error ChangeBranch(branchName string) error } @@ -36,6 +40,7 @@ type gitopsUpdateDeploymentFileUtils interface { TempDir(dir, pattern string) (name string, err error) RemoveAll(path string) error FileWrite(path string, content []byte, perm os.FileMode) error + FileRead(path string) ([]byte, error) Glob(pattern string) ([]string, error) } @@ -51,6 +56,25 @@ type gitopsUpdateDeploymentGitUtils struct { repository *git.Repository } +type gitopsUpdateDeploymentUtilsBundle struct { + *piperhttp.Client +} + +type gitopsUpdateDeploymentUtils interface { + DownloadFile(url, filename string, header http.Header, cookies []*http.Cookie) error +} + +func newGitopsUpdateDeploymentUtilsBundle() gitopsUpdateDeploymentUtils { + utils := gitopsUpdateDeploymentUtilsBundle{ + Client: &piperhttp.Client{}, + } + return &utils +} + +func (g *gitopsUpdateDeploymentUtilsBundle) DownloadFile(url, filename string, header http.Header, cookies []*http.Cookie) error { + return g.Client.DownloadFile(url, filename, header, cookies) +} + func (g *gitopsUpdateDeploymentGitUtils) CommitFiles(filePaths []string, commitMessage, author string) (plumbing.Hash, error) { for _, path := range filePaths { _, err := g.worktree.Add(path) @@ -71,13 +95,13 @@ func (g *gitopsUpdateDeploymentGitUtils) CommitFiles(filePaths []string, commitM return commit, nil } -func (g *gitopsUpdateDeploymentGitUtils) PushChangesToRepository(username, password string, force *bool) error { - return gitUtil.PushChangesToRepository(username, password, force, g.repository) +func (g *gitopsUpdateDeploymentGitUtils) PushChangesToRepository(username, password string, force *bool, caCerts []byte) error { + return gitUtil.PushChangesToRepository(username, password, force, g.repository, caCerts) } -func (g *gitopsUpdateDeploymentGitUtils) PlainClone(username, password, serverURL, directory string) error { +func (g *gitopsUpdateDeploymentGitUtils) PlainClone(username, password, serverURL, directory string, caCerts []byte) error { var err error - g.repository, err = gitUtil.PlainClone(username, password, serverURL, directory) + g.repository, err = gitUtil.PlainClone(username, password, serverURL, directory, caCerts) if err != nil { return errors.Wrapf(err, "plain clone failed '%s'", serverURL) } @@ -126,7 +150,12 @@ func runGitopsUpdateDeployment(config *gitopsUpdateDeploymentOptions, command gi } }() - err = cloneRepositoryAndChangeBranch(config, gitUtils, temporaryFolder) + certs, err := downloadCACertbunde(config.CustomTLSCertificateLinks, gitUtils, fileUtils) + if err != nil { + return err + } + + err = cloneRepositoryAndChangeBranch(config, gitUtils, fileUtils, temporaryFolder, certs) if err != nil { return errors.Wrap(err, "repository could not get prepared") } @@ -190,7 +219,7 @@ func runGitopsUpdateDeployment(config *gitopsUpdateDeploymentOptions, command gi } } - commit, err := commitAndPushChanges(config, gitUtils, allFiles) + commit, err := commitAndPushChanges(config, gitUtils, allFiles, certs) if err != nil { return errors.Wrap(err, "failed to commit and push changes") } @@ -292,8 +321,9 @@ func logNotRequiredButFilledFieldForKustomize(config *gitopsUpdateDeploymentOpti } } -func cloneRepositoryAndChangeBranch(config *gitopsUpdateDeploymentOptions, gitUtils iGitopsUpdateDeploymentGitUtils, temporaryFolder string) error { - err := gitUtils.PlainClone(config.Username, config.Password, config.ServerURL, temporaryFolder) +func cloneRepositoryAndChangeBranch(config *gitopsUpdateDeploymentOptions, gitUtils iGitopsUpdateDeploymentGitUtils, fileUtils gitopsUpdateDeploymentFileUtils, temporaryFolder string, certs []byte) error { + + err := gitUtils.PlainClone(config.Username, config.Password, config.ServerURL, temporaryFolder, certs) if err != nil { return errors.Wrap(err, "failed to plain clone repository") } @@ -305,6 +335,30 @@ func cloneRepositoryAndChangeBranch(config *gitopsUpdateDeploymentOptions, gitUt return nil } +func downloadCACertbunde(customTlsCertificateLinks []string, gitUtils iGitopsUpdateDeploymentGitUtils, fileUtils gitopsUpdateDeploymentFileUtils) ([]byte, error) { + certs := []byte{} + utils := newGitopsUpdateDeploymentUtilsBundle() + if len(customTlsCertificateLinks) > 0 { + for _, customTlsCertificateLink := range customTlsCertificateLinks { + log.Entry().Infof("Downloading CA certs %s into file '%s'", customTlsCertificateLink, path.Base(customTlsCertificateLink)) + err := utils.DownloadFile(customTlsCertificateLink, path.Base(customTlsCertificateLink), nil, nil) + if err != nil { + return certs, nil + } + + content, err := fileUtils.FileRead(path.Base(customTlsCertificateLink)) + if err != nil { + return certs, nil + } + log.Entry().Infof("CA certs added successfully to cert pool") + + certs = append(certs, content...) + } + } + + return certs, nil +} + func executeKubectl(config *gitopsUpdateDeploymentOptions, command gitopsUpdateDeploymentExecRunner, filePath string) ([]byte, error) { var outputBytes []byte registryImage, err := buildRegistryPlusImage(config) @@ -444,7 +498,7 @@ func buildRegistryPlusImageAndTagSeparately(config *gitopsUpdateDeploymentOption } -func commitAndPushChanges(config *gitopsUpdateDeploymentOptions, gitUtils iGitopsUpdateDeploymentGitUtils, filePaths []string) (plumbing.Hash, error) { +func commitAndPushChanges(config *gitopsUpdateDeploymentOptions, gitUtils iGitopsUpdateDeploymentGitUtils, filePaths []string, certs []byte) (plumbing.Hash, error) { commitMessage := config.CommitMessage if commitMessage == "" { @@ -456,7 +510,7 @@ func commitAndPushChanges(config *gitopsUpdateDeploymentOptions, gitUtils iGitop return [20]byte{}, errors.Wrap(err, "committing changes failed") } - err = gitUtils.PushChangesToRepository(config.Username, config.Password, &config.ForcePush) + err = gitUtils.PushChangesToRepository(config.Username, config.Password, &config.ForcePush, certs) if err != nil { return [20]byte{}, errors.Wrap(err, "pushing changes failed") } diff --git a/cmd/gitopsUpdateDeployment_generated.go b/cmd/gitopsUpdateDeployment_generated.go index 97eb254291..ca1c926643 100644 --- a/cmd/gitopsUpdateDeployment_generated.go +++ b/cmd/gitopsUpdateDeployment_generated.go @@ -16,20 +16,21 @@ import ( ) type gitopsUpdateDeploymentOptions struct { - BranchName string `json:"branchName,omitempty"` - CommitMessage string `json:"commitMessage,omitempty"` - ServerURL string `json:"serverUrl,omitempty"` - ForcePush bool `json:"forcePush,omitempty"` - Username string `json:"username,omitempty"` - Password string `json:"password,omitempty"` - FilePath string `json:"filePath,omitempty"` - ContainerName string `json:"containerName,omitempty"` - ContainerRegistryURL string `json:"containerRegistryUrl,omitempty"` - ContainerImageNameTag string `json:"containerImageNameTag,omitempty"` - ChartPath string `json:"chartPath,omitempty"` - HelmValues []string `json:"helmValues,omitempty"` - DeploymentName string `json:"deploymentName,omitempty"` - Tool string `json:"tool,omitempty" validate:"possible-values=kubectl helm kustomize"` + BranchName string `json:"branchName,omitempty"` + CommitMessage string `json:"commitMessage,omitempty"` + ServerURL string `json:"serverUrl,omitempty"` + ForcePush bool `json:"forcePush,omitempty"` + Username string `json:"username,omitempty"` + Password string `json:"password,omitempty"` + FilePath string `json:"filePath,omitempty"` + ContainerName string `json:"containerName,omitempty"` + ContainerRegistryURL string `json:"containerRegistryUrl,omitempty"` + ContainerImageNameTag string `json:"containerImageNameTag,omitempty"` + ChartPath string `json:"chartPath,omitempty"` + HelmValues []string `json:"helmValues,omitempty"` + DeploymentName string `json:"deploymentName,omitempty"` + Tool string `json:"tool,omitempty" validate:"possible-values=kubectl helm kustomize"` + CustomTLSCertificateLinks []string `json:"customTlsCertificateLinks,omitempty"` } // GitopsUpdateDeploymentCommand Updates Kubernetes Deployment Manifest in an Infrastructure Git Repository @@ -155,6 +156,7 @@ func addGitopsUpdateDeploymentFlags(cmd *cobra.Command, stepConfig *gitopsUpdate cmd.Flags().StringSliceVar(&stepConfig.HelmValues, "helmValues", []string{}, "List of helm values as YAML file reference or URL (as per helm parameter description for `-f` / `--values`)") cmd.Flags().StringVar(&stepConfig.DeploymentName, "deploymentName", os.Getenv("PIPER_deploymentName"), "Defines the name of the deployment. In case of `kustomize` this is the name or alias of the image in the `kustomization.yaml`") cmd.Flags().StringVar(&stepConfig.Tool, "tool", `kubectl`, "Defines the tool which should be used to update the deployment description.") + cmd.Flags().StringSliceVar(&stepConfig.CustomTLSCertificateLinks, "customTlsCertificateLinks", []string{}, "List containing download links of custom TLS certificates. This is required to ensure trusted connections to registries with custom certificates.") cmd.MarkFlagRequired("branchName") cmd.MarkFlagRequired("serverUrl") @@ -343,6 +345,15 @@ func gitopsUpdateDeploymentMetadata() config.StepData { Aliases: []config.Alias{}, Default: `kubectl`, }, + { + Name: "customTlsCertificateLinks", + ResourceRef: []config.ResourceReference{}, + Scope: []string{"PARAMETERS", "STAGES", "STEPS"}, + Type: "[]string", + Mandatory: false, + Aliases: []config.Alias{}, + Default: []string{}, + }, }, }, Containers: []config.Container{ diff --git a/cmd/gitopsUpdateDeployment_test.go b/cmd/gitopsUpdateDeployment_test.go index 2d05f1ce39..a776fdb83c 100644 --- a/cmd/gitopsUpdateDeployment_test.go +++ b/cmd/gitopsUpdateDeployment_test.go @@ -772,6 +772,7 @@ type filesMock struct { failOnCreation bool failOnDeletion bool failOnWrite bool + failOnRead bool failOnGlob bool path string } @@ -783,6 +784,13 @@ func (f filesMock) FileWrite(path string, content []byte, perm os.FileMode) erro return piperutils.Files{}.FileWrite(path, content, perm) } +func (f filesMock) FileRead(path string) ([]byte, error) { + if f.failOnRead { + return []byte{}, errors.New("error appeared") + } + return piperutils.Files{}.FileRead(path) +} + func (f filesMock) TempDir(dir string, pattern string) (name string, err error) { if f.failOnCreation { return "", errors.New("error appeared") @@ -848,7 +856,7 @@ func (v *gitUtilsMock) CommitFiles(newFiles []string, commitMessage string, _ st return [20]byte{123}, nil } -func (v gitUtilsMock) PushChangesToRepository(_ string, _ string, force *bool) error { +func (v gitUtilsMock) PushChangesToRepository(_ string, _ string, force *bool, caCerts []byte) error { if v.failOnPush { return errors.New("error on push") } @@ -858,7 +866,7 @@ func (v gitUtilsMock) PushChangesToRepository(_ string, _ string, force *bool) e return nil } -func (v *gitUtilsMock) PlainClone(_, _, _, directory string) error { +func (v *gitUtilsMock) PlainClone(_, _, _, directory string, caCerts []byte) error { if v.skipClone { return nil } diff --git a/pkg/git/git.go b/pkg/git/git.go index f843d1ee36..c5758f281a 100644 --- a/pkg/git/git.go +++ b/pkg/git/git.go @@ -1,13 +1,14 @@ package git import ( + "time" + "github.com/SAP/jenkins-library/pkg/log" "github.com/go-git/go-git/v5" "github.com/go-git/go-git/v5/plumbing" "github.com/go-git/go-git/v5/plumbing/object" "github.com/go-git/go-git/v5/plumbing/transport/http" "github.com/pkg/errors" - "time" ) // utilsWorkTree interface abstraction of git.Worktree to enable tests @@ -53,14 +54,18 @@ func commitSingleFile(filePath, commitMessage, author string, worktree utilsWork } // PushChangesToRepository Pushes all committed changes in the repository to the remote repository -func PushChangesToRepository(username, password string, force *bool, repository *git.Repository) error { - return pushChangesToRepository(username, password, force, repository) +func PushChangesToRepository(username, password string, force *bool, repository *git.Repository, caCerts []byte) error { + return pushChangesToRepository(username, password, force, repository, caCerts) } -func pushChangesToRepository(username, password string, force *bool, repository utilsRepository) error { +func pushChangesToRepository(username, password string, force *bool, repository utilsRepository, caCerts []byte) error { pushOptions := &git.PushOptions{ Auth: &http.BasicAuth{Username: username, Password: password}, } + + if len(caCerts) > 0 { + pushOptions.CABundle = caCerts + } if force != nil { pushOptions.Force = *force } @@ -72,16 +77,21 @@ func pushChangesToRepository(username, password string, force *bool, repository } // PlainClone Clones a non-bare repository to the provided directory -func PlainClone(username, password, serverURL, directory string) (*git.Repository, error) { +func PlainClone(username, password, serverURL, directory string, caCerts []byte) (*git.Repository, error) { abstractedGit := &abstractionGit{} - return plainClone(username, password, serverURL, directory, abstractedGit) + return plainClone(username, password, serverURL, directory, abstractedGit, caCerts) } -func plainClone(username, password, serverURL, directory string, abstractionGit utilsGit) (*git.Repository, error) { +func plainClone(username, password, serverURL, directory string, abstractionGit utilsGit, caCerts []byte) (*git.Repository, error) { gitCloneOptions := git.CloneOptions{ Auth: &http.BasicAuth{Username: username, Password: password}, URL: serverURL, } + + if len(caCerts) > 0 { + gitCloneOptions.CABundle = caCerts + } + repository, err := abstractionGit.plainClone(directory, false, &gitCloneOptions) if err != nil { return nil, errors.Wrap(err, "failed to clone git") diff --git a/pkg/git/git_test.go b/pkg/git/git_test.go index 39e50e3348..f5cf660db4 100644 --- a/pkg/git/git_test.go +++ b/pkg/git/git_test.go @@ -51,13 +51,13 @@ func TestPushChangesToRepository(t *testing.T) { t.Parallel() err := pushChangesToRepository("user", "password", nil, RepositoryMock{ test: t, - }) + }, []byte{}) assert.NoError(t, err) }) t.Run("error pushing", func(t *testing.T) { t.Parallel() - err := pushChangesToRepository("user", "password", nil, RepositoryMockError{}) + err := pushChangesToRepository("user", "password", nil, RepositoryMockError{}, []byte{}) assert.EqualError(t, err, "failed to push commit: error on push commits") }) } @@ -67,7 +67,7 @@ func TestPlainClone(t *testing.T) { t.Run("successful clone", func(t *testing.T) { t.Parallel() abstractedGit := &UtilsGitMock{} - _, err := plainClone("user", "password", "URL", "directory", abstractedGit) + _, err := plainClone("user", "password", "URL", "directory", abstractedGit, []byte{}) assert.NoError(t, err) assert.Equal(t, "directory", abstractedGit.path) assert.False(t, abstractedGit.isBare) @@ -78,7 +78,7 @@ func TestPlainClone(t *testing.T) { t.Run("error on cloning", func(t *testing.T) { t.Parallel() abstractedGit := UtilsGitMockError{} - _, err := plainClone("user", "password", "URL", "directory", abstractedGit) + _, err := plainClone("user", "password", "URL", "directory", abstractedGit, []byte{}) assert.EqualError(t, err, "failed to clone git: error during clone") }) } diff --git a/resources/metadata/gitopsUpdateDeployment.yaml b/resources/metadata/gitopsUpdateDeployment.yaml index 22bceee9bf..5349e2e74b 100644 --- a/resources/metadata/gitopsUpdateDeployment.yaml +++ b/resources/metadata/gitopsUpdateDeployment.yaml @@ -190,6 +190,13 @@ spec: - kubectl - helm - kustomize + - name: customTlsCertificateLinks + type: "[]string" + description: List containing download links of custom TLS certificates. This is required to ensure trusted connections to registries with custom certificates. + scope: + - PARAMETERS + - STAGES + - STEPS containers: - image: dtzar/helm-kubectl:3.8.0 workingDir: /config From 8c9beb98c60bd3097da9647455825563a10c2c99 Mon Sep 17 00:00:00 2001 From: Egor Balakin <14162703+m1ron0xFF@users.noreply.github.com> Date: Thu, 28 Sep 2023 16:14:35 +0400 Subject: [PATCH 5/8] feat(kanikoExecute): add dockerfilePath param to multipleImages (#4569) * add containerDockerfilePath param to multipleImages * rename ContainerDockerfilePath param to DockerfilePath * Fix trailing spaces --------- Co-authored-by: Egor Balakin <egor.balakin@sap.com> Co-authored-by: Vyacheslav Starostin <32613074+vstarostin@users.noreply.github.com> --- cmd/kanikoExecute.go | 17 +++++++++++++++-- resources/metadata/kanikoExecute.yaml | 1 + 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/cmd/kanikoExecute.go b/cmd/kanikoExecute.go index 91469991ce..645682b594 100644 --- a/cmd/kanikoExecute.go +++ b/cmd/kanikoExecute.go @@ -226,7 +226,13 @@ func runKanikoExecute(config *kanikoExecuteOptions, telemetryData *telemetry.Cus "--context-sub-path", entry.ContextSubPath, "--destination", fmt.Sprintf("%v/%v", containerRegistry, containerImageNameAndTag), ) - if err = runKaniko(config.DockerfilePath, buildOptions, config.ReadImageDigest, execRunner, fileUtils, commonPipelineEnvironment); err != nil { + + dockerfilePath := config.DockerfilePath + if entry.DockerfilePath != "" { + dockerfilePath = entry.DockerfilePath + } + + if err = runKaniko(dockerfilePath, buildOptions, config.ReadImageDigest, execRunner, fileUtils, commonPipelineEnvironment); err != nil { return fmt.Errorf("multipleImages: failed to build image '%v' using '%v': %w", entry.ContainerImageName, config.DockerfilePath, err) } @@ -251,7 +257,13 @@ func runKanikoExecute(config *kanikoExecuteOptions, telemetryData *telemetry.Cus "--context-sub-path", entry.ContextSubPath, "--destination", entry.ContainerImage, ) - if err = runKaniko(config.DockerfilePath, buildOptions, config.ReadImageDigest, execRunner, fileUtils, commonPipelineEnvironment); err != nil { + + dockerfilePath := config.DockerfilePath + if entry.DockerfilePath != "" { + dockerfilePath = entry.DockerfilePath + } + + if err = runKaniko(dockerfilePath, buildOptions, config.ReadImageDigest, execRunner, fileUtils, commonPipelineEnvironment); err != nil { return fmt.Errorf("multipleImages: failed to build image '%v' using '%v': %w", containerImageName, config.DockerfilePath, err) } @@ -405,6 +417,7 @@ func runKaniko(dockerFilepath string, buildOptions []string, readDigest bool, ex type multipleImageConf struct { ContextSubPath string `json:"contextSubPath,omitempty"` + DockerfilePath string `json:"dockerfilePath,omitempty"` ContainerImageName string `json:"containerImageName,omitempty"` ContainerImageTag string `json:"containerImageTag,omitempty"` ContainerImage string `json:"containerImage,omitempty"` diff --git a/resources/metadata/kanikoExecute.yaml b/resources/metadata/kanikoExecute.yaml index 18a241c42b..f8acefba0b 100644 --- a/resources/metadata/kanikoExecute.yaml +++ b/resources/metadata/kanikoExecute.yaml @@ -158,6 +158,7 @@ spec: Array keys: contextSubPath - Set a context subpath. + dockerfilePath - Dockerfile path (optional). If empty, root will be used. containerImageName - Name of the container which will be built. containerImageTag - Tag of the container which will be built. If empty - root containerImageTag will be used. containerImage - Defines the full name of the Docker image to be created including registry. From ac083606f027e0b958b485ae78e51aa9a417d601 Mon Sep 17 00:00:00 2001 From: Marcus Holl <marcus.holl@sap.com> Date: Fri, 29 Sep 2023 13:59:56 +0200 Subject: [PATCH 6/8] fix(helm): forward sourceRepositoryCredentialsId from groovy to go layer (#4604) forward sourceRepositoryCredentialsId from groovy to go layer in the same way how this is done for the targetRepositoryCredentialsId --- cmd/helmExecute_generated.go | 3 ++- resources/metadata/helmExecute.yaml | 5 ++++- vars/helmExecute.groovy | 1 + 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/cmd/helmExecute_generated.go b/cmd/helmExecute_generated.go index 516b471cbc..84a6c253a9 100644 --- a/cmd/helmExecute_generated.go +++ b/cmd/helmExecute_generated.go @@ -255,7 +255,8 @@ func helmExecuteMetadata() config.StepData { Secrets: []config.StepSecrets{ {Name: "kubeConfigFileCredentialsId", Description: "Jenkins 'Secret file' credentials ID containing kubeconfig file. Details can be found in the [Kubernetes documentation](https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/).", Type: "jenkins", Aliases: []config.Alias{{Name: "kubeCredentialsId", Deprecated: true}}}, {Name: "dockerConfigJsonCredentialsId", Description: "Jenkins 'Secret file' credentials ID containing Docker config.json (with registry credential(s)).", Type: "jenkins"}, - {Name: "targetRepositoryCredentialsId", Description: "Jenkins 'Username Password' credentials ID containing username and password for the Helm Repository authentication", Type: "jenkins"}, + {Name: "sourceRepositoryCredentialsId", Description: "Jenkins 'Username Password' credentials ID containing username and password for the Helm Repository authentication (source repo)", Type: "jenkins"}, + {Name: "targetRepositoryCredentialsId", Description: "Jenkins 'Username Password' credentials ID containing username and password for the Helm Repository authentication (target repo)", Type: "jenkins"}, }, Resources: []config.StepResources{ {Name: "deployDescriptor", Type: "stash"}, diff --git a/resources/metadata/helmExecute.yaml b/resources/metadata/helmExecute.yaml index f91c755a78..ccae717d7f 100644 --- a/resources/metadata/helmExecute.yaml +++ b/resources/metadata/helmExecute.yaml @@ -36,8 +36,11 @@ spec: - name: dockerConfigJsonCredentialsId description: Jenkins 'Secret file' credentials ID containing Docker config.json (with registry credential(s)). type: jenkins + - name: sourceRepositoryCredentialsId + description: Jenkins 'Username Password' credentials ID containing username and password for the Helm Repository authentication (source repo) + type: jenkins - name: targetRepositoryCredentialsId - description: Jenkins 'Username Password' credentials ID containing username and password for the Helm Repository authentication + description: Jenkins 'Username Password' credentials ID containing username and password for the Helm Repository authentication (target repo) type: jenkins resources: - name: deployDescriptor diff --git a/vars/helmExecute.groovy b/vars/helmExecute.groovy index ef729cd237..89c8ee202a 100644 --- a/vars/helmExecute.groovy +++ b/vars/helmExecute.groovy @@ -7,6 +7,7 @@ void call(Map parameters = [:]) { List credentials = [ [type: 'file', id: 'kubeConfigFileCredentialsId', env: ['PIPER_kubeConfig']], [type: 'file', id: 'dockerConfigJsonCredentialsId', env: ['PIPER_dockerConfigJSON']], + [type: 'usernamePassword', id: 'sourceRepositoryCredentialsId', env: ['PIPER_sourceRepositoryUser', 'PIPER_sourceRepositoryPassword']], [type: 'usernamePassword', id: 'targetRepositoryCredentialsId', env: ['PIPER_targetRepositoryUser', 'PIPER_targetRepositoryPassword']], ] piperExecuteBin(parameters, STEP_NAME, METADATA_FILE, credentials) From 3c24cae62776aadbe82e6533d7eead714d35b7cf Mon Sep 17 00:00:00 2001 From: Jk1484 <35270240+Jk1484@users.noreply.github.com> Date: Wed, 4 Oct 2023 15:44:48 +0500 Subject: [PATCH 7/8] feat(config): exporting generateConfig function and applying minor changes (#4605) * exporting generateConfig function and applying minor changes * Added setConfigOptions to set configOptions variable. Added possibility to set format output, json or yaml for now. * Correcting mistake on cmd/getDefaults.go Co-authored-by: Jordi van Liempt <35920075+jliempt@users.noreply.github.com> --------- Co-authored-by: Jordi van Liempt <35920075+jliempt@users.noreply.github.com> --- cmd/cnbBuild_test.go | 2 +- cmd/getConfig.go | 121 +++++++++++++++++++++++--------------- cmd/getConfig_test.go | 8 +-- cmd/getDefaults.go | 2 +- cmd/kanikoExecute_test.go | 6 +- 5 files changed, 82 insertions(+), 57 deletions(-) diff --git a/cmd/cnbBuild_test.go b/cmd/cnbBuild_test.go index 75ba12e4a0..24dd2331d3 100644 --- a/cmd/cnbBuild_test.go +++ b/cmd/cnbBuild_test.go @@ -105,7 +105,7 @@ func assetBuildEnv(t *testing.T, utils cnbutils.MockUtils, key, value string) bo } func TestRunCnbBuild(t *testing.T) { - configOptions.openFile = piperconf.OpenPiperFile + configOptions.OpenFile = piperconf.OpenPiperFile t.Run("prefers direct configuration", func(t *testing.T) { t.Parallel() diff --git a/cmd/getConfig.go b/cmd/getConfig.go index 6ea45de881..aa4734a75c 100644 --- a/cmd/getConfig.go +++ b/cmd/getConfig.go @@ -6,6 +6,7 @@ import ( "os" "path" "path/filepath" + "strings" "github.com/SAP/jenkins-library/pkg/config" "github.com/SAP/jenkins-library/pkg/log" @@ -16,19 +17,31 @@ import ( "github.com/spf13/cobra" ) -type configCommandOptions struct { - output string // output format, so far only JSON - outputFile string // if set: path to file where the output should be written to - parametersJSON string // parameters to be considered in JSON format - stageConfig bool - stageConfigAcceptedParameters []string - stepMetadata string // metadata to be considered, can be filePath or ENV containing JSON in format 'ENV:MY_ENV_VAR' - stepName string - contextConfig bool - openFile func(s string, t map[string]string) (io.ReadCloser, error) +type ConfigCommandOptions struct { + Output string // output format, so far only JSON, YAML + OutputFile string // if set: path to file where the output should be written to + ParametersJSON string // parameters to be considered in JSON format + StageConfig bool + StageConfigAcceptedParameters []string + StepMetadata string // metadata to be considered, can be filePath or ENV containing JSON in format 'ENV:MY_ENV_VAR' + StepName string + ContextConfig bool + OpenFile func(s string, t map[string]string) (io.ReadCloser, error) } -var configOptions configCommandOptions +var configOptions ConfigCommandOptions + +func SetConfigOptions(c ConfigCommandOptions) { + configOptions.ContextConfig = c.ContextConfig + configOptions.OpenFile = c.OpenFile + configOptions.Output = c.Output + configOptions.OutputFile = c.OutputFile + configOptions.ParametersJSON = c.ParametersJSON + configOptions.StageConfig = c.StageConfig + configOptions.StageConfigAcceptedParameters = c.StageConfigAcceptedParameters + configOptions.StepMetadata = c.StepMetadata + configOptions.StepName = c.StepName +} type getConfigUtils interface { FileExists(filename string) (bool, error) @@ -41,16 +54,17 @@ type getConfigUtilsBundle struct { } func newGetConfigUtilsUtils() getConfigUtils { - utils := getConfigUtilsBundle{ + return &getConfigUtilsBundle{ Files: &piperutils.Files{}, } - return &utils } // ConfigCommand is the entry command for loading the configuration of a pipeline step func ConfigCommand() *cobra.Command { + SetConfigOptions(ConfigCommandOptions{ + OpenFile: config.OpenPiperFile, + }) - configOptions.openFile = config.OpenPiperFile var createConfigCmd = &cobra.Command{ Use: "getConfig", Short: "Loads the project 'Piper' configuration respecting defaults and parameters.", @@ -62,9 +76,7 @@ func ConfigCommand() *cobra.Command { GeneralConfig.GitHubAccessTokens = ResolveAccessTokens(GeneralConfig.GitHubTokens) }, Run: func(cmd *cobra.Command, _ []string) { - utils := newGetConfigUtilsUtils() - err := generateConfig(utils) - if err != nil { + if err := generateConfigWrapper(); err != nil { log.SetErrorCategory(log.ErrorConfiguration) log.Entry().WithError(err).Fatal("failed to retrieve configuration") } @@ -77,8 +89,8 @@ func ConfigCommand() *cobra.Command { // GetDockerImageValue provides Piper commands additional access to configuration of step execution image if required func GetDockerImageValue(stepName string) (string, error) { - configOptions.contextConfig = true - configOptions.stepName = stepName + configOptions.ContextConfig = true + configOptions.StepName = stepName stepConfig, err := getConfig() if err != nil { return "", err @@ -94,8 +106,8 @@ func GetDockerImageValue(stepName string) (string, error) { } func getBuildToolFromStageConfig(stepName string) (string, error) { - configOptions.contextConfig = true - configOptions.stepName = stepName + configOptions.ContextConfig = true + configOptions.StepName = stepName stageConfig, err := GetStageConfig() if err != nil { return "", err @@ -116,7 +128,7 @@ func GetStageConfig() (config.StepConfig, error) { stepConfig := config.StepConfig{} projectConfigFile := getProjectConfigFile(GeneralConfig.CustomConfig) - customConfig, err := configOptions.openFile(projectConfigFile, GeneralConfig.GitHubAccessTokens) + customConfig, err := configOptions.OpenFile(projectConfigFile, GeneralConfig.GitHubAccessTokens) if err != nil { if !errors.Is(err, os.ErrNotExist) { return stepConfig, errors.Wrapf(err, "config: open configuration file '%v' failed", projectConfigFile) @@ -126,7 +138,7 @@ func GetStageConfig() (config.StepConfig, error) { defaultConfig := []io.ReadCloser{} for _, f := range GeneralConfig.DefaultConfig { - fc, err := configOptions.openFile(f, GeneralConfig.GitHubAccessTokens) + fc, err := configOptions.OpenFile(f, GeneralConfig.GitHubAccessTokens) // only create error for non-default values if err != nil && f != ".pipeline/defaults.yaml" { return stepConfig, errors.Wrapf(err, "config: getting defaults failed: '%v'", f) @@ -136,7 +148,7 @@ func GetStageConfig() (config.StepConfig, error) { } } - return myConfig.GetStageConfig(GeneralConfig.ParametersJSON, customConfig, defaultConfig, GeneralConfig.IgnoreCustomDefaults, configOptions.stageConfigAcceptedParameters, GeneralConfig.StageName) + return myConfig.GetStageConfig(GeneralConfig.ParametersJSON, customConfig, defaultConfig, GeneralConfig.IgnoreCustomDefaults, configOptions.StageConfigAcceptedParameters, GeneralConfig.StageName) } func getConfig() (config.StepConfig, error) { @@ -144,17 +156,17 @@ func getConfig() (config.StepConfig, error) { var stepConfig config.StepConfig var err error - if configOptions.stageConfig { + if configOptions.StageConfig { stepConfig, err = GetStageConfig() if err != nil { return stepConfig, errors.Wrap(err, "getting stage config failed") } } else { - log.Entry().Infof("Printing stepName %s", configOptions.stepName) + log.Entry().Infof("Printing stepName %s", configOptions.StepName) if GeneralConfig.MetaDataResolver == nil { GeneralConfig.MetaDataResolver = GetAllStepMetadata } - metadata, err := config.ResolveMetadata(GeneralConfig.GitHubAccessTokens, GeneralConfig.MetaDataResolver, configOptions.stepMetadata, configOptions.stepName) + metadata, err := config.ResolveMetadata(GeneralConfig.GitHubAccessTokens, GeneralConfig.MetaDataResolver, configOptions.StepMetadata, configOptions.StepName) if err != nil { return stepConfig, errors.Wrapf(err, "failed to resolve metadata") } @@ -172,7 +184,7 @@ func getConfig() (config.StepConfig, error) { projectConfigFile := getProjectConfigFile(GeneralConfig.CustomConfig) - customConfig, err := configOptions.openFile(projectConfigFile, GeneralConfig.GitHubAccessTokens) + customConfig, err := configOptions.OpenFile(projectConfigFile, GeneralConfig.GitHubAccessTokens) if err != nil { if !errors.Is(err, os.ErrNotExist) { return stepConfig, errors.Wrapf(err, "config: open configuration file '%v' failed", projectConfigFile) @@ -186,7 +198,7 @@ func getConfig() (config.StepConfig, error) { } for _, f := range GeneralConfig.DefaultConfig { - fc, err := configOptions.openFile(f, GeneralConfig.GitHubAccessTokens) + fc, err := configOptions.OpenFile(f, GeneralConfig.GitHubAccessTokens) // only create error for non-default values if err != nil && f != ".pipeline/defaults.yaml" { return stepConfig, errors.Wrapf(err, "config: getting defaults failed: '%v'", f) @@ -198,7 +210,7 @@ func getConfig() (config.StepConfig, error) { var flags map[string]interface{} - if configOptions.contextConfig { + if configOptions.ContextConfig { metadata.Spec.Inputs.Parameters = []config.StepParameters{} } @@ -208,33 +220,46 @@ func getConfig() (config.StepConfig, error) { } // apply context conditions if context configuration is requested - if configOptions.contextConfig { + if configOptions.ContextConfig { applyContextConditions(metadata, &stepConfig) } } return stepConfig, nil } -func generateConfig(utils getConfigUtils) error { +func generateConfigWrapper() error { + var formatter func(interface{}) (string, error) + switch strings.ToLower(configOptions.Output) { + case "yaml", "yml": + formatter = config.GetYAML + case "json": + formatter = config.GetJSON + default: + formatter = config.GetJSON + } + return GenerateConfig(formatter) +} + +func GenerateConfig(formatter func(interface{}) (string, error)) error { + utils := newGetConfigUtilsUtils() stepConfig, err := getConfig() if err != nil { return err } - myConfigJSON, err := config.GetJSON(stepConfig.Config) + myConfig, err := formatter(stepConfig.Config) if err != nil { - return fmt.Errorf("failed to get JSON from config: %w", err) + return fmt.Errorf("failed to marshal config: %w", err) } - if len(configOptions.outputFile) > 0 { - err := utils.FileWrite(configOptions.outputFile, []byte(myConfigJSON), 0666) - if err != nil { - return fmt.Errorf("failed to write output file %v: %w", configOptions.outputFile, err) + if len(configOptions.OutputFile) > 0 { + if err := utils.FileWrite(configOptions.OutputFile, []byte(myConfig), 0666); err != nil { + return fmt.Errorf("failed to write output file %v: %w", configOptions.OutputFile, err) } return nil } - fmt.Println(myConfigJSON) + fmt.Println(myConfig) return nil } @@ -242,20 +267,20 @@ func generateConfig(utils getConfigUtils) error { func addConfigFlags(cmd *cobra.Command) { // ToDo: support more output options, like https://kubernetes.io/docs/reference/kubectl/overview/#formatting-output - cmd.Flags().StringVar(&configOptions.output, "output", "json", "Defines the output format") - cmd.Flags().StringVar(&configOptions.outputFile, "outputFile", "", "Defines a file path. f set, the output will be written to the defines file") + cmd.Flags().StringVar(&configOptions.Output, "output", "json", "Defines the output format") + cmd.Flags().StringVar(&configOptions.OutputFile, "outputFile", "", "Defines a file path. f set, the output will be written to the defines file") - cmd.Flags().StringVar(&configOptions.parametersJSON, "parametersJSON", os.Getenv("PIPER_parametersJSON"), "Parameters to be considered in JSON format") - cmd.Flags().BoolVar(&configOptions.stageConfig, "stageConfig", false, "Defines if step stage configuration should be loaded and no step-specific config") - cmd.Flags().StringArrayVar(&configOptions.stageConfigAcceptedParameters, "stageConfigAcceptedParams", []string{}, "Defines the parameters used for filtering stage/general configuration when accessing stage config") - cmd.Flags().StringVar(&configOptions.stepMetadata, "stepMetadata", "", "Step metadata, passed as path to yaml") - cmd.Flags().StringVar(&configOptions.stepName, "stepName", "", "Step name, used to get step metadata if yaml path is not set") - cmd.Flags().BoolVar(&configOptions.contextConfig, "contextConfig", false, "Defines if step context configuration should be loaded instead of step config") + cmd.Flags().StringVar(&configOptions.ParametersJSON, "parametersJSON", os.Getenv("PIPER_parametersJSON"), "Parameters to be considered in JSON format") + cmd.Flags().BoolVar(&configOptions.StageConfig, "stageConfig", false, "Defines if step stage configuration should be loaded and no step-specific config") + cmd.Flags().StringArrayVar(&configOptions.StageConfigAcceptedParameters, "stageConfigAcceptedParams", []string{}, "Defines the parameters used for filtering stage/general configuration when accessing stage config") + cmd.Flags().StringVar(&configOptions.StepMetadata, "stepMetadata", "", "Step metadata, passed as path to yaml") + cmd.Flags().StringVar(&configOptions.StepName, "stepName", "", "Step name, used to get step metadata if yaml path is not set") + cmd.Flags().BoolVar(&configOptions.ContextConfig, "contextConfig", false, "Defines if step context configuration should be loaded instead of step config") } func defaultsAndFilters(metadata *config.StepData, stepName string) ([]io.ReadCloser, config.StepFilters, error) { - if configOptions.contextConfig { + if configOptions.ContextConfig { defaults, err := metadata.GetContextDefaults(stepName) if err != nil { return nil, config.StepFilters{}, errors.Wrap(err, "metadata: getting context defaults failed") diff --git a/cmd/getConfig_test.go b/cmd/getConfig_test.go index 327a5dc57d..f2acdbf561 100644 --- a/cmd/getConfig_test.go +++ b/cmd/getConfig_test.go @@ -56,8 +56,8 @@ func TestConfigCommand(t *testing.T) { t.Run("Run", func(t *testing.T) { t.Run("Success case", func(t *testing.T) { - configOptions.openFile = configOpenFileMock - configOptions.stepName = "githubCreateIssue" + configOptions.OpenFile = configOpenFileMock + configOptions.StepName = "githubCreateIssue" cmd.Run(cmd, []string{}) }) }) @@ -75,8 +75,8 @@ func TestDefaultsAndFilters(t *testing.T) { } t.Run("Context config", func(t *testing.T) { - configOptions.contextConfig = true - defer func() { configOptions.contextConfig = false }() + configOptions.ContextConfig = true + defer func() { configOptions.ContextConfig = false }() defaults, filters, err := defaultsAndFilters(&metadata, "stepName") assert.Equal(t, 1, len(defaults), "getting defaults failed") diff --git a/cmd/getDefaults.go b/cmd/getDefaults.go index 9930764fee..98b2bd998a 100644 --- a/cmd/getDefaults.go +++ b/cmd/getDefaults.go @@ -128,7 +128,7 @@ func generateDefaults(utils getDefaultsUtils) ([]byte, error) { if len(defaultsOptions.outputFile) > 0 { err := utils.FileWrite(defaultsOptions.outputFile, []byte(jsonOutput), 0666) if err != nil { - return jsonOutput, fmt.Errorf("failed to write output file %v: %w", configOptions.outputFile, err) + return jsonOutput, fmt.Errorf("failed to write output file %v: %w", defaultsOptions.outputFile, err) } return jsonOutput, nil } diff --git a/cmd/kanikoExecute_test.go b/cmd/kanikoExecute_test.go index 0571b4be77..b8aa6483ce 100644 --- a/cmd/kanikoExecute_test.go +++ b/cmd/kanikoExecute_test.go @@ -50,12 +50,12 @@ func TestRunKanikoExecute(t *testing.T) { // required due to config resolution during build settings retrieval // ToDo: proper mocking - openFileBak := configOptions.openFile + openFileBak := configOptions.OpenFile defer func() { - configOptions.openFile = openFileBak + configOptions.OpenFile = openFileBak }() - configOptions.openFile = configOpenFileMock + configOptions.OpenFile = configOpenFileMock t.Run("success case", func(t *testing.T) { config := &kanikoExecuteOptions{ From f3c70df939d2de67b4a134cc780441e004e02b7b Mon Sep 17 00:00:00 2001 From: akram8008 <900658008.akram@gmail.com> Date: Thu, 5 Oct 2023 20:34:33 +0500 Subject: [PATCH 8/8] moved func prepareGolangPrivatePackages to pkg/golang --- cmd/detectExecuteScan.go | 5 ++-- cmd/golangBuild.go | 22 ------------------ cmd/whitesourceExecuteScan.go | 5 ++-- pkg/golang/golang.go | 43 +++++++++++++++++++++++++++++++++++ 4 files changed, 49 insertions(+), 26 deletions(-) create mode 100644 pkg/golang/golang.go diff --git a/cmd/detectExecuteScan.go b/cmd/detectExecuteScan.go index faf6a07205..eeb5099181 100644 --- a/cmd/detectExecuteScan.go +++ b/cmd/detectExecuteScan.go @@ -15,6 +15,7 @@ import ( bd "github.com/SAP/jenkins-library/pkg/blackduck" "github.com/SAP/jenkins-library/pkg/command" piperGithub "github.com/SAP/jenkins-library/pkg/github" + "github.com/SAP/jenkins-library/pkg/golang" piperhttp "github.com/SAP/jenkins-library/pkg/http" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/maven" @@ -139,9 +140,9 @@ func detectExecuteScan(config detectExecuteScanOptions, _ *telemetry.CustomData, log.Entry().WithError(err).Warning("Failed to get GitHub client") } - if config.PrivateModulesGitToken != "" { + if config.PrivateModules == "" && config.PrivateModulesGitToken != "" { //configuring go private packages - if err := prepareGolangPrivatePackages(config.PrivateModules, config.PrivateModulesGitToken); err != nil { + if err := golang.PrepareGolangPrivatePackages("detectExecuteStep", config.PrivateModules, config.PrivateModulesGitToken); err != nil { log.Entry().Warningf("couldn't set private packages for golang, error: %s", err.Error()) } } diff --git a/cmd/golangBuild.go b/cmd/golangBuild.go index 22fec60ca2..8d3cf68783 100644 --- a/cmd/golangBuild.go +++ b/cmd/golangBuild.go @@ -600,25 +600,3 @@ func gitConfigurationForPrivateModules(privateMod string, token string, utils go return nil } - -// prepare golang private packages for whitesource and blackduck(detectExecuteScan) -func prepareGolangPrivatePackages(privateModules, privateModulesGitToken string) error { - - goConfig := golangBuildOptions{ - PrivateModules: privateModules, - PrivateModulesGitToken: privateModulesGitToken, - } // only these parameters are enough to configure - - utils := newGolangBuildUtils(goConfig) - - goModFile, err := readGoModFile(utils) // returns nil if go.mod doesnt exist - if err != nil { - return err - } - - if err = prepareGolangEnvironment(&goConfig, goModFile, utils); err != nil { - return err - } - - return nil -} diff --git a/cmd/whitesourceExecuteScan.go b/cmd/whitesourceExecuteScan.go index 65f7f68b0f..1f00d7d767 100644 --- a/cmd/whitesourceExecuteScan.go +++ b/cmd/whitesourceExecuteScan.go @@ -18,6 +18,7 @@ import ( "github.com/SAP/jenkins-library/pkg/command" "github.com/SAP/jenkins-library/pkg/format" + "github.com/SAP/jenkins-library/pkg/golang" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/npm" "github.com/SAP/jenkins-library/pkg/piperutils" @@ -157,9 +158,9 @@ func whitesourceExecuteScan(config ScanOptions, _ *telemetry.CustomData, commonP } func runWhitesourceExecuteScan(ctx context.Context, config *ScanOptions, scan *ws.Scan, utils whitesourceUtils, sys whitesource, commonPipelineEnvironment *whitesourceExecuteScanCommonPipelineEnvironment, influx *whitesourceExecuteScanInflux) error { - if config != nil && config.PrivateModulesGitToken != "" { + if config != nil && config.PrivateModules != "" && config.PrivateModulesGitToken != "" { //configuring go private packages - if err := prepareGolangPrivatePackages(config.PrivateModules, config.PrivateModulesGitToken); err != nil { + if err := golang.PrepareGolangPrivatePackages("WhitesourceExecuteStep", config.PrivateModules, config.PrivateModulesGitToken); err != nil { log.Entry().Warningf("couldn't set private packages for golang, error: %s", err.Error()) } } diff --git a/pkg/golang/golang.go b/pkg/golang/golang.go new file mode 100644 index 0000000000..8ff5d2f4df --- /dev/null +++ b/pkg/golang/golang.go @@ -0,0 +1,43 @@ +package golang + +import ( + "fmt" + "os" + "strings" + + "github.com/SAP/jenkins-library/pkg/command" +) + +type utilsBundle struct { + command.Command +} + +// prepare golang private packages for whitesource and blackduck(detectExecuteScan) +func PrepareGolangPrivatePackages(stepName, privateModules, privateModulesGitToken string) error { + utils := &utilsBundle{ + Command: command.Command{ + StepName: stepName, + }, + } + os.Setenv("GOPRIVATE", privateModules) + err := gitConfigurationForPrivateModules(privateModules, privateModulesGitToken, utils) + if err != nil { + return err + } + return nil +} + +func gitConfigurationForPrivateModules(privateMod string, token string, utils *utilsBundle) error { + privateMod = strings.ReplaceAll(privateMod, "/*", "") + privateMod = strings.ReplaceAll(privateMod, "*.", "") + modules := strings.Split(privateMod, ",") + for _, v := range modules { + authenticatedRepoURL := fmt.Sprintf("https://%s@%s", token, v) + repoBaseURL := fmt.Sprintf("https://%s", v) + err := utils.RunExecutable("git", "config", "--global", fmt.Sprintf("url.%s.insteadOf", authenticatedRepoURL), repoBaseURL) + if err != nil { + return err + } + } + return nil +}