1
0
mirror of https://github.com/SAP/jenkins-library.git synced 2025-02-05 13:25:19 +02:00
sap-jenkins-library/cmd/gcpPublishEvent.go
Jordi van Liempt ce34dd3f3c
fix(gcpPublishEvent): Error handling in non-standard Vault cases (#4938)
* fix error handling in non-standard Vault cases

* handle case where Vault isn't configured and no error is thrown

* remove unnecessary return

---------

Co-authored-by: jliempt <>
2024-05-28 14:19:17 +02:00

129 lines
3.9 KiB
Go

package cmd
import (
piperConfig "github.com/SAP/jenkins-library/pkg/config"
"github.com/SAP/jenkins-library/pkg/events"
"github.com/SAP/jenkins-library/pkg/gcp"
"github.com/SAP/jenkins-library/pkg/log"
"github.com/SAP/jenkins-library/pkg/orchestrator"
"github.com/SAP/jenkins-library/pkg/telemetry"
"github.com/SAP/jenkins-library/pkg/vault"
"github.com/pkg/errors"
)
type gcpPublishEventUtils interface {
GetConfig() *gcpPublishEventOptions
GetOIDCTokenByValidation(roleID string) (string, error)
GetFederatedToken(projectNumber, pool, provider, token string) (string, error)
Publish(projectNumber string, topic string, token string, key string, data []byte) error
}
type gcpPublishEventUtilsBundle struct {
config *gcpPublishEventOptions
*vault.Client
}
func (g gcpPublishEventUtilsBundle) GetConfig() *gcpPublishEventOptions {
return g.config
}
func (g gcpPublishEventUtilsBundle) GetFederatedToken(projectNumber, pool, provider, token string) (string, error) {
return gcp.GetFederatedToken(projectNumber, pool, provider, token)
}
func (g gcpPublishEventUtilsBundle) Publish(projectNumber string, topic string, token string, key string, data []byte) error {
return gcp.Publish(projectNumber, topic, token, key, data)
}
func gcpPublishEvent(config gcpPublishEventOptions, telemetryData *telemetry.CustomData) {
vaultCreds := piperConfig.VaultCredentials{
AppRoleID: GeneralConfig.VaultRoleID,
AppRoleSecretID: GeneralConfig.VaultRoleSecretID,
VaultToken: GeneralConfig.VaultToken,
}
vaultConfig := map[string]interface{}{
"vaultNamespace": config.VaultNamespace,
"vaultServerUrl": config.VaultServerURL,
}
client, err := piperConfig.GetVaultClientFromConfig(vaultConfig, vaultCreds)
if err != nil || client == nil {
log.Entry().WithError(err).Warnf("could not create Vault client: incomplete Vault configuration")
return
}
defer client.MustRevokeToken()
vaultClient, ok := client.(vault.Client)
if !ok {
log.Entry().WithError(err).Warnf("could not create Vault client")
return
}
utils := gcpPublishEventUtilsBundle{
config: &config,
Client: &vaultClient,
}
err = runGcpPublishEvent(utils)
if err != nil {
// do not fail the step
log.Entry().WithError(err).Warnf("step execution failed")
}
}
func runGcpPublishEvent(utils gcpPublishEventUtils) error {
config := utils.GetConfig()
var data []byte
var err error
provider, err := orchestrator.GetOrchestratorConfigProvider(nil)
if err != nil {
log.Entry().WithError(err).Warning("Cannot infer config from CI environment")
}
data, err = createNewEvent(config)
if err != nil {
return errors.Wrap(err, "failed to create event data")
}
oidcToken, err := utils.GetOIDCTokenByValidation(GeneralConfig.HookConfig.OIDCConfig.RoleID)
if err != nil {
return errors.Wrap(err, "failed to get OIDC token")
}
token, err := utils.GetFederatedToken(config.GcpProjectNumber, config.GcpWorkloadIDentityPool, config.GcpWorkloadIDentityPoolProvider, oidcToken)
if err != nil {
return errors.Wrap(err, "failed to get federated token")
}
err = utils.Publish(config.GcpProjectNumber, config.Topic, token, provider.BuildURL(), data)
if err != nil {
return errors.Wrap(err, "failed to publish event")
}
log.Entry().Infof("Event published successfully! With topic: %s", config.Topic)
return nil
}
func createNewEvent(config *gcpPublishEventOptions) ([]byte, error) {
event, err := events.NewEvent(config.EventType, config.EventSource).CreateWithJSONData(config.EventData)
if err != nil {
return []byte{}, errors.Wrap(err, "failed to create new event")
}
err = event.AddToCloudEventData(config.AdditionalEventData)
if err != nil {
log.Entry().Debugf("couldn't add additionalData to cloud event data: %s", err)
}
eventBytes, err := event.ToBytes()
if err != nil {
return []byte{}, errors.Wrap(err, "casting event to bytes failed")
}
log.Entry().Debugf("CloudEvent created: %s", string(eventBytes))
return eventBytes, nil
}