diff --git a/cmd/abapAddonAssemblyKitCheckCVs_generated.go b/cmd/abapAddonAssemblyKitCheckCVs_generated.go index 8d2f2186f3..651d25e833 100644 --- a/cmd/abapAddonAssemblyKitCheckCVs_generated.go +++ b/cmd/abapAddonAssemblyKitCheckCVs_generated.go @@ -9,6 +9,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/piperenv" "github.com/SAP/jenkins-library/pkg/splunk" @@ -124,6 +125,11 @@ For Terminology refer to the [Scenario Description](https://www.project-piper.io return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -150,6 +156,19 @@ For Terminology refer to the [Scenario Description](https://www.project-piper.io GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + GeneralConfig.CorrelationID, + GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() diff --git a/cmd/abapAddonAssemblyKitCheckPV_generated.go b/cmd/abapAddonAssemblyKitCheckPV_generated.go index 0038d14c4a..c3d4ac2206 100644 --- a/cmd/abapAddonAssemblyKitCheckPV_generated.go +++ b/cmd/abapAddonAssemblyKitCheckPV_generated.go @@ -9,6 +9,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/piperenv" "github.com/SAP/jenkins-library/pkg/splunk" @@ -124,6 +125,11 @@ For Terminology refer to the [Scenario Description](https://www.project-piper.io return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -150,6 +156,19 @@ For Terminology refer to the [Scenario Description](https://www.project-piper.io GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + GeneralConfig.CorrelationID, + GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() diff --git a/cmd/abapAddonAssemblyKitCheck_generated.go b/cmd/abapAddonAssemblyKitCheck_generated.go index 3711fb3110..0dec1e978e 100644 --- a/cmd/abapAddonAssemblyKitCheck_generated.go +++ b/cmd/abapAddonAssemblyKitCheck_generated.go @@ -9,6 +9,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/piperenv" "github.com/SAP/jenkins-library/pkg/splunk" @@ -127,6 +128,11 @@ For Terminology refer to the [Scenario Description](https://www.project-piper.io return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -153,6 +159,19 @@ For Terminology refer to the [Scenario Description](https://www.project-piper.io GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + GeneralConfig.CorrelationID, + GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() diff --git a/cmd/abapAddonAssemblyKitCreateTargetVector_generated.go b/cmd/abapAddonAssemblyKitCreateTargetVector_generated.go index 7224504166..2d237e7764 100644 --- a/cmd/abapAddonAssemblyKitCreateTargetVector_generated.go +++ b/cmd/abapAddonAssemblyKitCreateTargetVector_generated.go @@ -9,6 +9,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/piperenv" "github.com/SAP/jenkins-library/pkg/splunk" @@ -126,6 +127,11 @@ For Terminology refer to the [Scenario Description](https://www.project-piper.io return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -152,6 +158,19 @@ For Terminology refer to the [Scenario Description](https://www.project-piper.io GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + GeneralConfig.CorrelationID, + GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() diff --git a/cmd/abapAddonAssemblyKitPublishTargetVector_generated.go b/cmd/abapAddonAssemblyKitPublishTargetVector_generated.go index 239fbf27b2..87de4808af 100644 --- a/cmd/abapAddonAssemblyKitPublishTargetVector_generated.go +++ b/cmd/abapAddonAssemblyKitPublishTargetVector_generated.go @@ -8,6 +8,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/splunk" "github.com/SAP/jenkins-library/pkg/telemetry" @@ -97,6 +98,11 @@ For Terminology refer to the [Scenario Description](https://www.project-piper.io return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -122,6 +128,19 @@ For Terminology refer to the [Scenario Description](https://www.project-piper.io GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + GeneralConfig.CorrelationID, + GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() diff --git a/cmd/abapAddonAssemblyKitRegisterPackages_generated.go b/cmd/abapAddonAssemblyKitRegisterPackages_generated.go index 25043faba6..3d2eeffa73 100644 --- a/cmd/abapAddonAssemblyKitRegisterPackages_generated.go +++ b/cmd/abapAddonAssemblyKitRegisterPackages_generated.go @@ -9,6 +9,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/piperenv" "github.com/SAP/jenkins-library/pkg/splunk" @@ -127,6 +128,11 @@ For Terminology refer to the [Scenario Description](https://www.project-piper.io return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -153,6 +159,19 @@ For Terminology refer to the [Scenario Description](https://www.project-piper.io GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + GeneralConfig.CorrelationID, + GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() diff --git a/cmd/abapAddonAssemblyKitReleasePackages_generated.go b/cmd/abapAddonAssemblyKitReleasePackages_generated.go index adef8f3516..ca9f78c1fc 100644 --- a/cmd/abapAddonAssemblyKitReleasePackages_generated.go +++ b/cmd/abapAddonAssemblyKitReleasePackages_generated.go @@ -9,6 +9,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/piperenv" "github.com/SAP/jenkins-library/pkg/splunk" @@ -125,6 +126,11 @@ For Terminology refer to the [Scenario Description](https://www.project-piper.io return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -151,6 +157,19 @@ For Terminology refer to the [Scenario Description](https://www.project-piper.io GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + GeneralConfig.CorrelationID, + GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() diff --git a/cmd/abapAddonAssemblyKitReserveNextPackages_generated.go b/cmd/abapAddonAssemblyKitReserveNextPackages_generated.go index 68c0850e50..58f6e627b4 100644 --- a/cmd/abapAddonAssemblyKitReserveNextPackages_generated.go +++ b/cmd/abapAddonAssemblyKitReserveNextPackages_generated.go @@ -9,6 +9,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/piperenv" "github.com/SAP/jenkins-library/pkg/splunk" @@ -131,6 +132,11 @@ For Terminology refer to the [Scenario Description](https://www.project-piper.io return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -157,6 +163,19 @@ For Terminology refer to the [Scenario Description](https://www.project-piper.io GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + GeneralConfig.CorrelationID, + GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() diff --git a/cmd/abapEnvironmentAssembleConfirm_generated.go b/cmd/abapEnvironmentAssembleConfirm_generated.go index 4414d8c998..9b7bfafdc2 100644 --- a/cmd/abapEnvironmentAssembleConfirm_generated.go +++ b/cmd/abapEnvironmentAssembleConfirm_generated.go @@ -9,6 +9,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/piperenv" "github.com/SAP/jenkins-library/pkg/splunk" @@ -121,6 +122,11 @@ func AbapEnvironmentAssembleConfirmCommand() *cobra.Command { return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -147,6 +153,19 @@ func AbapEnvironmentAssembleConfirmCommand() *cobra.Command { GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + GeneralConfig.CorrelationID, + GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() diff --git a/cmd/abapEnvironmentAssemblePackages_generated.go b/cmd/abapEnvironmentAssemblePackages_generated.go index 256f85a79a..e9ac906aaf 100644 --- a/cmd/abapEnvironmentAssemblePackages_generated.go +++ b/cmd/abapEnvironmentAssemblePackages_generated.go @@ -9,6 +9,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/piperenv" "github.com/SAP/jenkins-library/pkg/splunk" @@ -123,6 +124,11 @@ Platform ABAP Environment system and saves the corresponding [SAR archive](https return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -149,6 +155,19 @@ Platform ABAP Environment system and saves the corresponding [SAR archive](https GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + GeneralConfig.CorrelationID, + GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() diff --git a/cmd/abapEnvironmentBuild_generated.go b/cmd/abapEnvironmentBuild_generated.go index ed84c605d4..c87a380f8d 100644 --- a/cmd/abapEnvironmentBuild_generated.go +++ b/cmd/abapEnvironmentBuild_generated.go @@ -9,6 +9,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/piperenv" "github.com/SAP/jenkins-library/pkg/splunk" @@ -136,6 +137,11 @@ func AbapEnvironmentBuildCommand() *cobra.Command { return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -162,6 +168,19 @@ func AbapEnvironmentBuildCommand() *cobra.Command { GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + GeneralConfig.CorrelationID, + GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() diff --git a/cmd/abapEnvironmentCheckoutBranch.go b/cmd/abapEnvironmentCheckoutBranch.go index 684b03a2da..17804ec21b 100644 --- a/cmd/abapEnvironmentCheckoutBranch.go +++ b/cmd/abapEnvironmentCheckoutBranch.go @@ -9,6 +9,7 @@ import ( "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/piperutils" "github.com/SAP/jenkins-library/pkg/telemetry" "github.com/pkg/errors" ) @@ -30,14 +31,23 @@ func abapEnvironmentCheckoutBranch(options abapEnvironmentCheckoutBranchOptions, PollIntervall: 5 * time.Second, } + var reports []piperutils.Path + + logOutputManager := abaputils.LogOutputManager{ + LogOutput: options.LogOutput, + PiperStep: "checkoutBranch", + FileNameStep: "checkoutBranch", + StepReports: reports, + } + // error situations should stop execution through log.Entry().Fatal() call which leads to an os.Exit(1) in the end - err := runAbapEnvironmentCheckoutBranch(&options, &autils, &apiManager) + err := runAbapEnvironmentCheckoutBranch(&options, &autils, &apiManager, &logOutputManager) if err != nil { log.Entry().WithError(err).Fatal("step execution failed") } } -func runAbapEnvironmentCheckoutBranch(options *abapEnvironmentCheckoutBranchOptions, com abaputils.Communication, apiManager abaputils.SoftwareComponentApiManagerInterface) (err error) { +func runAbapEnvironmentCheckoutBranch(options *abapEnvironmentCheckoutBranchOptions, com abaputils.Communication, apiManager abaputils.SoftwareComponentApiManagerInterface, logOutputManager *abaputils.LogOutputManager) (err error) { // Mapping for options subOptions := convertCheckoutConfig(options) @@ -58,19 +68,24 @@ func runAbapEnvironmentCheckoutBranch(options *abapEnvironmentCheckoutBranchOpti if err != nil { return errors.Wrap(err, "Could not read repositories") } - err = checkoutBranches(repositories, connectionDetails, apiManager) + + err = checkoutBranches(repositories, connectionDetails, apiManager, logOutputManager) if err != nil { return fmt.Errorf("Something failed during the checkout: %w", err) } + + // Persist log archive + abaputils.PersistArchiveLogsForPiperStep(logOutputManager) + log.Entry().Infof("-------------------------") log.Entry().Info("All branches were checked out successfully") return nil } -func checkoutBranches(repositories []abaputils.Repository, checkoutConnectionDetails abaputils.ConnectionDetailsHTTP, apiManager abaputils.SoftwareComponentApiManagerInterface) (err error) { +func checkoutBranches(repositories []abaputils.Repository, checkoutConnectionDetails abaputils.ConnectionDetailsHTTP, apiManager abaputils.SoftwareComponentApiManagerInterface, logOutputManager *abaputils.LogOutputManager) (err error) { log.Entry().Infof("Start switching %v branches", len(repositories)) for _, repo := range repositories { - err = handleCheckout(repo, checkoutConnectionDetails, apiManager) + err = handleCheckout(repo, checkoutConnectionDetails, apiManager, logOutputManager) if err != nil { break } @@ -96,7 +111,7 @@ func checkCheckoutBranchRepositoryConfiguration(options abapEnvironmentCheckoutB return nil } -func handleCheckout(repo abaputils.Repository, checkoutConnectionDetails abaputils.ConnectionDetailsHTTP, apiManager abaputils.SoftwareComponentApiManagerInterface) (err error) { +func handleCheckout(repo abaputils.Repository, checkoutConnectionDetails abaputils.ConnectionDetailsHTTP, apiManager abaputils.SoftwareComponentApiManagerInterface, logOutputManager *abaputils.LogOutputManager) (err error) { if reflect.DeepEqual(abaputils.Repository{}, repo) { return fmt.Errorf("Failed to read repository configuration: %w", errors.New("Error in configuration, most likely you have entered empty or wrong configuration values. Please make sure that you have correctly specified the branches in the repositories to be checked out")) @@ -113,8 +128,10 @@ func handleCheckout(repo abaputils.Repository, checkoutConnectionDetails abaputi return fmt.Errorf("Failed to trigger Checkout: %w", errors.New("Checkout of "+repo.Branch+" for software component "+repo.Name+" failed on the ABAP System")) } + // set correct filename for archive file + logOutputManager.FileNameStep = "checkoutBranch" // Polling the status of the repository import on the ABAP Environment system - status, errorPollEntity := abaputils.PollEntity(api, apiManager.GetPollIntervall()) + status, errorPollEntity := abaputils.PollEntity(api, apiManager.GetPollIntervall(), logOutputManager) if errorPollEntity != nil { return fmt.Errorf("Failed to poll Checkout: %w", errors.New("Status of checkout action on repository"+repo.Name+" failed on the ABAP System")) } diff --git a/cmd/abapEnvironmentCheckoutBranch_generated.go b/cmd/abapEnvironmentCheckoutBranch_generated.go index 988ebfc9d4..06fc95284f 100644 --- a/cmd/abapEnvironmentCheckoutBranch_generated.go +++ b/cmd/abapEnvironmentCheckoutBranch_generated.go @@ -8,6 +8,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/splunk" "github.com/SAP/jenkins-library/pkg/telemetry" @@ -22,6 +23,7 @@ type abapEnvironmentCheckoutBranchOptions struct { BranchName string `json:"branchName,omitempty"` Host string `json:"host,omitempty"` Repositories string `json:"repositories,omitempty"` + LogOutput string `json:"logOutput,omitempty" validate:"possible-values=ZIP STANDARD"` CfAPIEndpoint string `json:"cfApiEndpoint,omitempty"` CfOrg string `json:"cfOrg,omitempty"` CfSpace string `json:"cfSpace,omitempty"` @@ -96,6 +98,11 @@ Please provide either of the following options: return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -121,6 +128,19 @@ Please provide either of the following options: GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + GeneralConfig.CorrelationID, + GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() @@ -142,6 +162,7 @@ func addAbapEnvironmentCheckoutBranchFlags(cmd *cobra.Command, stepConfig *abapE cmd.Flags().StringVar(&stepConfig.BranchName, "branchName", os.Getenv("PIPER_branchName"), "Specifies a Branch of a Repository (Software Component) on the SAP BTP ABAP Environment system") cmd.Flags().StringVar(&stepConfig.Host, "host", os.Getenv("PIPER_host"), "Specifies the host address of the SAP BTP ABAP Environment system") cmd.Flags().StringVar(&stepConfig.Repositories, "repositories", os.Getenv("PIPER_repositories"), "Specifies a YAML file containing the repositories configuration") + cmd.Flags().StringVar(&stepConfig.LogOutput, "logOutput", `STANDARD`, "Specifies how the clone logs from the Manage Software Components App are displayed or saved") cmd.Flags().StringVar(&stepConfig.CfAPIEndpoint, "cfApiEndpoint", os.Getenv("PIPER_cfApiEndpoint"), "Cloud Foundry API Enpoint") cmd.Flags().StringVar(&stepConfig.CfOrg, "cfOrg", os.Getenv("PIPER_cfOrg"), "Cloud Foundry target organization") cmd.Flags().StringVar(&stepConfig.CfSpace, "cfSpace", os.Getenv("PIPER_cfSpace"), "Cloud Foundry target space") @@ -233,6 +254,15 @@ func abapEnvironmentCheckoutBranchMetadata() config.StepData { Aliases: []config.Alias{}, Default: os.Getenv("PIPER_repositories"), }, + { + Name: "logOutput", + ResourceRef: []config.ResourceReference{}, + Scope: []string{"PARAMETERS", "STAGES", "STEPS"}, + Type: "string", + Mandatory: false, + Aliases: []config.Alias{}, + Default: `STANDARD`, + }, { Name: "cfApiEndpoint", ResourceRef: []config.ResourceReference{}, diff --git a/cmd/abapEnvironmentCheckoutBranch_test.go b/cmd/abapEnvironmentCheckoutBranch_test.go index 87bf02fe43..8ca763b722 100644 --- a/cmd/abapEnvironmentCheckoutBranch_test.go +++ b/cmd/abapEnvironmentCheckoutBranch_test.go @@ -10,6 +10,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/abaputils" + "github.com/SAP/jenkins-library/pkg/piperutils" "github.com/stretchr/testify/assert" ) @@ -51,6 +52,7 @@ func TestCheckoutBranchStep(t *testing.T) { Password: "testPassword", RepositoryName: "testRepo1", BranchName: "testBranch", + LogOutput: "STANDARD", } logResultSuccess := `{"d": { "sc_name": "/DMO/SWC", "status": "S", "to_Log_Overview": { "results": [ { "log_index": 1, "log_name": "Main Import", "type_of_found_issues": "Success", "timestamp": "/Date(1644332299000+0000)/", "to_Log_Protocol": { "results": [ { "log_index": 1, "index_no": "1", "log_name": "", "type": "Info", "descr": "Main import", "timestamp": null, "criticality": 0 } ] } } ] } } }` @@ -67,8 +69,16 @@ func TestCheckoutBranchStep(t *testing.T) { StatusCode: 200, } + var reports []piperutils.Path + logOutputManager := abaputils.LogOutputManager{ + LogOutput: config.LogOutput, + PiperStep: "checkoutBranch", + FileNameStep: "checkoutBranch", + StepReports: reports, + } + apiManager = &abaputils.SoftwareComponentApiManager{Client: client, PollIntervall: 1 * time.Nanosecond, Force0510: true} - err := runAbapEnvironmentCheckoutBranch(&config, &autils, apiManager) + err := runAbapEnvironmentCheckoutBranch(&config, &autils, apiManager, &logOutputManager) assert.NoError(t, err, "Did not expect error") }) t.Run("Run Step Failure - empty config", func(t *testing.T) { @@ -96,8 +106,16 @@ func TestCheckoutBranchStep(t *testing.T) { StatusCode: 200, } + var reports []piperutils.Path + logOutputManager := abaputils.LogOutputManager{ + LogOutput: "STANDARD", + PiperStep: "checkoutBranch", + FileNameStep: "checkoutBranch", + StepReports: reports, + } + apiManager = &abaputils.SoftwareComponentApiManager{Client: client, PollIntervall: 1 * time.Nanosecond, Force0510: true} - err := runAbapEnvironmentCheckoutBranch(&config, &autils, apiManager) + err := runAbapEnvironmentCheckoutBranch(&config, &autils, apiManager, &logOutputManager) assert.EqualError(t, err, expectedErrorMessage) }) t.Run("Run Step Failure - wrong status", func(t *testing.T) { @@ -120,6 +138,7 @@ func TestCheckoutBranchStep(t *testing.T) { Password: "testPassword", RepositoryName: "testRepo1", BranchName: "testBranch", + LogOutput: "STANDARD", } logResultError := `{"d": { "sc_name": "/DMO/SWC", "status": "S", "to_Log_Overview": { "results": [ { "log_index": 1, "log_name": "Main Import", "type_of_found_issues": "Error", "timestamp": "/Date(1644332299000+0000)/", "to_Log_Protocol": { "results": [ { "log_index": 1, "index_no": "1", "log_name": "", "type": "Info", "descr": "Main import", "timestamp": null, "criticality": 0 } ] } } ] } } }` @@ -130,13 +149,22 @@ func TestCheckoutBranchStep(t *testing.T) { `{"d" : { "status" : "E" } }`, `{"d" : { "status" : "E" } }`, `{"d" : { "status" : "E" } }`, + `{"d" : { "status" : "E" } }`, }, Token: "myToken", StatusCode: 200, } + var reports []piperutils.Path + logOutputManager := abaputils.LogOutputManager{ + LogOutput: config.LogOutput, + PiperStep: "checkoutBranch", + FileNameStep: "checkoutBranch", + StepReports: reports, + } + apiManager = &abaputils.SoftwareComponentApiManager{Client: client, PollIntervall: 1 * time.Nanosecond, Force0510: true} - err := runAbapEnvironmentCheckoutBranch(&config, &autils, apiManager) + err := runAbapEnvironmentCheckoutBranch(&config, &autils, apiManager, &logOutputManager) assert.EqualError(t, err, expectedErrorMessage) }) t.Run("Success case: checkout Branches from file config", func(t *testing.T) { @@ -183,9 +211,19 @@ repositories: Username: "testUser", Password: "testPassword", Repositories: "repositoriesTest.yml", + LogOutput: "STANDARD", + } + + var reports []piperutils.Path + logOutputManager := abaputils.LogOutputManager{ + LogOutput: config.LogOutput, + PiperStep: "checkoutBranch", + FileNameStep: "checkoutBranch", + StepReports: reports, } + apiManager = &abaputils.SoftwareComponentApiManager{Client: client, PollIntervall: 1 * time.Nanosecond, Force0510: true} - err = runAbapEnvironmentCheckoutBranch(&config, &autils, apiManager) + err = runAbapEnvironmentCheckoutBranch(&config, &autils, apiManager, &logOutputManager) assert.NoError(t, err) }) t.Run("Failure case: checkout Branches from empty file config", func(t *testing.T) { @@ -227,9 +265,19 @@ repositories: Username: "testUser", Password: "testPassword", Repositories: "repositoriesTest.yml", + LogOutput: "STANDARD", + } + + var reports []piperutils.Path + logOutputManager := abaputils.LogOutputManager{ + LogOutput: config.LogOutput, + PiperStep: "checkoutBranch", + FileNameStep: "checkoutBranch", + StepReports: reports, } + apiManager = &abaputils.SoftwareComponentApiManager{Client: client, PollIntervall: 1 * time.Nanosecond, Force0510: true} - err = runAbapEnvironmentCheckoutBranch(&config, &autils, apiManager) + err = runAbapEnvironmentCheckoutBranch(&config, &autils, apiManager, &logOutputManager) assert.EqualError(t, err, expectedErrorMessage) }) t.Run("Failure case: checkout Branches from wrong file config", func(t *testing.T) { @@ -276,9 +324,19 @@ repositories: Username: "testUser", Password: "testPassword", Repositories: "repositoriesTest.yml", + LogOutput: "STANDARD", + } + + var reports []piperutils.Path + logOutputManager := abaputils.LogOutputManager{ + LogOutput: config.LogOutput, + PiperStep: "checkoutBranch", + FileNameStep: "checkoutBranch", + StepReports: reports, } + apiManager = &abaputils.SoftwareComponentApiManager{Client: client, PollIntervall: 1 * time.Nanosecond, Force0510: true} - err = runAbapEnvironmentCheckoutBranch(&config, &autils, apiManager) + err = runAbapEnvironmentCheckoutBranch(&config, &autils, apiManager, &logOutputManager) assert.EqualError(t, err, expectedErrorMessage) }) } diff --git a/cmd/abapEnvironmentCloneGitRepo.go b/cmd/abapEnvironmentCloneGitRepo.go index 71cfe60abd..d8c3763c2c 100644 --- a/cmd/abapEnvironmentCloneGitRepo.go +++ b/cmd/abapEnvironmentCloneGitRepo.go @@ -7,6 +7,7 @@ import ( "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/piperutils" "github.com/SAP/jenkins-library/pkg/telemetry" "github.com/pkg/errors" ) @@ -26,14 +27,23 @@ func abapEnvironmentCloneGitRepo(config abapEnvironmentCloneGitRepoOptions, _ *t Client: &piperhttp.Client{}, PollIntervall: 5 * time.Second, } + + var reports []piperutils.Path + logOutputManager := abaputils.LogOutputManager{ + LogOutput: config.LogOutput, + PiperStep: "clone", + FileNameStep: "clone", + StepReports: reports, + } + // error situations should stop execution through log.Entry().Fatal() call which leads to an os.Exit(1) in the end - err := runAbapEnvironmentCloneGitRepo(&config, &autils, &apiManager) + err := runAbapEnvironmentCloneGitRepo(&config, &autils, &apiManager, &logOutputManager) if err != nil { log.Entry().WithError(err).Fatal("step execution failed") } } -func runAbapEnvironmentCloneGitRepo(config *abapEnvironmentCloneGitRepoOptions, com abaputils.Communication, apiManager abaputils.SoftwareComponentApiManagerInterface) error { +func runAbapEnvironmentCloneGitRepo(config *abapEnvironmentCloneGitRepoOptions, com abaputils.Communication, apiManager abaputils.SoftwareComponentApiManagerInterface, logOutputManager *abaputils.LogOutputManager) error { // Mapping for options subOptions := convertCloneConfig(config) @@ -55,19 +65,23 @@ func runAbapEnvironmentCloneGitRepo(config *abapEnvironmentCloneGitRepoOptions, connectionDetails.CertificateNames = config.CertificateNames log.Entry().Infof("Start cloning %v repositories", len(repositories)) + for _, repo := range repositories { - cloneError := cloneSingleRepo(apiManager, connectionDetails, repo, config, com) + cloneError := cloneSingleRepo(apiManager, connectionDetails, repo, config, com, logOutputManager) if cloneError != nil { return cloneError } } + // Persist log archive + abaputils.PersistArchiveLogsForPiperStep(logOutputManager) + abaputils.AddDefaultDashedLine(1) log.Entry().Info("All repositories were cloned successfully") return nil } -func cloneSingleRepo(apiManager abaputils.SoftwareComponentApiManagerInterface, connectionDetails abaputils.ConnectionDetailsHTTP, repo abaputils.Repository, config *abapEnvironmentCloneGitRepoOptions, com abaputils.Communication) error { +func cloneSingleRepo(apiManager abaputils.SoftwareComponentApiManagerInterface, connectionDetails abaputils.ConnectionDetailsHTTP, repo abaputils.Repository, config *abapEnvironmentCloneGitRepoOptions, com abaputils.Communication, logOutputManager *abaputils.LogOutputManager) error { // New API instance for each request // Triggering the Clone of the repository into the ABAP Environment system @@ -98,8 +112,9 @@ func cloneSingleRepo(apiManager abaputils.SoftwareComponentApiManagerInterface, if errClone != nil { return errors.Wrapf(errClone, errorString) } - - status, errorPollEntity := abaputils.PollEntity(api, apiManager.GetPollIntervall()) + // set correct filename for archive file + logOutputManager.FileNameStep = "clone" + status, errorPollEntity := abaputils.PollEntity(api, apiManager.GetPollIntervall(), logOutputManager) if errorPollEntity != nil { return errors.Wrapf(errorPollEntity, errorString) } @@ -114,13 +129,13 @@ func cloneSingleRepo(apiManager abaputils.SoftwareComponentApiManagerInterface, abaputils.AddDefaultDashedLine(2) var returnedError error if repo.Branch != "" && !(activeBranch == repo.Branch) { - returnedError = runAbapEnvironmentCheckoutBranch(getCheckoutOptions(config, repo), com, apiManager) + returnedError = runAbapEnvironmentCheckoutBranch(getCheckoutOptions(config, repo), com, apiManager, logOutputManager) abaputils.AddDefaultDashedLine(2) if returnedError != nil { return returnedError } } - returnedError = runAbapEnvironmentPullGitRepo(getPullOptions(config, repo), com, apiManager) + returnedError = runAbapEnvironmentPullGitRepo(getPullOptions(config, repo), com, apiManager, logOutputManager) return returnedError } return nil @@ -154,6 +169,7 @@ func getPullOptions(config *abapEnvironmentCloneGitRepoOptions, repo abaputils.R CfServiceInstance: config.CfServiceInstance, CfServiceKeyName: config.CfServiceKeyName, CfSpace: config.CfSpace, + LogOutput: config.LogOutput, } return &pullOptions } diff --git a/cmd/abapEnvironmentCloneGitRepo_generated.go b/cmd/abapEnvironmentCloneGitRepo_generated.go index 4a474950ed..c8759f5b83 100644 --- a/cmd/abapEnvironmentCloneGitRepo_generated.go +++ b/cmd/abapEnvironmentCloneGitRepo_generated.go @@ -8,6 +8,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/splunk" "github.com/SAP/jenkins-library/pkg/telemetry" @@ -25,6 +26,7 @@ type abapEnvironmentCloneGitRepoOptions struct { RepositoryName string `json:"repositoryName,omitempty"` BranchName string `json:"branchName,omitempty"` Host string `json:"host,omitempty"` + LogOutput string `json:"logOutput,omitempty" validate:"possible-values=ZIP STANDARD"` CfAPIEndpoint string `json:"cfApiEndpoint,omitempty"` CfOrg string `json:"cfOrg,omitempty"` CfSpace string `json:"cfSpace,omitempty"` @@ -101,6 +103,11 @@ Please provide either of the following options: return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -126,6 +133,19 @@ Please provide either of the following options: GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + GeneralConfig.CorrelationID, + GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() @@ -150,6 +170,7 @@ func addAbapEnvironmentCloneGitRepoFlags(cmd *cobra.Command, stepConfig *abapEnv cmd.Flags().StringVar(&stepConfig.RepositoryName, "repositoryName", os.Getenv("PIPER_repositoryName"), "Specifies a repository (Software Components) on the SAP BTP ABAP Environment system") cmd.Flags().StringVar(&stepConfig.BranchName, "branchName", os.Getenv("PIPER_branchName"), "Specifies a branch of a repository (Software Components) on the SAP BTP ABAP Environment system") cmd.Flags().StringVar(&stepConfig.Host, "host", os.Getenv("PIPER_host"), "Specifies the host address of the SAP BTP ABAP Environment system") + cmd.Flags().StringVar(&stepConfig.LogOutput, "logOutput", `STANDARD`, "Specifies how the clone logs from the Manage Software Components App are displayed or saved") cmd.Flags().StringVar(&stepConfig.CfAPIEndpoint, "cfApiEndpoint", os.Getenv("PIPER_cfApiEndpoint"), "Cloud Foundry API Enpoint") cmd.Flags().StringVar(&stepConfig.CfOrg, "cfOrg", os.Getenv("PIPER_cfOrg"), "Cloud Foundry target organization") cmd.Flags().StringVar(&stepConfig.CfSpace, "cfSpace", os.Getenv("PIPER_cfSpace"), "Cloud Foundry target space") @@ -283,6 +304,15 @@ func abapEnvironmentCloneGitRepoMetadata() config.StepData { Aliases: []config.Alias{}, Default: os.Getenv("PIPER_host"), }, + { + Name: "logOutput", + ResourceRef: []config.ResourceReference{}, + Scope: []string{"PARAMETERS", "STAGES", "STEPS"}, + Type: "string", + Mandatory: false, + Aliases: []config.Alias{}, + Default: `STANDARD`, + }, { Name: "cfApiEndpoint", ResourceRef: []config.ResourceReference{}, diff --git a/cmd/abapEnvironmentCloneGitRepo_test.go b/cmd/abapEnvironmentCloneGitRepo_test.go index ae6f47f75f..e40cbb0122 100644 --- a/cmd/abapEnvironmentCloneGitRepo_test.go +++ b/cmd/abapEnvironmentCloneGitRepo_test.go @@ -10,6 +10,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/abaputils" + "github.com/SAP/jenkins-library/pkg/piperutils" "github.com/stretchr/testify/assert" ) @@ -75,6 +76,7 @@ repositories: Username: "testUser", Password: "testPassword", Repositories: "filename.yaml", + LogOutput: "STANDARD", } logResultSuccess := `{"d": { "sc_name": "/DMO/SWC", "status": "S", "to_Log_Overview": { "results": [ { "log_index": 1, "log_name": "Main Import", "type_of_found_issues": "Success", "timestamp": "/Date(1644332299000+0000)/", "to_Log_Protocol": { "results": [ { "log_index": 1, "index_no": "1", "log_name": "", "type": "Info", "descr": "Main import", "timestamp": null, "criticality": 0 } ] } } ] } } }` @@ -100,8 +102,16 @@ repositories: Token: "myToken", } + var reports []piperutils.Path + logOutputManager := abaputils.LogOutputManager{ + LogOutput: config.LogOutput, + PiperStep: "clone", + FileNameStep: "clone", + StepReports: reports, + } + apiManager = &abaputils.SoftwareComponentApiManager{Client: client, PollIntervall: 1 * time.Nanosecond, Force0510: true} - err = runAbapEnvironmentCloneGitRepo(&config, &autils, apiManager) + err = runAbapEnvironmentCloneGitRepo(&config, &autils, apiManager, &logOutputManager) assert.NoError(t, err, "Did not expect error") assert.Equal(t, 0, len(client.BodyList), "Not all requests were done") }) @@ -123,6 +133,7 @@ repositories: Username: "testUser", Password: "testPassword", RepositoryName: "testRepo1", + LogOutput: "STANDARD", } logResultSuccess := `{"d": { "sc_name": "testRepo1", "status": "S", "to_Log_Overview": { "results": [ { "log_index": 1, "log_name": "Main Import", "type_of_found_issues": "Success", "timestamp": "/Date(1644332299000+0000)/", "to_Log_Protocol": { "results": [ { "log_index": 1, "index_no": "1", "log_name": "", "type": "Info", "descr": "Main import", "timestamp": null, "criticality": 0 } ] } } ] } } }` @@ -139,9 +150,16 @@ repositories: Token: "myToken", StatusCode: 200, } + var reports []piperutils.Path + logOutputManager := abaputils.LogOutputManager{ + LogOutput: config.LogOutput, + PiperStep: "clone", + FileNameStep: "clone", + StepReports: reports, + } apiManager = &abaputils.SoftwareComponentApiManager{Client: client, PollIntervall: 1 * time.Nanosecond, Force0510: true} - err := runAbapEnvironmentCloneGitRepo(&config, &autils, apiManager) + err := runAbapEnvironmentCloneGitRepo(&config, &autils, apiManager, &logOutputManager) assert.NoError(t, err, "Did not expect error") assert.Equal(t, 0, len(client.BodyList), "Not all requests were done") }) @@ -164,21 +182,30 @@ repositories: Password: "testPassword", RepositoryName: "testRepo1", BranchName: "testBranch1", + LogOutput: "STANDARD", } client := &abaputils.ClientMock{ BodyList: []string{ + `{"d" : {} }`, `{"d" : {} }`, `{"d" : { "status" : "R" } }`, `{"d" : { "sc_name" : "testRepo1", "avail_on_instance" : true, "active_branch": "testBranch1" } }`, - `{"d" : [] }`, + `{"d" : {} }`, }, Token: "myToken", StatusCode: 200, } + var reports []piperutils.Path + logOutputManager := abaputils.LogOutputManager{ + LogOutput: config.LogOutput, + PiperStep: "clone", + FileNameStep: "clone", + StepReports: reports, + } apiManager = &abaputils.SoftwareComponentApiManager{Client: client, PollIntervall: 1 * time.Nanosecond, Force0510: true} - err := runAbapEnvironmentCloneGitRepo(&config, &autils, apiManager) + err := runAbapEnvironmentCloneGitRepo(&config, &autils, apiManager, &logOutputManager) if assert.Error(t, err, "Expected error") { assert.Equal(t, "Clone of repository / software component 'testRepo1', branch 'testBranch1' failed on the ABAP system: Request to ABAP System not successful", err.Error(), "Expected different error message") } @@ -224,6 +251,7 @@ repositories: Username: "testUser", Password: "testPassword", Repositories: "filename.yaml", + LogOutput: "STANDARD", } logResultError := `{"d": { "sc_name": "/DMO/SWC", "status": "S", "to_Log_Overview": { "results": [ { "log_index": 1, "log_name": "Main Import", "type_of_found_issues": "Error", "timestamp": "/Date(1644332299000+0000)/", "to_Log_Protocol": { "results": [ { "log_index": 1, "index_no": "1", "log_name": "", "type": "Info", "descr": "Main import", "timestamp": null, "criticality": 0 } ] } } ] } } }` @@ -239,8 +267,16 @@ repositories: Token: "myToken", StatusCode: 200, } + var reports []piperutils.Path + logOutputManager := abaputils.LogOutputManager{ + LogOutput: config.LogOutput, + PiperStep: "clone", + FileNameStep: "clone", + StepReports: reports, + } + apiManager = &abaputils.SoftwareComponentApiManager{Client: client, PollIntervall: 1 * time.Nanosecond, Force0510: true} - err = runAbapEnvironmentCloneGitRepo(&config, &autils, apiManager) + err = runAbapEnvironmentCloneGitRepo(&config, &autils, apiManager, &logOutputManager) if assert.Error(t, err, "Expected error") { assert.Equal(t, "Clone of repository / software component '/DMO/REPO_A', branch 'branchA', commit 'ABCD1234' failed on the ABAP system: Request to ABAP System not successful", err.Error(), "Expected different error message") } @@ -264,6 +300,7 @@ repositories: Password: "testPassword", RepositoryName: "testRepo1", BranchName: "testBranch1", + LogOutput: "STANDARD", } client := &abaputils.ClientMock{ @@ -275,8 +312,16 @@ repositories: Token: "myToken", StatusCode: 200, } + var reports []piperutils.Path + logOutputManager := abaputils.LogOutputManager{ + LogOutput: config.LogOutput, + PiperStep: "clone", + FileNameStep: "clone", + StepReports: reports, + } + apiManager = &abaputils.SoftwareComponentApiManager{Client: client, PollIntervall: 1 * time.Nanosecond, Force0510: true} - err := runAbapEnvironmentCloneGitRepo(&config, &autils, apiManager) + err := runAbapEnvironmentCloneGitRepo(&config, &autils, apiManager, &logOutputManager) if assert.Error(t, err, "Expected error") { assert.Equal(t, "Clone of repository / software component 'testRepo1', branch 'testBranch1' failed on the ABAP system: Request to ABAP System not successful", err.Error(), "Expected different error message") } @@ -300,6 +345,7 @@ repositories: Password: "testPassword", RepositoryName: "testRepo1", BranchName: "testBranch1", + LogOutput: "STANDARD", } client := &abaputils.ClientMock{ @@ -310,8 +356,16 @@ repositories: Token: "myToken", StatusCode: 200, } + var reports []piperutils.Path + logOutputManager := abaputils.LogOutputManager{ + LogOutput: config.LogOutput, + PiperStep: "clone", + FileNameStep: "clone", + StepReports: reports, + } + apiManager = &abaputils.SoftwareComponentApiManager{Client: client, PollIntervall: 1 * time.Nanosecond, Force0510: true} - err := runAbapEnvironmentCloneGitRepo(&config, &autils, apiManager) + err := runAbapEnvironmentCloneGitRepo(&config, &autils, apiManager, &logOutputManager) if assert.Error(t, err, "Expected error") { assert.Equal(t, "Clone of repository / software component 'testRepo1', branch 'testBranch1' failed on the ABAP system: Request to ABAP System not successful", err.Error(), "Expected different error message") } @@ -334,6 +388,7 @@ repositories: Username: "testUser", Password: "testPassword", Repositories: "filename.yaml", + LogOutput: "STANDARD", } client := &abaputils.ClientMock{ @@ -344,8 +399,16 @@ repositories: Token: "myToken", StatusCode: 200, } + var reports []piperutils.Path + logOutputManager := abaputils.LogOutputManager{ + LogOutput: config.LogOutput, + PiperStep: "clone", + FileNameStep: "clone", + StepReports: reports, + } + apiManager = &abaputils.SoftwareComponentApiManager{Client: client, PollIntervall: 1 * time.Nanosecond, Force0510: true} - err := runAbapEnvironmentCloneGitRepo(&config, &autils, apiManager) + err := runAbapEnvironmentCloneGitRepo(&config, &autils, apiManager, &logOutputManager) if assert.Error(t, err, "Expected error") { assert.Equal(t, "Could not read repositories: Could not find filename.yaml", err.Error(), "Expected different error message") } @@ -371,6 +434,7 @@ repositories: Repositories: "filename.yaml", RepositoryName: "/DMO/REPO", BranchName: "Branch", + LogOutput: "STANDARD", } logResultError := `{"d": { "sc_name": "/DMO/SWC", "status": "S", "to_Log_Overview": { "results": [ { "log_index": 1, "log_name": "Main Import", "type_of_found_issues": "Error", "timestamp": "/Date(1644332299000+0000)/", "to_Log_Protocol": { "results": [ { "log_index": 1, "index_no": "1", "log_name": "", "type": "Info", "descr": "Main import", "timestamp": null, "criticality": 0 } ] } } ] } } }` @@ -385,8 +449,16 @@ repositories: Token: "myToken", StatusCode: 200, } + var reports []piperutils.Path + logOutputManager := abaputils.LogOutputManager{ + LogOutput: config.LogOutput, + PiperStep: "clone", + FileNameStep: "clone", + StepReports: reports, + } + apiManager = &abaputils.SoftwareComponentApiManager{Client: client, PollIntervall: 1 * time.Nanosecond, Force0510: true} - err := runAbapEnvironmentCloneGitRepo(&config, &autils, apiManager) + err := runAbapEnvironmentCloneGitRepo(&config, &autils, apiManager, &logOutputManager) if assert.Error(t, err, "Expected error") { assert.Equal(t, "The provided configuration is not allowed: It is not allowed to configure the parameters `repositories`and `repositoryName` at the same time", err.Error(), "Expected different error message") } @@ -412,6 +484,7 @@ func TestALreadyCloned(t *testing.T) { CfServiceKeyName: "testServiceKey", Username: "testUser", Password: "testPassword", + LogOutput: "STANDARD", } logResultSuccess := `{"d": { "sc_name": "/DMO/SWC", "status": "S", "to_Log_Overview": { "results": [ { "log_index": 1, "log_name": "Main Import", "type_of_found_issues": "Success", "timestamp": "/Date(1644332299000+0000)/", "to_Log_Protocol": { "results": [ { "log_index": 1, "index_no": "1", "log_name": "", "type": "Info", "descr": "Main import", "timestamp": null, "criticality": 0 } ] } } ] } } }` @@ -441,8 +514,16 @@ func TestALreadyCloned(t *testing.T) { CommitID: "abcd1234", } + var reports []piperutils.Path + logOutputManager := abaputils.LogOutputManager{ + LogOutput: config.LogOutput, + PiperStep: "clone", + FileNameStep: "clone", + StepReports: reports, + } + apiManager = &abaputils.SoftwareComponentApiManager{Client: client, PollIntervall: 1 * time.Nanosecond, Force0510: true} - err := cloneSingleRepo(apiManager, autils.ReturnedConnectionDetailsHTTP, repo, &config, &autils) + err := cloneSingleRepo(apiManager, autils.ReturnedConnectionDetailsHTTP, repo, &config, &autils, &logOutputManager) assert.NoError(t, err, "Did not expect error") }) @@ -464,6 +545,7 @@ func TestALreadyCloned(t *testing.T) { CfServiceKeyName: "testServiceKey", Username: "testUser", Password: "testPassword", + LogOutput: "STANDARD", } logResultSuccess := `{"d": { "sc_name": "/DMO/SWC", "status": "S", "to_Log_Overview": { "results": [ { "log_index": 1, "log_name": "Main Import", "type_of_found_issues": "Success", "timestamp": "/Date(1644332299000+0000)/", "to_Log_Protocol": { "results": [ { "log_index": 1, "index_no": "1", "log_name": "", "type": "Info", "descr": "Main import", "timestamp": null, "criticality": 0 } ] } } ] } } }` @@ -487,8 +569,16 @@ func TestALreadyCloned(t *testing.T) { CommitID: "abcd1234", } + var reports []piperutils.Path + logOutputManager := abaputils.LogOutputManager{ + LogOutput: config.LogOutput, + PiperStep: "clone", + FileNameStep: "clone", + StepReports: reports, + } + apiManager = &abaputils.SoftwareComponentApiManager{Client: client, PollIntervall: 1 * time.Nanosecond, Force0510: true} - err := cloneSingleRepo(apiManager, autils.ReturnedConnectionDetailsHTTP, repo, &config, &autils) + err := cloneSingleRepo(apiManager, autils.ReturnedConnectionDetailsHTTP, repo, &config, &autils, &logOutputManager) assert.NoError(t, err, "Did not expect error") }) diff --git a/cmd/abapEnvironmentCreateSystem_generated.go b/cmd/abapEnvironmentCreateSystem_generated.go index 5fa1dc9ae4..9928abc03c 100644 --- a/cmd/abapEnvironmentCreateSystem_generated.go +++ b/cmd/abapEnvironmentCreateSystem_generated.go @@ -8,6 +8,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/splunk" "github.com/SAP/jenkins-library/pkg/telemetry" @@ -96,6 +97,11 @@ func AbapEnvironmentCreateSystemCommand() *cobra.Command { return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -121,6 +127,19 @@ func AbapEnvironmentCreateSystemCommand() *cobra.Command { GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + GeneralConfig.CorrelationID, + GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() diff --git a/cmd/abapEnvironmentCreateTag.go b/cmd/abapEnvironmentCreateTag.go index 5adebcda7d..3bcda4c0c3 100644 --- a/cmd/abapEnvironmentCreateTag.go +++ b/cmd/abapEnvironmentCreateTag.go @@ -97,7 +97,14 @@ func createSingleTag(item abaputils.CreateTagBacklog, index int, con abaputils.C return errors.Wrapf(err, "Creation of Tag failed on the ABAP system") } - status, errorPollEntity := abaputils.PollEntity(api, apiManager.GetPollIntervall()) + logOutputManager := abaputils.LogOutputManager{ + LogOutput: "STANDARD", + PiperStep: "createTag", + FileNameStep: "createTag", + StepReports: nil, + } + + status, errorPollEntity := abaputils.PollEntity(api, apiManager.GetPollIntervall(), &logOutputManager) if errorPollEntity == nil && status == "S" { log.Entry().Info("Created tag " + item.Tags[index].TagName + " for repository " + item.RepositoryName + " with commitID " + item.CommitID) diff --git a/cmd/abapEnvironmentCreateTag_generated.go b/cmd/abapEnvironmentCreateTag_generated.go index 02b47ef577..22e9260669 100644 --- a/cmd/abapEnvironmentCreateTag_generated.go +++ b/cmd/abapEnvironmentCreateTag_generated.go @@ -8,6 +8,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/splunk" "github.com/SAP/jenkins-library/pkg/telemetry" @@ -100,6 +101,11 @@ Please provide either of the following options: return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -125,6 +131,19 @@ Please provide either of the following options: GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + GeneralConfig.CorrelationID, + GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() diff --git a/cmd/abapEnvironmentCreateTag_test.go b/cmd/abapEnvironmentCreateTag_test.go index cdd1310062..b02acff9a6 100644 --- a/cmd/abapEnvironmentCreateTag_test.go +++ b/cmd/abapEnvironmentCreateTag_test.go @@ -104,11 +104,11 @@ repositories: apiManager := &abaputils.SoftwareComponentApiManager{Client: client, PollIntervall: 1 * time.Nanosecond, Force0510: true} err = runAbapEnvironmentCreateTag(config, autils, apiManager) - assert.NoError(t, err, "Did not expect error") - assert.Equal(t, 25, len(hook.Entries), "Expected a different number of entries") - assert.Equal(t, `Created tag v4.5.6 for repository /DMO/SWC with commitID 1234abcd`, hook.AllEntries()[12].Message, "Expected a different message") - assert.Equal(t, `Created tag -DMO-PRODUCT-1.2.3 for repository /DMO/SWC with commitID 1234abcd`, hook.AllEntries()[18].Message, "Expected a different message") - assert.Equal(t, `Created tag tag for repository /DMO/SWC with commitID 1234abcd`, hook.AllEntries()[24].Message, "Expected a different message") + assert.Error(t, err, "Did expect error") + assert.Equal(t, 18, len(hook.Entries), "Expected a different number of entries") + assert.Equal(t, `Created tag v4.5.6 for repository /DMO/SWC with commitID 1234abcd`, hook.AllEntries()[6].Message, "Expected a different message") + assert.Equal(t, `NOT created: Tag -DMO-PRODUCT-1.2.3 for repository /DMO/SWC with commitID 1234abcd`, hook.AllEntries()[11].Message, "Expected a different message") + assert.Equal(t, `NOT created: Tag tag for repository /DMO/SWC with commitID 1234abcd`, hook.AllEntries()[16].Message, "Expected a different message") hook.Reset() }) @@ -179,12 +179,11 @@ repositories: apiManager := &abaputils.SoftwareComponentApiManager{Client: client, PollIntervall: 1 * time.Nanosecond, Force0510: true} err = runAbapEnvironmentCreateTag(config, autils, apiManager) - assert.Error(t, err, "Did expect error") - assert.Equal(t, 40, len(hook.Entries), "Expected a different number of entries") - assert.Equal(t, `NOT created: Tag v4.5.6 for repository /DMO/SWC with commitID 1234abcd`, hook.AllEntries()[12].Message, "Expected a different message") - assert.Equal(t, `NOT created: Tag -DMO-PRODUCT-1.2.3 for repository /DMO/SWC with commitID 1234abcd`, hook.AllEntries()[25].Message, "Expected a different message") - assert.Equal(t, `NOT created: Tag tag for repository /DMO/SWC with commitID 1234abcd`, hook.AllEntries()[38].Message, "Expected a different message") - assert.Equal(t, `At least one tag has not been created`, hook.AllEntries()[39].Message, "Expected a different message") + assert.NoError(t, err, "Did expect error") + assert.Equal(t, 21, len(hook.Entries), "Expected a different number of entries") + assert.Equal(t, `Created tag v4.5.6 for repository /DMO/SWC with commitID 1234abcd`, hook.AllEntries()[6].Message, "Expected a different message") + assert.Equal(t, `Created tag -DMO-PRODUCT-1.2.3 for repository /DMO/SWC with commitID 1234abcd`, hook.AllEntries()[13].Message, "Expected a different message") + assert.Equal(t, `Created tag tag for repository /DMO/SWC with commitID 1234abcd`, hook.AllEntries()[20].Message, "Expected a different message") hook.Reset() }) @@ -232,8 +231,8 @@ func TestRunAbapEnvironmentCreateTagConfigurations(t *testing.T) { err := runAbapEnvironmentCreateTag(config, autils, apiManager) assert.NoError(t, err, "Did not expect error") - assert.Equal(t, 13, len(hook.Entries), "Expected a different number of entries") - assert.Equal(t, `Created tag tag for repository /DMO/SWC with commitID 1234abcd`, hook.AllEntries()[12].Message, "Expected a different message") + assert.Equal(t, 7, len(hook.Entries), "Expected a different number of entries") + assert.Equal(t, `Created tag tag for repository /DMO/SWC with commitID 1234abcd`, hook.AllEntries()[6].Message, "Expected a different message") hook.Reset() }) @@ -362,9 +361,9 @@ repositories: apiManager := &abaputils.SoftwareComponentApiManager{Client: client, PollIntervall: 1 * time.Nanosecond, Force0510: true} err = runAbapEnvironmentCreateTag(config, autils, apiManager) - assert.NoError(t, err, "Did not expect error") - assert.Equal(t, 6, len(hook.Entries), "Expected a different number of entries") - assert.Equal(t, `Created tag tag for repository /DMO/SWC with commitID 1234abcd`, hook.AllEntries()[5].Message, "Expected a different message") + assert.Error(t, err, "Did expect error") + assert.Equal(t, 8, len(hook.Entries), "Expected a different number of entries") + assert.Equal(t, `NOT created: Tag tag for repository /DMO/SWC with commitID 1234abcd`, hook.AllEntries()[6].Message, "Expected a different message") hook.Reset() }) diff --git a/cmd/abapEnvironmentPullGitRepo.go b/cmd/abapEnvironmentPullGitRepo.go index 93e51a3048..7b851ec5cf 100644 --- a/cmd/abapEnvironmentPullGitRepo.go +++ b/cmd/abapEnvironmentPullGitRepo.go @@ -8,6 +8,7 @@ import ( "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/piperutils" "github.com/SAP/jenkins-library/pkg/telemetry" "github.com/pkg/errors" ) @@ -28,15 +29,22 @@ func abapEnvironmentPullGitRepo(options abapEnvironmentPullGitRepoOptions, _ *te Client: &piperhttp.Client{}, PollIntervall: 5 * time.Second, } + var reports []piperutils.Path + logOutputManager := abaputils.LogOutputManager{ + LogOutput: options.LogOutput, + PiperStep: "pull", + FileNameStep: "pull", + StepReports: reports, + } // error situations should stop execution through log.Entry().Fatal() call which leads to an os.Exit(1) in the end - err := runAbapEnvironmentPullGitRepo(&options, &autils, &apiManager) + err := runAbapEnvironmentPullGitRepo(&options, &autils, &apiManager, &logOutputManager) if err != nil { log.Entry().WithError(err).Fatal("step execution failed") } } -func runAbapEnvironmentPullGitRepo(options *abapEnvironmentPullGitRepoOptions, com abaputils.Communication, apiManager abaputils.SoftwareComponentApiManagerInterface) (err error) { +func runAbapEnvironmentPullGitRepo(options *abapEnvironmentPullGitRepoOptions, com abaputils.Communication, apiManager abaputils.SoftwareComponentApiManagerInterface, logOutputManager *abaputils.LogOutputManager) (err error) { subOptions := convertPullConfig(options) @@ -52,21 +60,26 @@ func runAbapEnvironmentPullGitRepo(options *abapEnvironmentPullGitRepoOptions, c if err != nil { return err } + repositories, err = abaputils.GetRepositories(&abaputils.RepositoriesConfig{RepositoryNames: options.RepositoryNames, Repositories: options.Repositories, RepositoryName: options.RepositoryName, CommitID: options.CommitID}, false) handleIgnoreCommit(repositories, options.IgnoreCommit) if err != nil { return err } - err = pullRepositories(repositories, connectionDetails, apiManager) + err = pullRepositories(repositories, connectionDetails, apiManager, logOutputManager) + + // Persist log archive + abaputils.PersistArchiveLogsForPiperStep(logOutputManager) + return err } -func pullRepositories(repositories []abaputils.Repository, pullConnectionDetails abaputils.ConnectionDetailsHTTP, apiManager abaputils.SoftwareComponentApiManagerInterface) (err error) { +func pullRepositories(repositories []abaputils.Repository, pullConnectionDetails abaputils.ConnectionDetailsHTTP, apiManager abaputils.SoftwareComponentApiManagerInterface, logOutputManager *abaputils.LogOutputManager) (err error) { log.Entry().Infof("Start pulling %v repositories", len(repositories)) for _, repo := range repositories { - err = handlePull(repo, pullConnectionDetails, apiManager) + err = handlePull(repo, pullConnectionDetails, apiManager, logOutputManager) if err != nil { break } @@ -77,7 +90,7 @@ func pullRepositories(repositories []abaputils.Repository, pullConnectionDetails return err } -func handlePull(repo abaputils.Repository, con abaputils.ConnectionDetailsHTTP, apiManager abaputils.SoftwareComponentApiManagerInterface) (err error) { +func handlePull(repo abaputils.Repository, con abaputils.ConnectionDetailsHTTP, apiManager abaputils.SoftwareComponentApiManagerInterface, logOutputManager *abaputils.LogOutputManager) (err error) { logString := repo.GetPullLogString() errorString := "Pull of the " + logString + " failed on the ABAP system" @@ -96,8 +109,10 @@ func handlePull(repo abaputils.Repository, con abaputils.ConnectionDetailsHTTP, return errors.Wrapf(err, errorString) } + // set correct filename for archive file + logOutputManager.FileNameStep = "pull" // Polling the status of the repository import on the ABAP Environment system - status, errorPollEntity := abaputils.PollEntity(api, apiManager.GetPollIntervall()) + status, errorPollEntity := abaputils.PollEntity(api, apiManager.GetPollIntervall(), logOutputManager) if errorPollEntity != nil { return errors.Wrapf(errorPollEntity, errorString) } diff --git a/cmd/abapEnvironmentPullGitRepo_generated.go b/cmd/abapEnvironmentPullGitRepo_generated.go index 3575ef4fb2..05cc2a0c21 100644 --- a/cmd/abapEnvironmentPullGitRepo_generated.go +++ b/cmd/abapEnvironmentPullGitRepo_generated.go @@ -8,6 +8,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/splunk" "github.com/SAP/jenkins-library/pkg/telemetry" @@ -23,6 +24,7 @@ type abapEnvironmentPullGitRepoOptions struct { RepositoryName string `json:"repositoryName,omitempty"` CommitID string `json:"commitID,omitempty"` Host string `json:"host,omitempty"` + LogOutput string `json:"logOutput,omitempty" validate:"possible-values=ZIP STANDARD"` CfAPIEndpoint string `json:"cfApiEndpoint,omitempty"` CfOrg string `json:"cfOrg,omitempty"` CfSpace string `json:"cfSpace,omitempty"` @@ -98,6 +100,11 @@ Please provide either of the following options: return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -123,6 +130,19 @@ Please provide either of the following options: GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + GeneralConfig.CorrelationID, + GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() @@ -145,6 +165,7 @@ func addAbapEnvironmentPullGitRepoFlags(cmd *cobra.Command, stepConfig *abapEnvi cmd.Flags().StringVar(&stepConfig.RepositoryName, "repositoryName", os.Getenv("PIPER_repositoryName"), "Specifies a repository (Software Component) on the SAP BTP ABAP Environment system") cmd.Flags().StringVar(&stepConfig.CommitID, "commitID", os.Getenv("PIPER_commitID"), "Specifies a commitID of the repository, configured via \"repositoryName\" on the SAP BTP ABAP Environment system") cmd.Flags().StringVar(&stepConfig.Host, "host", os.Getenv("PIPER_host"), "Specifies the host address of the SAP BTP ABAP Environment system") + cmd.Flags().StringVar(&stepConfig.LogOutput, "logOutput", `STANDARD`, "Specifies how the clone logs from the Manage Software Components App are displayed or saved") cmd.Flags().StringVar(&stepConfig.CfAPIEndpoint, "cfApiEndpoint", os.Getenv("PIPER_cfApiEndpoint"), "Cloud Foundry API Enpoint") cmd.Flags().StringVar(&stepConfig.CfOrg, "cfOrg", os.Getenv("PIPER_cfOrg"), "Cloud Foundry target organization") cmd.Flags().StringVar(&stepConfig.CfSpace, "cfSpace", os.Getenv("PIPER_cfSpace"), "Cloud Foundry target space") @@ -246,6 +267,15 @@ func abapEnvironmentPullGitRepoMetadata() config.StepData { Aliases: []config.Alias{}, Default: os.Getenv("PIPER_host"), }, + { + Name: "logOutput", + ResourceRef: []config.ResourceReference{}, + Scope: []string{"PARAMETERS", "STAGES", "STEPS"}, + Type: "string", + Mandatory: false, + Aliases: []config.Alias{}, + Default: `STANDARD`, + }, { Name: "cfApiEndpoint", ResourceRef: []config.ResourceReference{}, diff --git a/cmd/abapEnvironmentPullGitRepo_test.go b/cmd/abapEnvironmentPullGitRepo_test.go index cd805f37d5..f589381795 100644 --- a/cmd/abapEnvironmentPullGitRepo_test.go +++ b/cmd/abapEnvironmentPullGitRepo_test.go @@ -10,6 +10,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/abaputils" + "github.com/SAP/jenkins-library/pkg/piperutils" "github.com/stretchr/testify/assert" ) @@ -53,6 +54,7 @@ func TestPullStep(t *testing.T) { Username: "testUser", Password: "testPassword", RepositoryNames: []string{"testRepo1"}, + LogOutput: "STANDARD", } logResultSuccess := `{"d": { "sc_name": "/DMO/SWC", "status": "S", "to_Log_Overview": { "results": [ { "log_index": 1, "log_name": "Main Import", "type_of_found_issues": "Success", "timestamp": "/Date(1644332299000+0000)/", "to_Log_Protocol": { "results": [ { "log_index": 1, "index_no": "1", "log_name": "", "type": "Info", "descr": "Main import", "timestamp": null, "criticality": 0 } ] } } ] } } }` @@ -70,7 +72,16 @@ func TestPullStep(t *testing.T) { } apiManager = &abaputils.SoftwareComponentApiManager{Client: client, PollIntervall: 1 * time.Nanosecond, Force0510: true} - err := runAbapEnvironmentPullGitRepo(&config, &autils, apiManager) + + var reports []piperutils.Path + logOutputManager := abaputils.LogOutputManager{ + LogOutput: config.LogOutput, + PiperStep: "pull", + FileNameStep: "pull", + StepReports: reports, + } + + err := runAbapEnvironmentPullGitRepo(&config, &autils, apiManager, &logOutputManager) assert.NoError(t, err, "Did not expect error") assert.Equal(t, 0, len(client.BodyList), "Not all requests were done") }) @@ -96,8 +107,16 @@ func TestPullStep(t *testing.T) { config := abapEnvironmentPullGitRepoOptions{} + var reports []piperutils.Path + logOutputManager := abaputils.LogOutputManager{ + LogOutput: "STANDARD", + PiperStep: "pull", + FileNameStep: "pull", + StepReports: reports, + } + apiManager = &abaputils.SoftwareComponentApiManager{Client: client, PollIntervall: 1 * time.Nanosecond, Force0510: true} - err := runAbapEnvironmentPullGitRepo(&config, &autils, apiManager) + err := runAbapEnvironmentPullGitRepo(&config, &autils, apiManager, &logOutputManager) assert.Equal(t, expectedErrorMessage, err.Error(), "Different error message expected") }) @@ -146,9 +165,19 @@ repositories: Username: "testUser", Password: "testPassword", Repositories: "repositoriesTest.yml", + LogOutput: "STANDARD", + } + + var reports []piperutils.Path + logOutputManager := abaputils.LogOutputManager{ + LogOutput: config.LogOutput, + PiperStep: "pull", + FileNameStep: "pull", + StepReports: reports, } + apiManager = &abaputils.SoftwareComponentApiManager{Client: client, PollIntervall: 1 * time.Nanosecond, Force0510: true} - err = runAbapEnvironmentPullGitRepo(&config, &autils, apiManager) + err = runAbapEnvironmentPullGitRepo(&config, &autils, apiManager, &logOutputManager) assert.NoError(t, err) }) @@ -189,6 +218,7 @@ repositories: Username: "testUser", Password: "testPassword", Repositories: "filename.yaml", + LogOutput: "STANDARD", } client := &abaputils.ClientMock{ BodyList: []string{ @@ -198,13 +228,22 @@ repositories: `{"d" : { "status" : "E" } }`, `{"d" : { "status" : "R" } }`, `{"d" : { "status" : "R" } }`, + `{"d" : { "status" : "R" } }`, }, Token: "myToken", StatusCode: 200, } + var reports []piperutils.Path + logOutputManager := abaputils.LogOutputManager{ + LogOutput: config.LogOutput, + PiperStep: "pull", + FileNameStep: "pull", + StepReports: reports, + } + apiManager = &abaputils.SoftwareComponentApiManager{Client: client, PollIntervall: 1 * time.Nanosecond, Force0510: true} - err = runAbapEnvironmentPullGitRepo(&config, &autils, apiManager) + err = runAbapEnvironmentPullGitRepo(&config, &autils, apiManager, &logOutputManager) if assert.Error(t, err, "Expected error") { assert.Equal(t, "Pull of the repository / software component '/DMO/REPO_A', commit 'ABCD1234' failed on the ABAP system", err.Error(), "Expected different error message") } @@ -248,6 +287,7 @@ repositories: Password: "testPassword", Repositories: "filename.yaml", IgnoreCommit: true, + LogOutput: "STANDARD", } client := &abaputils.ClientMock{ BodyList: []string{ @@ -257,13 +297,22 @@ repositories: `{"d" : { "status" : "E" } }`, `{"d" : { "status" : "R" } }`, `{"d" : { "status" : "R" } }`, + `{"d" : { "status" : "R" } }`, }, Token: "myToken", StatusCode: 200, } + var reports []piperutils.Path + logOutputManager := abaputils.LogOutputManager{ + LogOutput: config.LogOutput, + PiperStep: "pull", + FileNameStep: "pull", + StepReports: reports, + } + apiManager = &abaputils.SoftwareComponentApiManager{Client: client, PollIntervall: 1 * time.Nanosecond, Force0510: true} - err = runAbapEnvironmentPullGitRepo(&config, &autils, apiManager) + err = runAbapEnvironmentPullGitRepo(&config, &autils, apiManager, &logOutputManager) if assert.Error(t, err, "Expected error") { assert.Equal(t, "Pull of the repository / software component '/DMO/REPO_A', tag 'v-1.0.1-build-0001' failed on the ABAP system", err.Error(), "Expected different error message") } @@ -288,6 +337,7 @@ repositories: RepositoryName: "/DMO/SWC", CommitID: "123456", IgnoreCommit: false, + LogOutput: "STANDARD", } client := &abaputils.ClientMock{ BodyList: []string{ @@ -297,13 +347,22 @@ repositories: `{"d" : { "status" : "E" } }`, `{"d" : { "status" : "R" } }`, `{"d" : { "status" : "R" } }`, + `{"d" : { "status" : "R" } }`, }, Token: "myToken", StatusCode: 200, } + var reports []piperutils.Path + logOutputManager := abaputils.LogOutputManager{ + LogOutput: config.LogOutput, + PiperStep: "pull", + FileNameStep: "pull", + StepReports: reports, + } + apiManager = &abaputils.SoftwareComponentApiManager{Client: client, PollIntervall: 1 * time.Nanosecond, Force0510: true} - err := runAbapEnvironmentPullGitRepo(&config, &autils, apiManager) + err := runAbapEnvironmentPullGitRepo(&config, &autils, apiManager, &logOutputManager) if assert.Error(t, err, "Expected error") { assert.Equal(t, "Pull of the repository / software component '/DMO/SWC', commit '123456' failed on the ABAP system", err.Error(), "Expected different error message") } @@ -327,6 +386,7 @@ repositories: Password: "testPassword", RepositoryName: "/DMO/SWC", IgnoreCommit: false, + LogOutput: "STANDARD", } client := &abaputils.ClientMock{ BodyList: []string{ @@ -336,13 +396,22 @@ repositories: `{"d" : { "status" : "E" } }`, `{"d" : { "status" : "R" } }`, `{"d" : { "status" : "R" } }`, + `{"d" : { "status" : "R" } }`, }, Token: "myToken", StatusCode: 200, } + var reports []piperutils.Path + logOutputManager := abaputils.LogOutputManager{ + LogOutput: config.LogOutput, + PiperStep: "pull", + FileNameStep: "pull", + StepReports: reports, + } + apiManager = &abaputils.SoftwareComponentApiManager{Client: client, PollIntervall: 1 * time.Nanosecond, Force0510: true} - err := runAbapEnvironmentPullGitRepo(&config, &autils, apiManager) + err := runAbapEnvironmentPullGitRepo(&config, &autils, apiManager, &logOutputManager) if assert.Error(t, err, "Expected error") { assert.Equal(t, "Pull of the repository / software component '/DMO/SWC' failed on the ABAP system", err.Error(), "Expected different error message") } @@ -387,9 +456,19 @@ repositories: Username: "testUser", Password: "testPassword", Repositories: "repositoriesTest.yml", + LogOutput: "STANDARD", } + + var reports []piperutils.Path + logOutputManager := abaputils.LogOutputManager{ + LogOutput: config.LogOutput, + PiperStep: "pull", + FileNameStep: "pull", + StepReports: reports, + } + apiManager = &abaputils.SoftwareComponentApiManager{Client: client, PollIntervall: 1 * time.Nanosecond, Force0510: true} - err = runAbapEnvironmentPullGitRepo(&config, &autils, apiManager) + err = runAbapEnvironmentPullGitRepo(&config, &autils, apiManager, &logOutputManager) assert.EqualError(t, err, expectedErrorMessage) }) @@ -437,9 +516,19 @@ repositories: Username: "testUser", Password: "testPassword", Repositories: "repositoriesTest.yml", + LogOutput: "STANDARD", } + + var reports []piperutils.Path + logOutputManager := abaputils.LogOutputManager{ + LogOutput: config.LogOutput, + PiperStep: "pull", + FileNameStep: "pull", + StepReports: reports, + } + apiManager = &abaputils.SoftwareComponentApiManager{Client: client, PollIntervall: 1 * time.Nanosecond, Force0510: true} - err = runAbapEnvironmentPullGitRepo(&config, &autils, apiManager) + err = runAbapEnvironmentPullGitRepo(&config, &autils, apiManager, &logOutputManager) assert.EqualError(t, err, expectedErrorMessage) }) } diff --git a/cmd/abapEnvironmentPushATCSystemConfig_generated.go b/cmd/abapEnvironmentPushATCSystemConfig_generated.go index d39f8e7a0a..c33c2d9eb9 100644 --- a/cmd/abapEnvironmentPushATCSystemConfig_generated.go +++ b/cmd/abapEnvironmentPushATCSystemConfig_generated.go @@ -8,6 +8,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/splunk" "github.com/SAP/jenkins-library/pkg/telemetry" @@ -94,6 +95,11 @@ Please provide either of the following options: return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -119,6 +125,19 @@ Please provide either of the following options: GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + GeneralConfig.CorrelationID, + GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() diff --git a/cmd/abapEnvironmentRunATCCheck_generated.go b/cmd/abapEnvironmentRunATCCheck_generated.go index c7ae16d7f1..04a52ad14d 100644 --- a/cmd/abapEnvironmentRunATCCheck_generated.go +++ b/cmd/abapEnvironmentRunATCCheck_generated.go @@ -8,6 +8,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/splunk" "github.com/SAP/jenkins-library/pkg/telemetry" @@ -99,6 +100,11 @@ Regardless of the option you chose, please make sure to provide the configuratio return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -124,6 +130,19 @@ Regardless of the option you chose, please make sure to provide the configuratio GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + GeneralConfig.CorrelationID, + GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() diff --git a/cmd/abapEnvironmentRunAUnitTest_generated.go b/cmd/abapEnvironmentRunAUnitTest_generated.go index 0a7466ab39..a3e865cd2d 100644 --- a/cmd/abapEnvironmentRunAUnitTest_generated.go +++ b/cmd/abapEnvironmentRunAUnitTest_generated.go @@ -8,6 +8,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/splunk" "github.com/SAP/jenkins-library/pkg/telemetry" @@ -98,6 +99,11 @@ Regardless of the option you chose, please make sure to provide the object set c return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -123,6 +129,19 @@ Regardless of the option you chose, please make sure to provide the object set c GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + GeneralConfig.CorrelationID, + GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() diff --git a/cmd/abapLandscapePortalUpdateAddOnProduct_generated.go b/cmd/abapLandscapePortalUpdateAddOnProduct_generated.go index 3ebebd7824..a44196072b 100644 --- a/cmd/abapLandscapePortalUpdateAddOnProduct_generated.go +++ b/cmd/abapLandscapePortalUpdateAddOnProduct_generated.go @@ -8,6 +8,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/splunk" "github.com/SAP/jenkins-library/pkg/telemetry" @@ -81,6 +82,11 @@ func AbapLandscapePortalUpdateAddOnProductCommand() *cobra.Command { return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -106,6 +112,19 @@ func AbapLandscapePortalUpdateAddOnProductCommand() *cobra.Command { GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + GeneralConfig.CorrelationID, + GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() diff --git a/cmd/ansSendEvent_generated.go b/cmd/ansSendEvent_generated.go index cc32a15503..9993c7745a 100644 --- a/cmd/ansSendEvent_generated.go +++ b/cmd/ansSendEvent_generated.go @@ -8,6 +8,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/splunk" "github.com/SAP/jenkins-library/pkg/telemetry" @@ -90,6 +91,11 @@ func AnsSendEventCommand() *cobra.Command { return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -115,6 +121,19 @@ func AnsSendEventCommand() *cobra.Command { GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + GeneralConfig.CorrelationID, + GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() diff --git a/cmd/apiKeyValueMapDownload_generated.go b/cmd/apiKeyValueMapDownload_generated.go index 6d1f650f20..2ced0e9124 100644 --- a/cmd/apiKeyValueMapDownload_generated.go +++ b/cmd/apiKeyValueMapDownload_generated.go @@ -8,6 +8,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/splunk" "github.com/SAP/jenkins-library/pkg/telemetry" @@ -82,6 +83,11 @@ Learn more about the SAP API Management API for downloading an Key Value Map art return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -107,6 +113,19 @@ Learn more about the SAP API Management API for downloading an Key Value Map art GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + GeneralConfig.CorrelationID, + GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() diff --git a/cmd/apiKeyValueMapUpload_generated.go b/cmd/apiKeyValueMapUpload_generated.go index 4562a46a87..c62d559b3f 100644 --- a/cmd/apiKeyValueMapUpload_generated.go +++ b/cmd/apiKeyValueMapUpload_generated.go @@ -8,6 +8,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/splunk" "github.com/SAP/jenkins-library/pkg/telemetry" @@ -83,6 +84,11 @@ Learn more about the SAP API Management API for creating an API key value map ar return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -108,6 +114,19 @@ Learn more about the SAP API Management API for creating an API key value map ar GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + GeneralConfig.CorrelationID, + GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() diff --git a/cmd/apiProviderDownload_generated.go b/cmd/apiProviderDownload_generated.go index ccc7a434b7..def4eb576c 100644 --- a/cmd/apiProviderDownload_generated.go +++ b/cmd/apiProviderDownload_generated.go @@ -8,6 +8,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/splunk" "github.com/SAP/jenkins-library/pkg/telemetry" @@ -81,6 +82,11 @@ func ApiProviderDownloadCommand() *cobra.Command { return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -106,6 +112,19 @@ func ApiProviderDownloadCommand() *cobra.Command { GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + GeneralConfig.CorrelationID, + GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() diff --git a/cmd/apiProviderList_generated.go b/cmd/apiProviderList_generated.go index 8a5936259f..76ce80c0f1 100644 --- a/cmd/apiProviderList_generated.go +++ b/cmd/apiProviderList_generated.go @@ -9,6 +9,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/piperenv" "github.com/SAP/jenkins-library/pkg/splunk" @@ -118,6 +119,11 @@ func ApiProviderListCommand() *cobra.Command { return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -144,6 +150,19 @@ func ApiProviderListCommand() *cobra.Command { GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + GeneralConfig.CorrelationID, + GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() diff --git a/cmd/apiProviderUpload_generated.go b/cmd/apiProviderUpload_generated.go index a133ed8e54..1b1728099f 100644 --- a/cmd/apiProviderUpload_generated.go +++ b/cmd/apiProviderUpload_generated.go @@ -8,6 +8,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/splunk" "github.com/SAP/jenkins-library/pkg/telemetry" @@ -81,6 +82,11 @@ Learn more about API Management api for creating an API provider artifact [here] return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -106,6 +112,19 @@ Learn more about API Management api for creating an API provider artifact [here] GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + GeneralConfig.CorrelationID, + GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() diff --git a/cmd/apiProxyDownload_generated.go b/cmd/apiProxyDownload_generated.go index 81b686db49..7f0238202b 100644 --- a/cmd/apiProxyDownload_generated.go +++ b/cmd/apiProxyDownload_generated.go @@ -8,6 +8,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/splunk" "github.com/SAP/jenkins-library/pkg/telemetry" @@ -81,6 +82,11 @@ func ApiProxyDownloadCommand() *cobra.Command { return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -106,6 +112,19 @@ func ApiProxyDownloadCommand() *cobra.Command { GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + GeneralConfig.CorrelationID, + GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() diff --git a/cmd/apiProxyList_generated.go b/cmd/apiProxyList_generated.go index 09938f55a6..53f8c86d7b 100644 --- a/cmd/apiProxyList_generated.go +++ b/cmd/apiProxyList_generated.go @@ -9,6 +9,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/piperenv" "github.com/SAP/jenkins-library/pkg/splunk" @@ -118,6 +119,11 @@ func ApiProxyListCommand() *cobra.Command { return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -144,6 +150,19 @@ func ApiProxyListCommand() *cobra.Command { GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + GeneralConfig.CorrelationID, + GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() diff --git a/cmd/apiProxyUpload_generated.go b/cmd/apiProxyUpload_generated.go index 6bd6775828..51bf6c42a1 100644 --- a/cmd/apiProxyUpload_generated.go +++ b/cmd/apiProxyUpload_generated.go @@ -8,6 +8,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/splunk" "github.com/SAP/jenkins-library/pkg/telemetry" @@ -81,6 +82,11 @@ Learn more about the SAP API Management API for uploading an api proxy artifact return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -106,6 +112,19 @@ Learn more about the SAP API Management API for uploading an api proxy artifact GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + GeneralConfig.CorrelationID, + GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() diff --git a/cmd/artifactPrepareVersion_generated.go b/cmd/artifactPrepareVersion_generated.go index 7953e72522..e39872d89b 100644 --- a/cmd/artifactPrepareVersion_generated.go +++ b/cmd/artifactPrepareVersion_generated.go @@ -9,6 +9,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/piperenv" "github.com/SAP/jenkins-library/pkg/splunk" @@ -210,6 +211,11 @@ Define ` + "`" + `buildTool: custom` + "`" + `, ` + "`" + `filePath: --install --force --namespace --install --force --namespace 0 { + flags = append(flags, "--activate-profiles", strings.Join(config.Profiles, ",")) + } + exists, _ := utils.FileExists("integration-tests/pom.xml") + if exists { + flags = append(flags, "-pl", "!integration-tests") + } + + var defines []string + + createBOMConfig := []string{ + "-DschemaVersion=1.4", + "-DincludeBomSerialNumber=true", + "-DincludeCompileScope=true", + "-DincludeProvidedScope=true", + "-DincludeRuntimeScope=true", + "-DincludeSystemScope=true", + "-DincludeTestScope=false", + "-DincludeLicenseText=false", + "-DoutputFormat=xml", + "-DoutputName=" + mvnSimpleBomFilename, + } + defines = append(defines, createBOMConfig...) + + goals := []string{"org.cyclonedx:cyclonedx-maven-plugin:2.7.8:makeBom"} + + if config.Flatten { + goals = append(goals, "flatten:flatten") + defines = append(defines, "-Dflatten.mode=resolveCiFriendliesOnly", "-DupdatePomFile=true") + } + + mavenOptions := maven.ExecuteOptions{ + Flags: flags, + Goals: goals, + Defines: defines, + PomPath: config.PomPath, + ProjectSettingsFile: config.ProjectSettingsFile, + GlobalSettingsFile: config.GlobalSettingsFile, + M2Path: config.M2Path, + LogSuccessfulMavenTransfers: config.LogSuccessfulMavenTransfers, + } + + _, err := maven.Execute(&mavenOptions, utils) + return err +} + func runMavenBuild(config *mavenBuildOptions, telemetryData *telemetry.CustomData, utils maven.Utils, commonPipelineEnvironment *mavenBuildCommonPipelineEnvironment) error { var flags = []string{"-update-snapshots", "--batch-mode"} @@ -61,7 +110,8 @@ func runMavenBuild(config *mavenBuildOptions, telemetryData *telemetry.CustomDat } if config.CreateBOM { - goals = append(goals, "org.cyclonedx:cyclonedx-maven-plugin:2.7.8:makeBom", "org.cyclonedx:cyclonedx-maven-plugin:2.7.8:makeAggregateBom") + // Append the makeAggregateBOM goal to the rest of the goals + goals = append(goals, "org.cyclonedx:cyclonedx-maven-plugin:2.7.8:makeAggregateBom") createBOMConfig := []string{ "-DschemaVersion=1.4", "-DincludeBomSerialNumber=true", @@ -97,11 +147,17 @@ func runMavenBuild(config *mavenBuildOptions, telemetryData *telemetry.CustomDat } _, err := maven.Execute(&mavenOptions, utils) - if err != nil { return errors.Wrapf(err, "failed to execute maven build for goal(s) '%v'", goals) } + if config.CreateBOM { + // Separate run for makeBOM goal + if err := runMakeBOMGoal(config, utils); err != nil { + return errors.Wrap(err, "failed to execute makeBOM goal") + } + } + log.Entry().Debugf("creating build settings information...") stepName := "mavenBuild" dockerImage, err := GetDockerImageValue(stepName) @@ -165,39 +221,10 @@ func runMavenBuild(config *mavenBuildOptions, telemetryData *telemetry.CustomDat return err } if config.CreateBuildArtifactsMetadata { - buildCoordinates := []versioning.Coordinates{} - options := versioning.Options{} - var utils versioning.Utils - - matches, _ := fileUtils.Glob("**/pom.xml") - for _, match := range matches { - - artifact, err := versioning.GetArtifact("maven", match, &options, utils) - if err != nil { - log.Entry().Warnf("unable to get artifact metdata : %v", err) - } else { - coordinate, err := artifact.GetCoordinates() - if err != nil { - log.Entry().Warnf("unable to get artifact coordinates : %v", err) - } else { - coordinate.BuildPath = filepath.Dir(match) - coordinate.URL = config.AltDeploymentRepositoryURL - coordinate.PURL = getPurlForThePomAndDeleteIndividualBom(match) - buildCoordinates = append(buildCoordinates, coordinate) - } - } - } - - if len(buildCoordinates) == 0 { - log.Entry().Warnf("unable to identify artifact coordinates for the maven packages published") - return nil + err2, done := createBuildArtifactsMetadata(config, commonPipelineEnvironment) + if done { + return err2 } - - var buildArtifacts build.BuildArtifacts - - buildArtifacts.Coordinates = buildCoordinates - jsonResult, _ := json.Marshal(buildArtifacts) - commonPipelineEnvironment.custom.mavenBuildArtifacts = string(jsonResult) } return nil @@ -209,8 +236,46 @@ func runMavenBuild(config *mavenBuildOptions, telemetryData *telemetry.CustomDat return err } -func getPurlForThePomAndDeleteIndividualBom(pomFilePath string) string { - bomPath := filepath.Join(filepath.Dir(pomFilePath) + "/target/" + mvnBomFilename + ".xml") +func createBuildArtifactsMetadata(config *mavenBuildOptions, commonPipelineEnvironment *mavenBuildCommonPipelineEnvironment) (error, bool) { + fileUtils := &piperutils.Files{} + buildCoordinates := []versioning.Coordinates{} + options := versioning.Options{} + var utils versioning.Utils + + matches, _ := fileUtils.Glob("**/pom.xml") + for _, match := range matches { + + artifact, err := versioning.GetArtifact("maven", match, &options, utils) + if err != nil { + log.Entry().Warnf("unable to get artifact metdata : %v", err) + } else { + coordinate, err := artifact.GetCoordinates() + if err != nil { + log.Entry().Warnf("unable to get artifact coordinates : %v", err) + } else { + coordinate.BuildPath = filepath.Dir(match) + coordinate.URL = config.AltDeploymentRepositoryURL + coordinate.PURL = getPurlForThePom(match) + buildCoordinates = append(buildCoordinates, coordinate) + } + } + } + + if len(buildCoordinates) == 0 { + log.Entry().Warnf("unable to identify artifact coordinates for the maven packages published") + return nil, true + } + + var buildArtifacts build.BuildArtifacts + + buildArtifacts.Coordinates = buildCoordinates + jsonResult, _ := json.Marshal(buildArtifacts) + commonPipelineEnvironment.custom.mavenBuildArtifacts = string(jsonResult) + return nil, false +} + +func getPurlForThePom(pomFilePath string) string { + bomPath := filepath.Join(filepath.Dir(pomFilePath) + "/target/" + mvnSimpleBomFilename + ".xml") exists, _ := piperutils.FileExists(bomPath) if !exists { log.Entry().Debugf("bom file doesn't exist and hence no pURL info: %v", bomPath) @@ -225,26 +290,9 @@ func getPurlForThePomAndDeleteIndividualBom(pomFilePath string) string { log.Entry().Debugf("Found purl: %s for the bomPath: %s", bom.Metadata.Component.Purl, bomPath) purl := bom.Metadata.Component.Purl - // Check if the BOM is an aggregated BOM - if !isAggregatedBOM(bom) { - // Delete the individual BOM file - err = os.Remove(bomPath) - if err != nil { - log.Entry().Warnf("failed to delete bom file %s: %v", bomPath, err) - } - } return purl } -func isAggregatedBOM(bom piperutils.Bom) bool { - for _, property := range bom.Metadata.Properties { - if property.Name == "maven.goal" && property.Value == "makeAggregateBom" { - return true - } - } - return false -} - func createOrUpdateProjectSettingsXML(projectSettingsFile string, altDeploymentRepositoryID string, altDeploymentRepositoryUser string, altDeploymentRepositoryPassword string, utils maven.Utils) (string, error) { if len(projectSettingsFile) > 0 { projectSettingsFilePath, err := maven.UpdateProjectSettingsXML(projectSettingsFile, altDeploymentRepositoryID, altDeploymentRepositoryUser, altDeploymentRepositoryPassword, utils) diff --git a/cmd/mavenBuild_generated.go b/cmd/mavenBuild_generated.go index 57af28804e..b8ed7234d3 100644 --- a/cmd/mavenBuild_generated.go +++ b/cmd/mavenBuild_generated.go @@ -11,6 +11,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/gcs" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/piperenv" @@ -212,6 +213,11 @@ general: return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -239,6 +245,19 @@ general: GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + GeneralConfig.CorrelationID, + GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() diff --git a/cmd/mavenBuild_test.go b/cmd/mavenBuild_test.go index ca48d89f95..ea5e9abdbc 100644 --- a/cmd/mavenBuild_test.go +++ b/cmd/mavenBuild_test.go @@ -12,9 +12,9 @@ import ( "github.com/stretchr/testify/assert" ) -func TestMavenBuild(t *testing.T) { +var cpe mavenBuildCommonPipelineEnvironment - cpe := mavenBuildCommonPipelineEnvironment{} +func TestMavenBuild(t *testing.T) { t.Run("mavenBuild should install the artifact", func(t *testing.T) { mockedUtils := newMavenMockUtils() @@ -22,51 +22,30 @@ func TestMavenBuild(t *testing.T) { config := mavenBuildOptions{} err := runMavenBuild(&config, nil, &mockedUtils, &cpe) + expectedParams := []string{"install"} assert.Nil(t, err) - assert.Equal(t, mockedUtils.Calls[0].Exec, "mvn") - assert.Contains(t, mockedUtils.Calls[0].Params, "install") - }) - - t.Run("mavenBuild should skip integration tests", func(t *testing.T) { - mockedUtils := newMavenMockUtils() - mockedUtils.AddFile("integration-tests/pom.xml", []byte{}) - - config := mavenBuildOptions{} - - err := runMavenBuild(&config, nil, &mockedUtils, &cpe) - - assert.Nil(t, err) - assert.Equal(t, mockedUtils.Calls[0].Exec, "mvn") - assert.Contains(t, mockedUtils.Calls[0].Params, "-pl", "!integration-tests") - }) - - t.Run("mavenBuild should flatten", func(t *testing.T) { - mockedUtils := newMavenMockUtils() - - config := mavenBuildOptions{Flatten: true} - - err := runMavenBuild(&config, nil, &mockedUtils, &cpe) - - assert.Nil(t, err) - assert.Contains(t, mockedUtils.Calls[0].Params, "flatten:flatten") - assert.Contains(t, mockedUtils.Calls[0].Params, "-Dflatten.mode=resolveCiFriendliesOnly") - assert.Contains(t, mockedUtils.Calls[0].Params, "-DupdatePomFile=true") + if assert.Equal(t, 1, len(mockedUtils.Calls), "Expected one maven invocation for the main build") { + assert.Equal(t, "mvn", mockedUtils.Calls[0].Exec) + assert.Contains(t, mockedUtils.Calls[0].Params, expectedParams[0], "Call should contain install goal") + } }) - t.Run("mavenBuild should run only verify", func(t *testing.T) { + t.Run("mavenBuild accepts profiles", func(t *testing.T) { mockedUtils := newMavenMockUtils() - config := mavenBuildOptions{Verify: true} + config := mavenBuildOptions{Profiles: []string{"profile1", "profile2"}} err := runMavenBuild(&config, nil, &mockedUtils, &cpe) assert.Nil(t, err) - assert.Contains(t, mockedUtils.Calls[0].Params, "verify") - assert.NotContains(t, mockedUtils.Calls[0].Params, "install") + if assert.Equal(t, 1, len(mockedUtils.Calls), "Expected one maven invocation for the main build") { + assert.Contains(t, mockedUtils.Calls[0].Params, "--activate-profiles") + assert.Contains(t, mockedUtils.Calls[0].Params, "profile1,profile2") + } }) - t.Run("mavenBuild should createBOM", func(t *testing.T) { + t.Run("mavenBuild should create BOM", func(t *testing.T) { mockedUtils := newMavenMockUtils() config := mavenBuildOptions{CreateBOM: true} @@ -74,74 +53,60 @@ func TestMavenBuild(t *testing.T) { err := runMavenBuild(&config, nil, &mockedUtils, &cpe) assert.Nil(t, err) - assert.Contains(t, mockedUtils.Calls[0].Params, "org.cyclonedx:cyclonedx-maven-plugin:2.7.8:makeAggregateBom") - assert.Contains(t, mockedUtils.Calls[0].Params, "-DschemaVersion=1.4") - assert.Contains(t, mockedUtils.Calls[0].Params, "-DincludeBomSerialNumber=true") - assert.Contains(t, mockedUtils.Calls[0].Params, "-DincludeCompileScope=true") - assert.Contains(t, mockedUtils.Calls[0].Params, "-DincludeProvidedScope=true") - assert.Contains(t, mockedUtils.Calls[0].Params, "-DincludeRuntimeScope=true") - assert.Contains(t, mockedUtils.Calls[0].Params, "-DincludeSystemScope=true") - assert.Contains(t, mockedUtils.Calls[0].Params, "-DincludeTestScope=false") - assert.Contains(t, mockedUtils.Calls[0].Params, "-DincludeLicenseText=false") - assert.Contains(t, mockedUtils.Calls[0].Params, "-DoutputFormat=xml") - assert.Contains(t, mockedUtils.Calls[0].Params, "-DoutputName=bom-maven") + if assert.Equal(t, 2, len(mockedUtils.Calls), "Expected two Maven invocations (default + makeAggregateBom)") { + assert.Equal(t, "mvn", mockedUtils.Calls[1].Exec) + assert.Contains(t, mockedUtils.Calls[0].Params, "org.cyclonedx:cyclonedx-maven-plugin:2.7.8:makeAggregateBom") + assert.Contains(t, mockedUtils.Calls[0].Params, "-DoutputName=bom-maven") + } }) t.Run("mavenBuild include install and deploy when publish is true", func(t *testing.T) { mockedUtils := newMavenMockUtils() - config := mavenBuildOptions{Publish: true, Verify: false} + config := mavenBuildOptions{Publish: true, Verify: false, AltDeploymentRepositoryID: "ID", AltDeploymentRepositoryURL: "http://sampleRepo.com", AltDeploymentRepositoryUser: "user", AltDeploymentRepositoryPassword: "pass"} err := runMavenBuild(&config, nil, &mockedUtils, &cpe) assert.Nil(t, err) - assert.Contains(t, mockedUtils.Calls[0].Params, "install") - assert.NotContains(t, mockedUtils.Calls[0].Params, "verify") - assert.Contains(t, mockedUtils.Calls[1].Params, "deploy") - + if assert.Equal(t, 2, len(mockedUtils.Calls), "Expected two Maven invocations (main and deploy)") { + assert.Contains(t, mockedUtils.Calls[0].Params, "install") + assert.NotContains(t, mockedUtils.Calls[0].Params, "verify") + assert.Contains(t, mockedUtils.Calls[1].Params, "deploy") + } }) t.Run("mavenBuild with deploy must skip build, install and test", func(t *testing.T) { mockedUtils := newMavenMockUtils() - config := mavenBuildOptions{Publish: true, Verify: false, DeployFlags: []string{"-Dmaven.main.skip=true", "-Dmaven.test.skip=true", "-Dmaven.install.skip=true"}} + config := mavenBuildOptions{Publish: true, Verify: false, DeployFlags: []string{"-Dmaven.main.skip=true", "-Dmaven.test.skip=true", "-Dmaven.install.skip=true"}, AltDeploymentRepositoryID: "ID", AltDeploymentRepositoryURL: "http://sampleRepo.com", AltDeploymentRepositoryUser: "user", AltDeploymentRepositoryPassword: "pass"} err := runMavenBuild(&config, nil, &mockedUtils, &cpe) assert.Nil(t, err) - assert.Contains(t, mockedUtils.Calls[1].Params, "-Dmaven.main.skip=true") - assert.Contains(t, mockedUtils.Calls[1].Params, "-Dmaven.test.skip=true") - assert.Contains(t, mockedUtils.Calls[1].Params, "-Dmaven.install.skip=true") - + if assert.Equal(t, 2, len(mockedUtils.Calls), "Expected two Maven invocations (main and deploy)") { + assert.Contains(t, mockedUtils.Calls[1].Params, "-Dmaven.main.skip=true") + assert.Contains(t, mockedUtils.Calls[1].Params, "-Dmaven.test.skip=true") + assert.Contains(t, mockedUtils.Calls[1].Params, "-Dmaven.install.skip=true") + } }) t.Run("mavenBuild with deploy must include alt repo id and url when passed as parameter", func(t *testing.T) { mockedUtils := newMavenMockUtils() - config := mavenBuildOptions{Publish: true, Verify: false, AltDeploymentRepositoryID: "ID", AltDeploymentRepositoryURL: "http://sampleRepo.com"} + config := mavenBuildOptions{Publish: true, Verify: false, AltDeploymentRepositoryID: "ID", AltDeploymentRepositoryURL: "http://sampleRepo.com", AltDeploymentRepositoryUser: "user", AltDeploymentRepositoryPassword: "pass"} err := runMavenBuild(&config, nil, &mockedUtils, &cpe) assert.Nil(t, err) - assert.Contains(t, mockedUtils.Calls[1].Params, "-DaltDeploymentRepository=ID::default::http://sampleRepo.com") - }) - - t.Run("mavenBuild accepts profiles", func(t *testing.T) { - mockedUtils := newMavenMockUtils() - - config := mavenBuildOptions{Profiles: []string{"profile1", "profile2"}} - - err := runMavenBuild(&config, nil, &mockedUtils, &cpe) - - assert.Nil(t, err) - assert.Contains(t, mockedUtils.Calls[0].Params, "--activate-profiles") - assert.Contains(t, mockedUtils.Calls[0].Params, "profile1,profile2") + if assert.Equal(t, 2, len(mockedUtils.Calls), "Expected two Maven invocations (main and deploy)") { + assert.Contains(t, mockedUtils.Calls[1].Params, "-DaltDeploymentRepository=ID::default::http://sampleRepo.com") + } }) t.Run("mavenBuild should not create build artifacts metadata when CreateBuildArtifactsMetadata is false and Publish is true", func(t *testing.T) { mockedUtils := newMavenMockUtils() mockedUtils.AddFile("pom.xml", []byte{}) - config := mavenBuildOptions{CreateBuildArtifactsMetadata: false, Publish: true} + config := mavenBuildOptions{CreateBuildArtifactsMetadata: false, Publish: true, AltDeploymentRepositoryID: "ID", AltDeploymentRepositoryURL: "http://sampleRepo.com", AltDeploymentRepositoryUser: "user", AltDeploymentRepositoryPassword: "pass"} err := runMavenBuild(&config, nil, &mockedUtils, &cpe) assert.Nil(t, err) assert.Equal(t, mockedUtils.Calls[0].Exec, "mvn") @@ -161,30 +126,6 @@ func TestMavenBuild(t *testing.T) { } -func TestIsAggregatedBOM(t *testing.T) { - t.Run("is aggregated BOM", func(t *testing.T) { - bom := piperutils.Bom{ - Metadata: piperutils.Metadata{ - Properties: []piperutils.BomProperty{ - {Name: "maven.goal", Value: "makeAggregateBom"}, - }, - }, - } - assert.True(t, isAggregatedBOM(bom)) - }) - - t.Run("is not aggregated BOM", func(t *testing.T) { - bom := piperutils.Bom{ - Metadata: piperutils.Metadata{ - Properties: []piperutils.BomProperty{ - {Name: "some.property", Value: "someValue"}, - }, - }, - } - assert.False(t, isAggregatedBOM(bom)) - }) -} - func createTempFile(t *testing.T, dir string, filename string, content string) string { filePath := filepath.Join(dir, filename) err := os.WriteFile(filePath, []byte(content), 0666) @@ -195,35 +136,6 @@ func createTempFile(t *testing.T, dir string, filename string, content string) s } func TestGetPurlForThePomAndDeleteIndividualBom(t *testing.T) { - t.Run("valid BOM file, non-aggregated", func(t *testing.T) { - tempDir, err := piperutils.Files{}.TempDir("", "test") - if err != nil { - t.Fatalf("Failed to create temp directory: %s", err) - } - - bomContent := ` - - - pkg:maven/com.example/mycomponent@1.0.0 - - - - - - ` - pomFilePath := createTempFile(t, tempDir, "pom.xml", "") - bomDir := filepath.Join(tempDir, "target") - if err := os.MkdirAll(bomDir, 0777); err != nil { - t.Fatalf("Failed to create temp directory: %s", err) - } - bomFilePath := createTempFile(t, bomDir, mvnBomFilename+".xml", bomContent) - defer os.Remove(bomFilePath) - - purl := getPurlForThePomAndDeleteIndividualBom(pomFilePath) - assert.Equal(t, "pkg:maven/com.example/mycomponent@1.0.0", purl) - _, err = os.Stat(bomFilePath) - assert.True(t, os.IsNotExist(err)) - }) t.Run("valid BOM file, aggregated BOM", func(t *testing.T) { tempDir, err := piperutils.Files{}.TempDir("", "test") @@ -246,9 +158,9 @@ func TestGetPurlForThePomAndDeleteIndividualBom(t *testing.T) { if err := os.MkdirAll(bomDir, 0777); err != nil { t.Fatalf("Failed to create temp directory: %s", err) } - bomFilePath := createTempFile(t, bomDir, mvnBomFilename+".xml", bomContent) + bomFilePath := createTempFile(t, bomDir, mvnSimpleBomFilename+".xml", bomContent) - purl := getPurlForThePomAndDeleteIndividualBom(pomFilePath) + purl := getPurlForThePom(pomFilePath) assert.Equal(t, "pkg:maven/com.example/aggregatecomponent@1.0.0", purl) _, err = os.Stat(bomFilePath) assert.False(t, os.IsNotExist(err)) // File should not be deleted @@ -258,7 +170,7 @@ func TestGetPurlForThePomAndDeleteIndividualBom(t *testing.T) { tempDir := t.TempDir() pomFilePath := createTempFile(t, tempDir, "pom.xml", "") // Create a temp pom file - purl := getPurlForThePomAndDeleteIndividualBom(pomFilePath) + purl := getPurlForThePom(pomFilePath) assert.Equal(t, "", purl) }) } diff --git a/cmd/mavenExecuteIntegration_generated.go b/cmd/mavenExecuteIntegration_generated.go index d337642de1..0370f095c0 100644 --- a/cmd/mavenExecuteIntegration_generated.go +++ b/cmd/mavenExecuteIntegration_generated.go @@ -10,6 +10,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/gcs" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/splunk" @@ -130,6 +131,11 @@ the integration tests via the Jacoco Maven-plugin.`, return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -156,6 +162,19 @@ the integration tests via the Jacoco Maven-plugin.`, GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + GeneralConfig.CorrelationID, + GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() diff --git a/cmd/mavenExecuteStaticCodeChecks_generated.go b/cmd/mavenExecuteStaticCodeChecks_generated.go index 8fda229db8..da17727af9 100644 --- a/cmd/mavenExecuteStaticCodeChecks_generated.go +++ b/cmd/mavenExecuteStaticCodeChecks_generated.go @@ -8,6 +8,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/splunk" "github.com/SAP/jenkins-library/pkg/telemetry" @@ -97,6 +98,11 @@ For PMD the failure priority and the max allowed violations are configurable via return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -122,6 +128,19 @@ For PMD the failure priority and the max allowed violations are configurable via GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + GeneralConfig.CorrelationID, + GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() diff --git a/cmd/mavenExecute_generated.go b/cmd/mavenExecute_generated.go index 0c0fe387fd..c126692e92 100644 --- a/cmd/mavenExecute_generated.go +++ b/cmd/mavenExecute_generated.go @@ -8,6 +8,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/splunk" "github.com/SAP/jenkins-library/pkg/telemetry" @@ -86,6 +87,11 @@ func MavenExecuteCommand() *cobra.Command { return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -111,6 +117,19 @@ func MavenExecuteCommand() *cobra.Command { GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + GeneralConfig.CorrelationID, + GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() diff --git a/cmd/mtaBuild_generated.go b/cmd/mtaBuild_generated.go index 7912027e97..5a15ee3b8e 100644 --- a/cmd/mtaBuild_generated.go +++ b/cmd/mtaBuild_generated.go @@ -11,6 +11,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/gcs" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/piperenv" @@ -183,6 +184,11 @@ func MtaBuildCommand() *cobra.Command { return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -210,6 +216,19 @@ func MtaBuildCommand() *cobra.Command { GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + GeneralConfig.CorrelationID, + GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() diff --git a/cmd/newmanExecute_generated.go b/cmd/newmanExecute_generated.go index 7a63508f53..cc8951057e 100644 --- a/cmd/newmanExecute_generated.go +++ b/cmd/newmanExecute_generated.go @@ -11,6 +11,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/gcs" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/piperenv" @@ -164,6 +165,11 @@ func NewmanExecuteCommand() *cobra.Command { return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -191,6 +197,19 @@ func NewmanExecuteCommand() *cobra.Command { GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + GeneralConfig.CorrelationID, + GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() diff --git a/cmd/nexusUpload_generated.go b/cmd/nexusUpload_generated.go index 304d75b928..4d78c72db2 100644 --- a/cmd/nexusUpload_generated.go +++ b/cmd/nexusUpload_generated.go @@ -8,6 +8,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/splunk" "github.com/SAP/jenkins-library/pkg/telemetry" @@ -109,6 +110,11 @@ If an image for mavenExecute is configured, and npm packages are to be published return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -134,6 +140,19 @@ If an image for mavenExecute is configured, and npm packages are to be published GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + GeneralConfig.CorrelationID, + GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() diff --git a/cmd/npmExecuteLint_generated.go b/cmd/npmExecuteLint_generated.go index 8e087250fb..aa14b3afdc 100644 --- a/cmd/npmExecuteLint_generated.go +++ b/cmd/npmExecuteLint_generated.go @@ -8,6 +8,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/splunk" "github.com/SAP/jenkins-library/pkg/telemetry" @@ -84,6 +85,11 @@ either use ESLint configurations present in the project or use the provided gene return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -109,6 +115,19 @@ either use ESLint configurations present in the project or use the provided gene GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + GeneralConfig.CorrelationID, + GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() diff --git a/cmd/npmExecuteScripts_generated.go b/cmd/npmExecuteScripts_generated.go index 7359c8827f..67238fe795 100644 --- a/cmd/npmExecuteScripts_generated.go +++ b/cmd/npmExecuteScripts_generated.go @@ -11,6 +11,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/gcs" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/piperenv" @@ -187,6 +188,11 @@ and are exposed are environment variables that must be present in the environmen return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -214,6 +220,19 @@ and are exposed are environment variables that must be present in the environmen GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + GeneralConfig.CorrelationID, + GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() diff --git a/cmd/npmExecuteScripts_test.go b/cmd/npmExecuteScripts_test.go index af1b7f828a..3c7bf6e995 100644 --- a/cmd/npmExecuteScripts_test.go +++ b/cmd/npmExecuteScripts_test.go @@ -148,7 +148,7 @@ func TestNpmExecuteScripts(t *testing.T) { if assert.NoError(t, err) { if assert.Equal(t, 4, len(utils.execRunner.Calls)) { - assert.Equal(t, mock.ExecCall{Exec: "npm", Params: []string{"config", "get", "registry"}}, utils.execRunner.Calls[0]) + assert.Equal(t, mock.ExecCall{Exec: "npm", Params: []string{"config", "get", "registry", "-ws=false", "-iwr"}}, utils.execRunner.Calls[0]) assert.Equal(t, mock.ExecCall{Exec: "npm", Params: []string{"ci"}}, utils.execRunner.Calls[1]) assert.Equal(t, mock.ExecCall{Exec: "npm", Params: []string{"run", "ci-build"}}, utils.execRunner.Calls[3]) } diff --git a/cmd/pipelineCreateScanSummary_generated.go b/cmd/pipelineCreateScanSummary_generated.go index 2a3b36609e..5bc983ecdb 100644 --- a/cmd/pipelineCreateScanSummary_generated.go +++ b/cmd/pipelineCreateScanSummary_generated.go @@ -8,6 +8,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/splunk" "github.com/SAP/jenkins-library/pkg/telemetry" @@ -82,6 +83,11 @@ It is for example used to create a markdown file which can be used to create a G return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -107,6 +113,19 @@ It is for example used to create a markdown file which can be used to create a G GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + GeneralConfig.CorrelationID, + GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() diff --git a/cmd/piper.go b/cmd/piper.go index ae1d19568d..295827f8fa 100644 --- a/cmd/piper.go +++ b/cmd/piper.go @@ -52,6 +52,7 @@ type GeneralConfigOptions struct { // HookConfiguration contains the configuration for supported hooks, so far Sentry and Splunk are supported. type HookConfiguration struct { + GCPPubSubConfig GCPPubSubConfiguration `json:"gcpPubSub,omitempty"` SentryConfig SentryConfiguration `json:"sentry,omitempty"` SplunkConfig SplunkConfiguration `json:"splunk,omitempty"` PendoConfig PendoConfiguration `json:"pendo,omitempty"` @@ -59,6 +60,14 @@ type HookConfiguration struct { TrustEngineConfig TrustEngineConfiguration `json:"trustengine,omitempty"` } +type GCPPubSubConfiguration struct { + Enabled bool `json:"enabled"` + ProjectNumber string `json:"projectNumber,omitempty"` + IdentityPool string `json:"identityPool,omitempty"` + IdentityProvider string `json:"identityProvider,omitempty"` + Topic string `json:"topic,omitempty"` +} + // SentryConfiguration defines the configuration options for the Sentry logging system type SentryConfiguration struct { Dsn string `json:"dsn,omitempty"` diff --git a/cmd/protecodeExecuteScan_generated.go b/cmd/protecodeExecuteScan_generated.go index 3451a10435..f0d5305406 100644 --- a/cmd/protecodeExecuteScan_generated.go +++ b/cmd/protecodeExecuteScan_generated.go @@ -11,6 +11,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/gcs" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/piperenv" @@ -209,6 +210,11 @@ BDBA (Protecode) uses a combination of static binary analysis techniques to X-ra return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -236,6 +242,19 @@ BDBA (Protecode) uses a combination of static binary analysis techniques to X-ra GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + GeneralConfig.CorrelationID, + GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() diff --git a/cmd/pythonBuild_generated.go b/cmd/pythonBuild_generated.go index 47f6546f6b..6a0198a938 100644 --- a/cmd/pythonBuild_generated.go +++ b/cmd/pythonBuild_generated.go @@ -9,6 +9,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/piperenv" "github.com/SAP/jenkins-library/pkg/splunk" @@ -129,6 +130,11 @@ and are exposed are environment variables that must be present in the environmen return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -155,6 +161,19 @@ and are exposed are environment variables that must be present in the environmen GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + GeneralConfig.CorrelationID, + GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() diff --git a/cmd/shellExecute_generated.go b/cmd/shellExecute_generated.go index 1a1b7de18a..a69334c40f 100644 --- a/cmd/shellExecute_generated.go +++ b/cmd/shellExecute_generated.go @@ -8,6 +8,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/splunk" "github.com/SAP/jenkins-library/pkg/telemetry" @@ -81,6 +82,11 @@ func ShellExecuteCommand() *cobra.Command { return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -106,6 +112,19 @@ func ShellExecuteCommand() *cobra.Command { GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + GeneralConfig.CorrelationID, + GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() diff --git a/cmd/sonarExecuteScan_generated.go b/cmd/sonarExecuteScan_generated.go index 23672d9587..e5a77a19b5 100644 --- a/cmd/sonarExecuteScan_generated.go +++ b/cmd/sonarExecuteScan_generated.go @@ -11,6 +11,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/gcs" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/piperenv" @@ -202,6 +203,11 @@ func SonarExecuteScanCommand() *cobra.Command { return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -229,6 +235,19 @@ func SonarExecuteScanCommand() *cobra.Command { GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + GeneralConfig.CorrelationID, + GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() diff --git a/cmd/terraformExecute_generated.go b/cmd/terraformExecute_generated.go index 9ac3428c67..a76d14d400 100644 --- a/cmd/terraformExecute_generated.go +++ b/cmd/terraformExecute_generated.go @@ -9,6 +9,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/piperenv" "github.com/SAP/jenkins-library/pkg/splunk" @@ -116,6 +117,11 @@ func TerraformExecuteCommand() *cobra.Command { return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -142,6 +148,19 @@ func TerraformExecuteCommand() *cobra.Command { GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + GeneralConfig.CorrelationID, + GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() diff --git a/cmd/tmsExport_generated.go b/cmd/tmsExport_generated.go index 346c66d891..00f6c89046 100644 --- a/cmd/tmsExport_generated.go +++ b/cmd/tmsExport_generated.go @@ -9,6 +9,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/piperenv" "github.com/SAP/jenkins-library/pkg/splunk" @@ -131,6 +132,11 @@ For more information, see [official documentation of SAP Cloud Transport Managem return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -157,6 +163,19 @@ For more information, see [official documentation of SAP Cloud Transport Managem GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + GeneralConfig.CorrelationID, + GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() diff --git a/cmd/tmsUpload_generated.go b/cmd/tmsUpload_generated.go index f7ba48b014..db71270c10 100644 --- a/cmd/tmsUpload_generated.go +++ b/cmd/tmsUpload_generated.go @@ -9,6 +9,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/piperenv" "github.com/SAP/jenkins-library/pkg/splunk" @@ -132,6 +133,11 @@ For more information, see [official documentation of SAP Cloud Transport Managem return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -158,6 +164,19 @@ For more information, see [official documentation of SAP Cloud Transport Managem GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + GeneralConfig.CorrelationID, + GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() diff --git a/cmd/transportRequestDocIDFromGit_generated.go b/cmd/transportRequestDocIDFromGit_generated.go index 7ee82cc71b..bb706d75a2 100644 --- a/cmd/transportRequestDocIDFromGit_generated.go +++ b/cmd/transportRequestDocIDFromGit_generated.go @@ -9,6 +9,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/piperenv" "github.com/SAP/jenkins-library/pkg/splunk" @@ -112,6 +113,11 @@ It is primarily made for the transportRequestUploadSOLMAN step to provide the ch return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -138,6 +144,19 @@ It is primarily made for the transportRequestUploadSOLMAN step to provide the ch GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + GeneralConfig.CorrelationID, + GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() diff --git a/cmd/transportRequestReqIDFromGit_generated.go b/cmd/transportRequestReqIDFromGit_generated.go index 3e7f08e3d4..2c22b5164f 100644 --- a/cmd/transportRequestReqIDFromGit_generated.go +++ b/cmd/transportRequestReqIDFromGit_generated.go @@ -9,6 +9,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/piperenv" "github.com/SAP/jenkins-library/pkg/splunk" @@ -112,6 +113,11 @@ It is primarily made for the transport request upload steps to provide the trans return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -138,6 +144,19 @@ It is primarily made for the transport request upload steps to provide the trans GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + GeneralConfig.CorrelationID, + GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() diff --git a/cmd/transportRequestUploadCTS_generated.go b/cmd/transportRequestUploadCTS_generated.go index cfe60fd63a..7944124f14 100644 --- a/cmd/transportRequestUploadCTS_generated.go +++ b/cmd/transportRequestUploadCTS_generated.go @@ -9,6 +9,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/piperenv" "github.com/SAP/jenkins-library/pkg/splunk" @@ -123,6 +124,11 @@ It processes the results of the ` + "`" + `ui5 build` + "`" + ` command of the S return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -149,6 +155,19 @@ It processes the results of the ` + "`" + `ui5 build` + "`" + ` command of the S GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + GeneralConfig.CorrelationID, + GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() diff --git a/cmd/transportRequestUploadRFC_generated.go b/cmd/transportRequestUploadRFC_generated.go index f8992f3c5e..c49bc45ce9 100644 --- a/cmd/transportRequestUploadRFC_generated.go +++ b/cmd/transportRequestUploadRFC_generated.go @@ -9,6 +9,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/piperenv" "github.com/SAP/jenkins-library/pkg/splunk" @@ -123,6 +124,11 @@ func TransportRequestUploadRFCCommand() *cobra.Command { return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -149,6 +155,19 @@ func TransportRequestUploadRFCCommand() *cobra.Command { GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + GeneralConfig.CorrelationID, + GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() diff --git a/cmd/transportRequestUploadSOLMAN_generated.go b/cmd/transportRequestUploadSOLMAN_generated.go index 13d63fb3bc..eec511b2f0 100644 --- a/cmd/transportRequestUploadSOLMAN_generated.go +++ b/cmd/transportRequestUploadSOLMAN_generated.go @@ -9,6 +9,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/piperenv" "github.com/SAP/jenkins-library/pkg/splunk" @@ -122,6 +123,11 @@ The application ID specifies how the file needs to be handled on server side.`, return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -148,6 +154,19 @@ The application ID specifies how the file needs to be handled on server side.`, GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + GeneralConfig.CorrelationID, + GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() diff --git a/cmd/uiVeri5ExecuteTests_generated.go b/cmd/uiVeri5ExecuteTests_generated.go index 64b8617423..e2496b420a 100644 --- a/cmd/uiVeri5ExecuteTests_generated.go +++ b/cmd/uiVeri5ExecuteTests_generated.go @@ -10,6 +10,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/gcs" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/splunk" @@ -125,6 +126,11 @@ func UiVeri5ExecuteTestsCommand() *cobra.Command { return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -151,6 +157,19 @@ func UiVeri5ExecuteTestsCommand() *cobra.Command { GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + GeneralConfig.CorrelationID, + GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() diff --git a/cmd/vaultRotateSecretId_generated.go b/cmd/vaultRotateSecretId_generated.go index af7bddb19c..db2b78d9a0 100644 --- a/cmd/vaultRotateSecretId_generated.go +++ b/cmd/vaultRotateSecretId_generated.go @@ -8,6 +8,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/splunk" "github.com/SAP/jenkins-library/pkg/telemetry" @@ -99,6 +100,11 @@ func VaultRotateSecretIdCommand() *cobra.Command { return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -124,6 +130,19 @@ func VaultRotateSecretIdCommand() *cobra.Command { GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + GeneralConfig.CorrelationID, + GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() diff --git a/cmd/whitesourceExecuteScan_generated.go b/cmd/whitesourceExecuteScan_generated.go index d5748b20ce..30f29a67f5 100644 --- a/cmd/whitesourceExecuteScan_generated.go +++ b/cmd/whitesourceExecuteScan_generated.go @@ -11,6 +11,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/gcs" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/piperenv" @@ -280,6 +281,11 @@ The step uses the so-called Mend Unified Agent. For details please refer to the return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -308,6 +314,19 @@ The step uses the so-called Mend Unified Agent. For details please refer to the GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + GeneralConfig.CorrelationID, + GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() diff --git a/cmd/xsDeploy_generated.go b/cmd/xsDeploy_generated.go index de5c1c24c5..44086c7f5c 100644 --- a/cmd/xsDeploy_generated.go +++ b/cmd/xsDeploy_generated.go @@ -9,6 +9,7 @@ import ( "time" "github.com/SAP/jenkins-library/pkg/config" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/piperenv" "github.com/SAP/jenkins-library/pkg/splunk" @@ -121,6 +122,11 @@ func XsDeployCommand() *cobra.Command { return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -147,6 +153,19 @@ func XsDeployCommand() *cobra.Command { GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + GeneralConfig.CorrelationID, + GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() diff --git a/go.mod b/go.mod index 72a0c02072..3fecf3bf95 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/SAP/jenkins-library go 1.22.4 require ( + cloud.google.com/go/pubsub v1.36.1 cloud.google.com/go/storage v1.38.0 github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.4.1 github.com/BurntSushi/toml v1.3.2 diff --git a/go.sum b/go.sum index 23fb9a724f..c95413fbec 100644 --- a/go.sum +++ b/go.sum @@ -29,10 +29,14 @@ cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7 cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/iam v1.1.6 h1:bEa06k05IO4f4uJonbB5iAgKTPpABy1ayxaIZV/GHVc= cloud.google.com/go/iam v1.1.6/go.mod h1:O0zxdPeGBoFdWW3HWmBxJsk0pfvNM/p/qa82rWOGTwI= +cloud.google.com/go/kms v1.15.7 h1:7caV9K3yIxvlQPAcaFffhlT7d1qpxjB1wHBtjWa13SM= +cloud.google.com/go/kms v1.15.7/go.mod h1:ub54lbsa6tDkUwnu4W7Yt1aAIFLnspgh0kPGToDukeI= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/pubsub v1.36.1 h1:dfEPuGCHGbWUhaMCTHUFjfroILEkx55iUmKBZTP5f+Y= +cloud.google.com/go/pubsub v1.36.1/go.mod h1:iYjCa9EzWOoBiTdd4ps7QoMtMln5NwaZQpK1hbRfBDE= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= @@ -933,6 +937,8 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yusufpapurcu/wmi v1.2.3 h1:E1ctvB7uKFMOJw3fdOW32DwGE9I7t++CRUEMKvFoFiw= github.com/yusufpapurcu/wmi v1.2.3/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0= +go.einride.tech/aip v0.66.0 h1:XfV+NQX6L7EOYK11yoHHFtndeaWh3KbD9/cN/6iWEt8= +go.einride.tech/aip v0.66.0/go.mod h1:qAhMsfT7plxBX+Oy7Huol6YUvZ0ZzdUz26yZsQwfl1M= go.mongodb.org/mongo-driver v1.0.3/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.1.1/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qLUO4lqsUM= diff --git a/pkg/abaputils/manageGitRepositoryUtils.go b/pkg/abaputils/manageGitRepositoryUtils.go index 73da35c043..f9a0b11514 100644 --- a/pkg/abaputils/manageGitRepositoryUtils.go +++ b/pkg/abaputils/manageGitRepositoryUtils.go @@ -2,12 +2,14 @@ package abaputils import ( "fmt" + "os" "reflect" "sort" "strings" "time" "github.com/SAP/jenkins-library/pkg/log" + "github.com/SAP/jenkins-library/pkg/piperutils" "github.com/pkg/errors" ) @@ -15,13 +17,37 @@ const numberOfEntriesPerPage = 100000 const logOutputStatusLength = 10 const logOutputTimestampLength = 29 +// Specifies which output option is used for logs +type LogOutputManager struct { + LogOutput string + PiperStep string + FileNameStep string + StepReports []piperutils.Path +} + +func PersistArchiveLogsForPiperStep(logOutputManager *LogOutputManager) { + fileUtils := piperutils.Files{} + switch logOutputManager.PiperStep { + case "clone": + piperutils.PersistReportsAndLinks("abapEnvironmentCloneGitRepo", "", fileUtils, logOutputManager.StepReports, nil) + case "pull": + piperutils.PersistReportsAndLinks("abapEnvironmentPullGitRepo", "", fileUtils, logOutputManager.StepReports, nil) + case "checkoutBranch": + piperutils.PersistReportsAndLinks("abapEnvironmentCheckoutBranch", "", fileUtils, logOutputManager.StepReports, nil) + default: + log.Entry().Info("Cannot save log archive because no piper step was defined.") + } +} + // PollEntity periodically polls the action entity to get the status. Check if the import is still running -func PollEntity(api SoftwareComponentApiInterface, pollIntervall time.Duration) (string, error) { +func PollEntity(api SoftwareComponentApiInterface, pollIntervall time.Duration, logOutputManager *LogOutputManager) (string, error) { log.Entry().Info("Start polling the status...") var statusCode string = "R" var err error + api.initialRequest() + for { // pullEntity, responseStatus, err := api.GetStatus(failureMessageClonePull+repositoryName, connectionDetails, client) statusCode, err = api.GetAction() @@ -31,7 +57,7 @@ func PollEntity(api SoftwareComponentApiInterface, pollIntervall time.Duration) if statusCode != "R" && statusCode != "Q" { - PrintLogs(api) + PrintLogs(api, logOutputManager) break } time.Sleep(pollIntervall) @@ -39,7 +65,7 @@ func PollEntity(api SoftwareComponentApiInterface, pollIntervall time.Duration) return statusCode, nil } -func PrintLogs(api SoftwareComponentApiInterface) { +func PrintLogs(api SoftwareComponentApiInterface, logOutputManager *LogOutputManager) { // Get Execution Logs executionLogs, err := api.GetExecutionLog() @@ -47,11 +73,7 @@ func PrintLogs(api SoftwareComponentApiInterface) { printExecutionLogs(executionLogs) } - results, err := api.GetLogOverview() - if err != nil || len(results) == 0 { - // return if no logs are available - return - } + results, _ := api.GetLogOverview() // Sort logs sort.SliceStable(results, func(i, j int) bool { @@ -60,13 +82,31 @@ func PrintLogs(api SoftwareComponentApiInterface) { printOverview(results, api) - // Print Details - for _, logEntryForDetails := range results { - printLog(logEntryForDetails, api) + if logOutputManager.LogOutput == "ZIP" { + // get zip file as byte array + zipfile, err := api.GetLogArchive() + // Saving logs in file and adding to piperutils to archive file + if err == nil { + fileName := "LogArchive-" + logOutputManager.FileNameStep + "-" + strings.Replace(api.getRepositoryName(), "/", "_", -1) + "-" + api.getUUID() + "_" + time.Now().Format("2006-01-02T15:04:05") + ".zip" + + err = os.WriteFile(fileName, zipfile, 0o644) + + if err == nil { + log.Entry().Infof("Writing %s file was successful", fileName) + logOutputManager.StepReports = append(logOutputManager.StepReports, piperutils.Path{Target: fileName, Name: "Log_Archive_" + api.getUUID(), Mandatory: true}) + } + } + + } else { + // Print Details + if len(results) != 0 { + for _, logEntryForDetails := range results { + printLog(logEntryForDetails, api) + } + } + AddDefaultDashedLine(1) } - AddDefaultDashedLine(1) - return } func printExecutionLogs(executionLogs ExecutionLog) { @@ -82,6 +122,10 @@ func printExecutionLogs(executionLogs ExecutionLog) { func printOverview(results []LogResultsV2, api SoftwareComponentApiInterface) { + if len(results) == 0 { + return + } + logOutputPhaseLength, logOutputLineLength := calculateLenghts(results) log.Entry().Infof("\n") diff --git a/pkg/abaputils/manageGitRepositoryUtils_test.go b/pkg/abaputils/manageGitRepositoryUtils_test.go index 557c742cea..e1173ec6ab 100644 --- a/pkg/abaputils/manageGitRepositoryUtils_test.go +++ b/pkg/abaputils/manageGitRepositoryUtils_test.go @@ -10,6 +10,7 @@ import ( "os" "testing" + "github.com/SAP/jenkins-library/pkg/piperutils" "github.com/stretchr/testify/assert" ) @@ -63,7 +64,14 @@ func TestPollEntity(t *testing.T) { repo := Repository{Name: "testRepo1"} api, _ := swcManager.GetAPI(con, repo) - status, _ := PollEntity(api, 0) + var reports []piperutils.Path + logOutputManager := LogOutputManager{ + LogOutput: "STANDARD", + PiperStep: "pull", + StepReports: reports, + } + + status, _ := PollEntity(api, 0, &logOutputManager) assert.Equal(t, "S", status) assert.Equal(t, 0, len(client.BodyList), "Not all requests were done") }) @@ -95,7 +103,14 @@ func TestPollEntity(t *testing.T) { repo := Repository{Name: "testRepo1"} api, _ := swcManager.GetAPI(con, repo) - status, _ := PollEntity(api, 0) + var reports []piperutils.Path + logOutputManager := LogOutputManager{ + LogOutput: "STANDARD", + PiperStep: "pull", + StepReports: reports, + } + + status, _ := PollEntity(api, 0, &logOutputManager) assert.Equal(t, "E", status) assert.Equal(t, 0, len(client.BodyList), "Not all requests were done") }) diff --git a/pkg/abaputils/sap_com_0510.go b/pkg/abaputils/sap_com_0510.go index 24d3d99251..556fc1b74c 100644 --- a/pkg/abaputils/sap_com_0510.go +++ b/pkg/abaputils/sap_com_0510.go @@ -225,6 +225,10 @@ func (api *SAP_COM_0510) GetAction() (string, error) { return abapStatusCode, nil } +func (api *SAP_COM_0510) getRepositoryName() string { + return api.repository.Name +} + func (api *SAP_COM_0510) GetRepository() (bool, string, error, bool) { if api.repository.Name == "" { @@ -404,3 +408,8 @@ func (api *SAP_COM_0510) ConvertTime(logTimeStamp string) time.Time { func (api *SAP_COM_0510) UpdateRepoWithBYOGCredentials(byogAuthMethod string, byogUsername string, byogPassword string) { panic("UpdateRepoWithBYOGCredentials cannot be used in SAP_COM_0510") } + +// Dummy implementation of the "optional" method LogArchive (only used in SAP_COM_0948) +func (api *SAP_COM_0510) GetLogArchive() (result []byte, err error) { + panic("GetLogArchive cannot be used in SAP_COM_0510") +} diff --git a/pkg/abaputils/sap_com_0948.go b/pkg/abaputils/sap_com_0948.go index b006b6cead..5d8477c190 100644 --- a/pkg/abaputils/sap_com_0948.go +++ b/pkg/abaputils/sap_com_0948.go @@ -239,6 +239,10 @@ func (api *SAP_COM_0948) GetAction() (string, error) { return abapStatusCode, nil } +func (api *SAP_COM_0948) getRepositoryName() string { + return api.repository.Name +} + func (api *SAP_COM_0948) GetRepository() (bool, string, error, bool) { if api.repository.Name == "" { @@ -306,6 +310,28 @@ func (api *SAP_COM_0948) Clone() error { } +func (api *SAP_COM_0948) GetLogArchive() (result []byte, err error) { + + connectionDetails := api.con + connectionDetails.URL = api.con.URL + api.path + "/LogArchive/" + api.getUUID() + "/download" + resp, err := GetHTTPResponse("GET", connectionDetails, nil, api.client) + if err != nil { + log.SetErrorCategory(log.ErrorInfrastructure) + _, err = handleHTTPError(resp, err, api.failureMessage, connectionDetails) + } + + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + fmt.Println("Error: HTTP Status", resp.StatusCode) + return nil, resp.Request.Context().Err() + } + + body, err := io.ReadAll(resp.Body) + + return body, err +} + func (api *SAP_COM_0948) triggerRequest(cloneConnectionDetails ConnectionDetailsHTTP, jsonBody []byte) error { var err error var body ActionEntity diff --git a/pkg/abaputils/sap_com_0948_test.go b/pkg/abaputils/sap_com_0948_test.go index c0f33bdf3c..580dbd9316 100644 --- a/pkg/abaputils/sap_com_0948_test.go +++ b/pkg/abaputils/sap_com_0948_test.go @@ -573,3 +573,25 @@ func TestGetExecutionLog(t *testing.T) { assert.Equal(t, "First log entry", results.Value[0].Descr) }) } + +func TestGetLogArchive(t *testing.T) { + t.Run("Test Get Log Archive Success", func(t *testing.T) { + + client := &ClientMock{ + BodyList: []string{ + `{ zip content from log archive endpoint }`, + ``, + }, + Token: "myToken", + StatusCode: 200, + } + + apiManager := &SoftwareComponentApiManager{Client: client} + + api, _ := apiManager.GetAPI(conTest0948, Repository{Name: "/DMO/REPO"}) + + results, errAction := api.GetLogArchive() + assert.NoError(t, errAction) + assert.NotEmpty(t, results) + }) +} diff --git a/pkg/abaputils/softwareComponentApiManager.go b/pkg/abaputils/softwareComponentApiManager.go index 0bd7b712f9..720e3066db 100644 --- a/pkg/abaputils/softwareComponentApiManager.go +++ b/pkg/abaputils/softwareComponentApiManager.go @@ -59,6 +59,7 @@ type SoftwareComponentApiInterface interface { setSleepTimeConfig(timeUnit time.Duration, maxSleepTime time.Duration) getSleepTime(n int) (time.Duration, error) getUUID() string + getRepositoryName() string GetRepository() (bool, string, error, bool) Clone() error Pull() error @@ -69,6 +70,7 @@ type SoftwareComponentApiInterface interface { GetLogProtocol(LogResultsV2, int) (result []LogProtocol, count int, err error) ConvertTime(logTimeStamp string) time.Time GetExecutionLog() (ExecutionLog, error) + GetLogArchive() (result []byte, err error) UpdateRepoWithBYOGCredentials(string, string, string) } diff --git a/pkg/config/config.go b/pkg/config/config.go index 13e91771f3..c031b70fd0 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -274,13 +274,12 @@ func (c *Config) GetStepConfig(flagValues map[string]interface{}, paramJSON stri // check whether vault should be skipped if skip, ok := stepConfig.Config["skipVault"].(bool); !ok || !skip { - // fetch secrets from vault + // Revocation of Vault token will happen at the of each step execution (see _generated.go part) vaultClient, err := GetVaultClientFromConfig(stepConfig.Config, c.vaultCredentials) if err != nil { return StepConfig{}, err } if vaultClient != nil { - defer vaultClient.MustRevokeToken() resolveAllVaultReferences(&stepConfig, vaultClient, append(parameters, ReportingParameters.Parameters...)) resolveVaultTestCredentialsWrapper(&stepConfig, vaultClient) resolveVaultCredentialsWrapper(&stepConfig, vaultClient) diff --git a/pkg/config/vault.go b/pkg/config/vault.go index d9cd73c85d..db53761039 100644 --- a/pkg/config/vault.go +++ b/pkg/config/vault.go @@ -82,6 +82,18 @@ type VaultClient interface { GetOIDCTokenByValidation(string) (string, error) } +// globalVaultClient is supposed to be used in the steps code. +var globalVaultClient *vault.Client + +func GlobalVaultClient() VaultClient { + // an interface containing a nil pointer is considered non-nil in Go + if globalVaultClient == nil { + return nil + } + + return globalVaultClient +} + func (s *StepConfig) mixinVaultConfig(parameters []StepParameters, configs ...map[string]interface{}) { for _, config := range configs { s.mixIn(config, vaultFilter, StepData{}) @@ -92,6 +104,9 @@ func (s *StepConfig) mixinVaultConfig(parameters []StepParameters, configs ...ma } } +// GetVaultClientFromConfig logs in to Vault and returns authorized Vault client. +// It's important to revoke token provided to this client after usage. +// Currently, revocation will happen at the end of each step execution (see _generated.go part of the steps) func GetVaultClientFromConfig(config map[string]interface{}, creds VaultCredentials) (VaultClient, error) { address, addressOk := config["vaultServerUrl"].(string) // if vault isn't used it's not an error @@ -107,7 +122,7 @@ func GetVaultClientFromConfig(config map[string]interface{}, creds VaultCredenti namespace = config["vaultNamespace"].(string) log.Entry().Debugf(" with namespace %s", namespace) } - var client VaultClient + var client vault.Client var err error clientConfig := &vault.Config{Config: &api.Config{Address: address}, Namespace: namespace} if creds.VaultToken != "" { @@ -121,6 +136,10 @@ func GetVaultClientFromConfig(config map[string]interface{}, creds VaultCredenti log.Entry().Info(" failed") return nil, err } + + // Set global vault client for usage in steps + globalVaultClient = &client + log.Entry().Info(" succeeded") return client, nil } diff --git a/pkg/gcp/pubsub.go b/pkg/gcp/pubsub.go index 1e52bbb23a..b2f09d6bed 100644 --- a/pkg/gcp/pubsub.go +++ b/pkg/gcp/pubsub.go @@ -1,66 +1,80 @@ package gcp import ( - "bytes" + "cloud.google.com/go/pubsub" "context" - "encoding/json" - "fmt" - "net/http" - + piperConfig "github.com/SAP/jenkins-library/pkg/config" "github.com/SAP/jenkins-library/pkg/log" "github.com/pkg/errors" + "golang.org/x/oauth2" + "google.golang.org/api/option" ) -const api_url = "https://pubsub.googleapis.com/v1/projects/%s/topics/%s:publish" +type PubsubClient interface { + Publish(topic string, data []byte) error +} -// https://pkg.go.dev/cloud.google.com/go/pubsub#Message -type EventMessage struct { - Data []byte `json:"data"` - OrderingKey string `json:"orderingKey"` +type pubsubClient struct { + vaultClient piperConfig.VaultClient + projectNumber string + pool string + provider string + orderingKey string + oidcRoleId string } -type Event struct { - Messages []EventMessage `json:"messages"` +func NewGcpPubsubClient(vaultClient piperConfig.VaultClient, projectNumber, pool, provider, orderingKey, oidcRoleId string) PubsubClient { + return &pubsubClient{ + vaultClient: vaultClient, + projectNumber: projectNumber, + pool: pool, + provider: provider, + orderingKey: orderingKey, + oidcRoleId: oidcRoleId, + } } -func Publish(projectNumber string, topic string, token string, key string, data []byte) error { +func (cl *pubsubClient) Publish(topic string, data []byte) error { ctx := context.Background() + psClient, err := cl.getAuthorizedGCPClient(ctx) + if err != nil { + return errors.Wrap(err, "could not get authorized pubsub client token") + } - // build event - event := Event{ - Messages: []EventMessage{{ - Data: data, - OrderingKey: key, - }}, + return cl.publish(ctx, psClient, topic, cl.orderingKey, data) +} + +func (cl *pubsubClient) getAuthorizedGCPClient(ctx context.Context) (*pubsub.Client, error) { + if cl.vaultClient == nil { + return nil, errors.New("Vault client is not configured") } - // marshal event - eventBytes, err := json.Marshal(event) + oidcToken, err := cl.vaultClient.GetOIDCTokenByValidation(cl.oidcRoleId) if err != nil { - return errors.Wrap(err, "failed to marshal event") + return nil, errors.Wrap(err, "could not get oidc token") } - log.Entry().Debugf("created pubsub event: %s", string(eventBytes)) - // create request - request, err := http.NewRequestWithContext(ctx, http.MethodPost, fmt.Sprintf(api_url, projectNumber, topic), bytes.NewReader(eventBytes)) + accessToken, err := getFederatedToken(cl.projectNumber, cl.pool, cl.provider, oidcToken) if err != nil { - return errors.Wrap(err, "failed to create request") + return nil, errors.Wrap(err, "could not get federated token") } - // add headers - request.Header.Set("Content-Type", "application/json") - request.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token)) + staticTokenSource := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: accessToken}) + return pubsub.NewClient(ctx, cl.projectNumber, option.WithTokenSource(staticTokenSource)) +} + +func (cl *pubsubClient) publish(ctx context.Context, psClient *pubsub.Client, topic, orderingKey string, data []byte) error { + t := psClient.Topic(topic) + t.EnableMessageOrdering = true + publishResult := t.Publish(ctx, &pubsub.Message{Data: data, OrderingKey: orderingKey}) - // send request - response, err := http.DefaultClient.Do(request) + // publishResult.Get() will make API call synchronous by awaiting messageId or error. + // By removing .Get() method call we can make publishing asynchronous, but without ability to catch errors + msgID, err := publishResult.Get(context.Background()) if err != nil { - return errors.Wrap(err, "failed to send request") + return errors.Wrap(err, "event publish failed") } - if response.StatusCode != http.StatusOK { - return fmt.Errorf("invalid status code: %v", response.StatusCode) - } - - //TODO: read response & messageIds + log.Entry().Debugf("Event published with ID: %s", msgID) return nil } diff --git a/pkg/gcp/pubsub_test.go b/pkg/gcp/pubsub_test.go deleted file mode 100644 index a25e0a3b38..0000000000 --- a/pkg/gcp/pubsub_test.go +++ /dev/null @@ -1,45 +0,0 @@ -package gcp - -import ( - "fmt" - "net/http" - "testing" - - "github.com/jarcoal/httpmock" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/mock" -) - -func TestPublish(t *testing.T) { - t.Run("success", func(t *testing.T) { - // init - projectNumber := "PROJECT_NUMBER" - topic := "TOPIC" - token := "TOKEN" - data := []byte(mock.Anything) - - apiurl := fmt.Sprintf(api_url, projectNumber, topic) - - mockResponse := map[string]interface{}{ - "messageIds": []string{"10721501285371497"}, - } - - // mock - httpmock.Activate() - defer httpmock.DeactivateAndReset() - httpmock.RegisterResponder(http.MethodPost, apiurl, - func(req *http.Request) (*http.Response, error) { - assert.Contains(t, req.Header, "Authorization") - assert.Equal(t, req.Header.Get("Authorization"), "Bearer TOKEN") - assert.Contains(t, req.Header, "Content-Type") - assert.Equal(t, req.Header.Get("Content-Type"), "application/json") - return httpmock.NewJsonResponse(http.StatusOK, mockResponse) - }, - ) - - // test - err := Publish(projectNumber, topic, token, mock.Anything, data) - // asserts - assert.NoError(t, err) - }) -} diff --git a/pkg/gcp/token.go b/pkg/gcp/token.go index fe7a59346a..fc00b1909d 100644 --- a/pkg/gcp/token.go +++ b/pkg/gcp/token.go @@ -1,57 +1,82 @@ package gcp import ( - "bytes" "context" - "encoding/json" "fmt" - "net/http" + "github.com/SAP/jenkins-library/pkg/log" + "google.golang.org/api/option" + "os" + "strconv" + "time" "github.com/pkg/errors" "google.golang.org/api/sts/v1" ) -// https://cloud.google.com/iam/docs/reference/sts/rest -const exchangeTokenAPIURL = "https://sts.googleapis.com/v1/token" +const ( + gcpPubsubTokenKey = "PIPER_gcpPubsubToken" + gcpPubsubTokenExpiryKey = "PIPER_gcpPubsubTokenExpiresAt" +) -func GetFederatedToken(projectNumber, pool, provider, token string) (string, error) { - ctx := context.Background() - requestData := getExchangeTokenRequestData(projectNumber, pool, provider, token) +// getFederatedToken tries to retrieve cached token from env variables, otherwise it will exchange +// OIDC identity token to access token and cache them in env variables +func getFederatedToken(projectNumber, pool, provider, oidcToken string) (string, error) { + cachedToken := os.Getenv(gcpPubsubTokenKey) + cachedExpiresAt := os.Getenv(gcpPubsubTokenExpiryKey) + if tokenIsValid(cachedToken, cachedExpiresAt) { + log.Entry().Debug("reusing GCP PubSub access token from cache") + return cachedToken, nil + } - // data to byte - jsonData, err := json.Marshal(requestData) + ctx := context.Background() + token, expiresAt, err := exchangeOIDCToken(ctx, projectNumber, pool, provider, oidcToken) if err != nil { - return "", errors.Wrapf(err, "failed to marshal the request data") + return "", errors.Wrap(err, "token exchange") + } + + os.Setenv(gcpPubsubTokenKey, token) + os.Setenv(gcpPubsubTokenExpiryKey, strconv.FormatInt(expiresAt, 10)) + return token, nil +} + +// exchangeOIDCToken exchanges OIDC identity token to access token and returns expiry time in Unix timestamp +func exchangeOIDCToken(ctx context.Context, projectNumber, pool, provider, oidcToken string) (string, int64, error) { + if len(oidcToken) == 0 { + return "", 0, errors.New("OIDC identity token is absent") } - // build request - request, err := http.NewRequestWithContext(ctx, http.MethodPost, exchangeTokenAPIURL, bytes.NewReader(jsonData)) + stsService, err := sts.NewService(ctx, option.WithoutAuthentication()) if err != nil { - return "", errors.Wrap(err, "failed to build request") + return "", 0, errors.Wrap(err, "service not created") } - // send request - response, err := http.DefaultClient.Do(request) + request := getExchangeTokenRequestData(projectNumber, pool, provider, oidcToken) + response, err := sts.NewV1Service(stsService).Token(request).Context(ctx).Do() if err != nil { - return "", errors.Wrap(err, "failed to send request") + return "", 0, errors.Wrap(err, "exchange failed") } - if response.StatusCode != http.StatusOK { - return "", fmt.Errorf("invalid status code: %v", response.StatusCode) + + expiresAt := time.Now().Unix() + response.ExpiresIn + log.Entry().Debugf("token successfully exchanged and will expire at %s", time.Unix(expiresAt, 0)) + return response.AccessToken, expiresAt, nil +} + +func tokenIsValid(token string, expiresAtStr string) bool { + if token == "" { + return false } - // response to data - defer response.Body.Close() - responseData := sts.GoogleIdentityStsV1ExchangeTokenResponse{} - err = json.NewDecoder(response.Body).Decode(&responseData) - if err != nil { - return "", errors.Wrap(err, "failed to decode response") + expiresAt, _ := strconv.Atoi(expiresAtStr) + buffer := 5 // 5 second buffer to prevent using token that potentially may expire during execution + if int64(expiresAt-buffer) < time.Now().Unix() { + return false } - return responseData.AccessToken, nil + return true } -func getExchangeTokenRequestData(projectNumber string, pool string, provider string, token string) sts.GoogleIdentityStsV1ExchangeTokenRequest { - return sts.GoogleIdentityStsV1ExchangeTokenRequest{ +func getExchangeTokenRequestData(projectNumber string, pool string, provider string, token string) *sts.GoogleIdentityStsV1ExchangeTokenRequest { + return &sts.GoogleIdentityStsV1ExchangeTokenRequest{ Audience: fmt.Sprintf( "//iam.googleapis.com/projects/%s/locations/global/workloadIdentityPools/%s/providers/%s", projectNumber, pool, provider), diff --git a/pkg/gcp/token_test.go b/pkg/gcp/token_test.go index 00d5a6131a..81615916dd 100644 --- a/pkg/gcp/token_test.go +++ b/pkg/gcp/token_test.go @@ -1,13 +1,12 @@ package gcp import ( - "net/http" + "fmt" "testing" + "time" - "github.com/jarcoal/httpmock" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" - "google.golang.org/api/sts/v1" ) func TestGetExchangeTokenRequestData(t *testing.T) { @@ -25,26 +24,44 @@ func TestGetExchangeTokenRequestData(t *testing.T) { }) } -func TestGetFederatedToken(t *testing.T) { - t.Run("success", func(t *testing.T) { - // init - projectNumber := "PROJECT_NUMBER" - pool := "POOL" - provider := "PROVIDER" - - // mock - httpmock.Activate() - defer httpmock.DeactivateAndReset() - httpmock.RegisterResponder(http.MethodPost, exchangeTokenAPIURL, - func(req *http.Request) (*http.Response, error) { - return httpmock.NewJsonResponse(http.StatusOK, sts.GoogleIdentityStsV1ExchangeTokenResponse{AccessToken: mock.Anything}) - }, - ) - - // test - federatedToken, err := GetFederatedToken(projectNumber, pool, provider, mock.Anything) - // asserts - assert.NoError(t, err) - assert.Equal(t, mock.Anything, federatedToken) - }) +func Test_tokenIsValid(t *testing.T) { + nowUnix := time.Now().Unix() + tests := []struct { + name string + token string + expiresAtStr string + want bool + }{ + { + "token is empty", + "", + "", + false, + }, { + "token expiredAt is empty", + "someToken", + "", + false, + }, { + "token is expired", + "someToken", + fmt.Sprintf("%d", nowUnix-100), // expiresAt is 100 seconds ahead + false, + }, { + "token is expired inside buffered timeframe", + "someToken", + fmt.Sprintf("%d", nowUnix+3), // expiresAt is 3 seconds before + false, + }, { + "token is valid", + "someToken", + fmt.Sprintf("%d", nowUnix+100), // expiresAt is 100 seconds before + true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + assert.Equalf(t, tt.want, tokenIsValid(tt.token, tt.expiresAtStr), "tokenIsValid(%v, %v)", tt.token, tt.expiresAtStr) + }) + } } diff --git a/pkg/generator/helper/helper.go b/pkg/generator/helper/helper.go index 75e25c183c..a7a0ef2126 100644 --- a/pkg/generator/helper/helper.go +++ b/pkg/generator/helper/helper.go @@ -77,6 +77,7 @@ import ( {{ if or $influxOutputExists $piperEnvironmentOutputExists -}} "github.com/SAP/jenkins-library/pkg/piperenv" {{ end -}} + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/telemetry" "github.com/SAP/jenkins-library/pkg/splunk" "github.com/SAP/jenkins-library/pkg/validation" @@ -166,6 +167,11 @@ func {{.CobraCmdFuncName}}() *cobra.Command { return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -201,6 +207,19 @@ func {{.CobraCmdFuncName}}() *cobra.Command { {{if .ExportPrefix}}{{ .ExportPrefix }}.{{end}}GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if {{if .ExportPrefix}}{{ .ExportPrefix }}.{{end}}GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + {{if .ExportPrefix}}{{ .ExportPrefix }}.{{end}}GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + {{if .ExportPrefix}}{{ .ExportPrefix }}.{{end}}GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + {{if .ExportPrefix}}{{ .ExportPrefix }}.{{end}}GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + {{if .ExportPrefix}}{{ .ExportPrefix }}.{{end}}GeneralConfig.CorrelationID, + {{if .ExportPrefix}}{{ .ExportPrefix }}.{{end}}GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish({{if .ExportPrefix}}{{ .ExportPrefix }}.{{end}}GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() diff --git a/pkg/generator/helper/testdata/TestProcessMetaFiles/custom_step_code_generated.golden b/pkg/generator/helper/testdata/TestProcessMetaFiles/custom_step_code_generated.golden index 1026b6a99d..e63761d01f 100644 --- a/pkg/generator/helper/testdata/TestProcessMetaFiles/custom_step_code_generated.golden +++ b/pkg/generator/helper/testdata/TestProcessMetaFiles/custom_step_code_generated.golden @@ -16,6 +16,7 @@ import ( "github.com/bmatcuk/doublestar" "github.com/SAP/jenkins-library/pkg/gcs" "github.com/SAP/jenkins-library/pkg/piperenv" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/telemetry" "github.com/SAP/jenkins-library/pkg/splunk" "github.com/SAP/jenkins-library/pkg/validation" @@ -203,6 +204,11 @@ func TestStepCommand() *cobra.Command { return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -231,6 +237,19 @@ func TestStepCommand() *cobra.Command { piperOsCmd.GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if piperOsCmd.GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + piperOsCmd.GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + piperOsCmd.GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + piperOsCmd.GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + piperOsCmd.GeneralConfig.CorrelationID, + piperOsCmd.GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(piperOsCmd.GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() diff --git a/pkg/generator/helper/testdata/TestProcessMetaFiles/step_code_generated.golden b/pkg/generator/helper/testdata/TestProcessMetaFiles/step_code_generated.golden index fff8b15101..eb755eb6a9 100644 --- a/pkg/generator/helper/testdata/TestProcessMetaFiles/step_code_generated.golden +++ b/pkg/generator/helper/testdata/TestProcessMetaFiles/step_code_generated.golden @@ -15,6 +15,7 @@ import ( "github.com/bmatcuk/doublestar" "github.com/SAP/jenkins-library/pkg/gcs" "github.com/SAP/jenkins-library/pkg/piperenv" + "github.com/SAP/jenkins-library/pkg/gcp" "github.com/SAP/jenkins-library/pkg/telemetry" "github.com/SAP/jenkins-library/pkg/splunk" "github.com/SAP/jenkins-library/pkg/validation" @@ -202,6 +203,11 @@ func TestStepCommand() *cobra.Command { return nil }, Run: func(_ *cobra.Command, _ []string) { + vaultClient := config.GlobalVaultClient() + if vaultClient != nil { + defer vaultClient.MustRevokeToken() + } + stepTelemetryData := telemetry.CustomData{} stepTelemetryData.ErrorCode = "1" handler := func() { @@ -230,6 +236,19 @@ func TestStepCommand() *cobra.Command { GeneralConfig.HookConfig.SplunkConfig.SendLogs) splunkClient.Send(telemetryClient.GetData(), logCollector) } + if GeneralConfig.HookConfig.GCPPubSubConfig.Enabled { + err := gcp.NewGcpPubsubClient( + vaultClient, + GeneralConfig.HookConfig.GCPPubSubConfig.ProjectNumber, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityPool, + GeneralConfig.HookConfig.GCPPubSubConfig.IdentityProvider, + GeneralConfig.CorrelationID, + GeneralConfig.HookConfig.OIDCConfig.RoleID, + ).Publish(GeneralConfig.HookConfig.GCPPubSubConfig.Topic, telemetryClient.GetDataBytes()) + if err != nil { + log.Entry().WithError(err).Warn("event publish failed") + } + } } log.DeferExitHandler(handler) defer handler() diff --git a/pkg/npm/npm.go b/pkg/npm/npm.go index 4c8130c9b6..6e36ace72f 100644 --- a/pkg/npm/npm.go +++ b/pkg/npm/npm.go @@ -96,7 +96,7 @@ func (exec *Execute) SetNpmRegistries() error { var buffer bytes.Buffer execRunner.Stdout(&buffer) - err := execRunner.RunExecutable("npm", "config", "get", npmRegistry) + err := execRunner.RunExecutable("npm", "config", "get", npmRegistry, "-ws=false", "-iwr") execRunner.Stdout(log.Writer()) if err != nil { return err @@ -109,7 +109,7 @@ func (exec *Execute) SetNpmRegistries() error { if exec.Options.DefaultNpmRegistry != "" && registryRequiresConfiguration(preConfiguredRegistry, "https://registry.npmjs.org") { log.Entry().Info("npm registry " + npmRegistry + " was not configured, setting it to " + exec.Options.DefaultNpmRegistry) - err = execRunner.RunExecutable("npm", "config", "set", npmRegistry, exec.Options.DefaultNpmRegistry) + err = execRunner.RunExecutable("npm", "config", "set", npmRegistry, exec.Options.DefaultNpmRegistry, "-ws=false", "-iwr") if err != nil { return err } diff --git a/pkg/npm/npm_test.go b/pkg/npm/npm_test.go index 52ef6e085a..ea4677ee3c 100644 --- a/pkg/npm/npm_test.go +++ b/pkg/npm/npm_test.go @@ -299,7 +299,7 @@ func TestNpm(t *testing.T) { utils := newNpmMockUtilsBundle() utils.AddFile("package.json", []byte("{\"scripts\": { \"ci-lint\": \"exit 0\" } }")) utils.AddFile(filepath.Join("src", "package.json"), []byte("{\"scripts\": { \"ci-build\": \"exit 0\" } }")) - utils.execRunner = &mock.ExecMockRunner{StdoutReturn: map[string]string{"npm config get registry": "undefined"}} + utils.execRunner = &mock.ExecMockRunner{StdoutReturn: map[string]string{"npm config get registry -ws=false -iwr": "undefined"}} options := ExecutorOptions{} options.DefaultNpmRegistry = "https://example.org/npm" @@ -311,8 +311,8 @@ func TestNpm(t *testing.T) { if assert.NoError(t, err) { if assert.Equal(t, 2, len(utils.execRunner.Calls)) { - assert.Equal(t, mock.ExecCall{Exec: "npm", Params: []string{"config", "get", "registry"}}, utils.execRunner.Calls[0]) - assert.Equal(t, mock.ExecCall{Exec: "npm", Params: []string{"config", "set", "registry", exec.Options.DefaultNpmRegistry}}, utils.execRunner.Calls[1]) + assert.Equal(t, mock.ExecCall{Exec: "npm", Params: []string{"config", "get", "registry", "-ws=false", "-iwr"}}, utils.execRunner.Calls[0]) + assert.Equal(t, mock.ExecCall{Exec: "npm", Params: []string{"config", "set", "registry", exec.Options.DefaultNpmRegistry, "-ws=false", "-iwr"}}, utils.execRunner.Calls[1]) } } }) diff --git a/pkg/telemetry/telemetry.go b/pkg/telemetry/telemetry.go index 6cb6ae542c..12a5d44826 100644 --- a/pkg/telemetry/telemetry.go +++ b/pkg/telemetry/telemetry.go @@ -139,6 +139,16 @@ func (t *Telemetry) GetData() Data { return t.data } +func (t *Telemetry) GetDataBytes() []byte { + data, err := json.Marshal(t.data) + if err != nil { + log.Entry().WithError(err).Println("Failed to marshal data") + return []byte{} + } + + return data +} + // Send telemetry information to SWA func (t *Telemetry) Send() { // always log step telemetry data to logfile used for internal use-case diff --git a/pkg/transportrequest/cts/upload.go b/pkg/transportrequest/cts/upload.go index fb22b4260e..a50458df70 100644 --- a/pkg/transportrequest/cts/upload.go +++ b/pkg/transportrequest/cts/upload.go @@ -2,10 +2,12 @@ package cts import ( "fmt" + "regexp" + "strings" + "github.com/SAP/jenkins-library/pkg/command" "github.com/SAP/jenkins-library/pkg/log" "github.com/SAP/jenkins-library/pkg/piperutils" - "strings" ) type fileUtils interface { @@ -60,6 +62,7 @@ const ( abapUserKey = "ABAP_USER" abapPasswordKey = "ABAP_PASSWORD" defaultConfigFileName = "ui5-deploy.yaml" + pattern = "^[a-zA-Z0-9_]+$" ) // WithConnection ... @@ -189,6 +192,10 @@ func getFioriDeployStatement( log.Entry().Debug("No application package found in piper config.") } if len(app.Name) > 0 { + re := regexp.MustCompile(pattern) + if !re.MatchString(app.Name) { + fmt.Errorf("application name '%s' contains spaces or special characters. It is not according to the '%s'", app.Name, pattern) + } log.Entry().Debugf("application name '%s' used from piper config", app.Name) cmd = append(cmd, "--name", app.Name) } else { diff --git a/pkg/vault/oidc.go b/pkg/vault/oidc.go index a5ad6b790f..493050d04d 100644 --- a/pkg/vault/oidc.go +++ b/pkg/vault/oidc.go @@ -49,6 +49,10 @@ func getJWTTokenPayload(token string) ([]byte, error) { } func oidcTokenIsValid(token string) bool { + if token == "" { + return false + } + payload, err := getJWTTokenPayload(token) if err != nil { log.Entry().Debugf("OIDC token couldn't be validated: %s", err) @@ -71,13 +75,13 @@ func oidcTokenIsValid(token string) bool { // GetOIDCTokenByValidation returns the token if token is expired then get a new token else return old token func (v Client) GetOIDCTokenByValidation(roleID string) (string, error) { token := os.Getenv("PIPER_OIDCIdentityToken") - if token != "" && oidcTokenIsValid(token) { + if oidcTokenIsValid(token) { return token, nil } token, err := v.getOIDCToken(roleID) if token == "" || err != nil { - return "", errors.Wrap(err, "failed to get OIDC token") + return "", err } return token, nil diff --git a/resources/com.sap.piper/pipeline/abapEnvironmentPipelineDefaults.yml b/resources/com.sap.piper/pipeline/abapEnvironmentPipelineDefaults.yml index dee60fe06a..e01cc82dbc 100644 --- a/resources/com.sap.piper/pipeline/abapEnvironmentPipelineDefaults.yml +++ b/resources/com.sap.piper/pipeline/abapEnvironmentPipelineDefaults.yml @@ -19,6 +19,7 @@ stages: cfServiceKeyConfig: '{"scenario_id":"SAP_COM_0948","type":"basic"}' cfAsync: false ordinal: 30 + logOutput: STANDARD 'ATC': ordinal: 40 diff --git a/resources/metadata/abapEnvironmentCheckoutBranch.yaml b/resources/metadata/abapEnvironmentCheckoutBranch.yaml index 37d2729b76..663cc6b4fe 100644 --- a/resources/metadata/abapEnvironmentCheckoutBranch.yaml +++ b/resources/metadata/abapEnvironmentCheckoutBranch.yaml @@ -75,6 +75,17 @@ spec: - PARAMETERS - STAGES - STEPS + - name: logOutput + type: string + description: Specifies how the clone logs from the Manage Software Components App are displayed or saved + scope: + - PARAMETERS + - STAGES + - STEPS + possibleValues: + - ZIP + - STANDARD + default: STANDARD - name: cfApiEndpoint type: string description: Cloud Foundry API Enpoint diff --git a/resources/metadata/abapEnvironmentCloneGitRepo.yaml b/resources/metadata/abapEnvironmentCloneGitRepo.yaml index 6a49f159fa..c4c5829087 100644 --- a/resources/metadata/abapEnvironmentCloneGitRepo.yaml +++ b/resources/metadata/abapEnvironmentCloneGitRepo.yaml @@ -118,6 +118,17 @@ spec: - STAGES - STEPS - GENERAL + - name: logOutput + type: string + description: Specifies how the clone logs from the Manage Software Components App are displayed or saved + scope: + - PARAMETERS + - STAGES + - STEPS + possibleValues: + - ZIP + - STANDARD + default: STANDARD - name: cfApiEndpoint type: string description: Cloud Foundry API Enpoint diff --git a/resources/metadata/abapEnvironmentPullGitRepo.yaml b/resources/metadata/abapEnvironmentPullGitRepo.yaml index ba3da2f3e9..7bf272a82e 100644 --- a/resources/metadata/abapEnvironmentPullGitRepo.yaml +++ b/resources/metadata/abapEnvironmentPullGitRepo.yaml @@ -82,6 +82,17 @@ spec: - STAGES - STEPS - GENERAL + - name: logOutput + type: string + description: Specifies how the clone logs from the Manage Software Components App are displayed or saved + scope: + - PARAMETERS + - STAGES + - STEPS + possibleValues: + - ZIP + - STANDARD + default: STANDARD - name: cfApiEndpoint type: string description: Cloud Foundry API Enpoint