github.com/SAP/jenkins-library@v1.362.0/cmd/gcpPublishEvent.go (about)

     1  package cmd
     2  
     3  import (
     4  	piperConfig "github.com/SAP/jenkins-library/pkg/config"
     5  	"github.com/SAP/jenkins-library/pkg/events"
     6  	"github.com/SAP/jenkins-library/pkg/gcp"
     7  	"github.com/SAP/jenkins-library/pkg/log"
     8  	"github.com/SAP/jenkins-library/pkg/orchestrator"
     9  	"github.com/SAP/jenkins-library/pkg/telemetry"
    10  	"github.com/SAP/jenkins-library/pkg/vault"
    11  
    12  	"github.com/pkg/errors"
    13  )
    14  
    15  type gcpPublishEventUtils interface {
    16  	GetConfig() *gcpPublishEventOptions
    17  	GetOIDCTokenByValidation(roleID string) (string, error)
    18  	GetFederatedToken(projectNumber, pool, provider, token string) (string, error)
    19  	Publish(projectNumber string, topic string, token string, key string, data []byte) error
    20  }
    21  
    22  type gcpPublishEventUtilsBundle struct {
    23  	config *gcpPublishEventOptions
    24  	*vault.Client
    25  }
    26  
    27  func (g gcpPublishEventUtilsBundle) GetConfig() *gcpPublishEventOptions {
    28  	return g.config
    29  }
    30  
    31  func (g gcpPublishEventUtilsBundle) GetFederatedToken(projectNumber, pool, provider, token string) (string, error) {
    32  	return gcp.GetFederatedToken(projectNumber, pool, provider, token)
    33  }
    34  
    35  func (g gcpPublishEventUtilsBundle) Publish(projectNumber string, topic string, token string, key string, data []byte) error {
    36  	return gcp.Publish(projectNumber, topic, token, key, data)
    37  }
    38  
    39  func gcpPublishEvent(config gcpPublishEventOptions, telemetryData *telemetry.CustomData) {
    40  	vaultCreds := piperConfig.VaultCredentials{
    41  		AppRoleID:       GeneralConfig.VaultRoleID,
    42  		AppRoleSecretID: GeneralConfig.VaultRoleSecretID,
    43  		VaultToken:      GeneralConfig.VaultToken,
    44  	}
    45  	vaultConfig := map[string]interface{}{
    46  		"vaultNamespace": config.VaultNamespace,
    47  		"vaultServerUrl": config.VaultServerURL,
    48  	}
    49  
    50  	client, err := piperConfig.GetVaultClientFromConfig(vaultConfig, vaultCreds)
    51  	if err != nil {
    52  		log.Entry().WithError(err).Warnf("could not create Vault client")
    53  	}
    54  	defer client.MustRevokeToken()
    55  
    56  	vaultClient, ok := client.(vault.Client)
    57  	if !ok {
    58  		log.Entry().WithError(err).Warnf("could not create Vault client")
    59  	}
    60  
    61  	utils := gcpPublishEventUtilsBundle{
    62  		config: &config,
    63  		Client: &vaultClient,
    64  	}
    65  
    66  	err = runGcpPublishEvent(utils)
    67  	if err != nil {
    68  		// do not fail the step
    69  		log.Entry().WithError(err).Warnf("step execution failed")
    70  	}
    71  }
    72  
    73  func runGcpPublishEvent(utils gcpPublishEventUtils) error {
    74  	config := utils.GetConfig()
    75  
    76  	var data []byte
    77  	var err error
    78  
    79  	provider, err := orchestrator.GetOrchestratorConfigProvider(nil)
    80  	if err != nil {
    81  		log.Entry().WithError(err).Warning("Cannot infer config from CI environment")
    82  	}
    83  
    84  	data, err = createNewEvent(config)
    85  	if err != nil {
    86  		return errors.Wrap(err, "failed to create event data")
    87  	}
    88  
    89  	oidcToken, err := utils.GetOIDCTokenByValidation(GeneralConfig.HookConfig.OIDCConfig.RoleID)
    90  	if err != nil {
    91  		return errors.Wrap(err, "failed to get OIDC token")
    92  	}
    93  
    94  	token, err := utils.GetFederatedToken(config.GcpProjectNumber, config.GcpWorkloadIDentityPool, config.GcpWorkloadIDentityPoolProvider, oidcToken)
    95  	if err != nil {
    96  		return errors.Wrap(err, "failed to get federated token")
    97  	}
    98  
    99  	err = utils.Publish(config.GcpProjectNumber, config.Topic, token, provider.BuildURL(), data)
   100  	if err != nil {
   101  		return errors.Wrap(err, "failed to publish event")
   102  	}
   103  
   104  	log.Entry().Infof("Event published successfully! With topic: %s", config.Topic)
   105  
   106  	return nil
   107  }
   108  
   109  func createNewEvent(config *gcpPublishEventOptions) ([]byte, error) {
   110  	event, err := events.NewEvent(config.EventType, config.EventSource).CreateWithJSONData(config.EventData)
   111  	if err != nil {
   112  		return []byte{}, errors.Wrap(err, "failed to create new event")
   113  	}
   114  
   115  	err = event.AddToCloudEventData(config.AdditionalEventData)
   116  	if err != nil {
   117  		log.Entry().Debugf("couldn't add additionalData to cloud event data: %s", err)
   118  	}
   119  
   120  	eventBytes, err := event.ToBytes()
   121  	if err != nil {
   122  		return []byte{}, errors.Wrap(err, "casting event to bytes failed")
   123  	}
   124  	log.Entry().Debugf("CloudEvent created: %s", string(eventBytes))
   125  	return eventBytes, nil
   126  }