fluxcd / notification-controller

The GitOps Toolkit event forwarder and notification dispatcher
https://fluxcd.io
Apache License 2.0
150 stars 132 forks source link

Add new notifier to send CloudEvent / CDEvent #395

Open bradmccoydev opened 2 years ago

bradmccoydev commented 2 years ago

This is a feature request to add the ability to send a CloudEvent / CDEvent from a flux notification to enable better interoperability between tools such as Keptn or Tekton for example.

This issue relates to #195 we can either update the forwarder notifier or create a new notifier for events.

The easiest and most likely accepted way of doing this is as follows:

  1. Extend the Provider secret to contain a Body Template for the HTTP request. As we are already getting the secret.Data it is easy to reference the "body" and pull it the same way we get the headers and address.

  2. Now that we have the Body template we need the key-value pairs of the metadata we require to substitute the template. This can be passed through the Provider.Metadata.Labels, as we are already pulling the provider object and Labels, is a mandatory field that can be used for the key values.

  3. Use basic go text/template to switch out these values in the body from the secret.

Please find below an example

1.

apiVersion: v1
kind: Secret
metadata:
  name: keptn-flux-integration
  namespace: flux-system
stringData:
  address: http://keptn-flux-integration.flux-system.svc.cluster.local:80
  headers: |
     Content-Type: application/json
     x-token: 
  body: |
    {
      "data": {
        "configurationChange": {},
        "labels": {
          "servicename": "{{.keptnService}}"
        },
        "project": "{{.keptnProject}}",
        "service": "{{.keptnService}}",
        "stage": "{{.keptnStage}}"
      },
      "source": "flux",
      "specversion": "1.0",
      "type": "{{.keptnType}}",
      "shkeptnspecversion": "0.2.3"
    }

2.

apiVersion: notification.toolkit.fluxcd.io/v1beta1
kind: Provider
metadata:
  name: keptn-flux-integration
  namespace: flux-system
  labels:
    keptnProject: gsoc
    keptnService: podtato-head
    keptnStage: qa
    keptnType: sh.keptn.event.qa.delivery.triggered
spec:
  type: generic
  address: http://keptn-flux-integration.flux-system.svc.cluster.local:80
  secretRef:
    name: keptn-flux-integration`

3.

var template string
    for k, v := range secret.Data {
        switch k {
        case "body":
            template = string(v)
        case "headers":
            headers := make(map[interface{}]interface{})
            err := yaml.Unmarshal(v, &headers)

            if err != nil {
                log.Errorf("Error parsing headers: %s", err)
            }

            keptnEvent.Headers = headers
        }
    }

    tmpl, err := texttemplate.New("labels").Parse(template)

I'm happy to do a PR to demonstrate this if it will be accepted. Thanks

bradmccoydev commented 2 years ago

Notes from Flux community meeting 11-Aug. We will investigate alternative ways of doing this and look into transforming a Kubernetes event into a Cloudevent and how we add our custom metadata. @bradmccoydev to investigate further, and see if anyone else is doing this.

makkes commented 1 year ago

Hey @bradmccoydev, did you get to take a look at this? I'd be happy to pair up on this effort. Find me on Slack as @max.

bradmccoydev commented 1 year ago

Hey @makkes sorry I haven't yet, it got stale, but still very interested. That sounds great I will reach out, is that CNCF slack right?

makkes commented 1 year ago

is that CNCF slack right?

yes, it is.