Implement DockerHub webhook receiver

Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
This commit is contained in:
Stefan Prodan 2021-01-14 16:57:31 +02:00
parent fbf4f217f1
commit 4e63d79514
No known key found for this signature in database
GPG Key ID: 3299AEB0E4085BAF
5 changed files with 47 additions and 8 deletions

View File

@ -27,7 +27,7 @@ import (
type ReceiverSpec struct {
// Type of webhook sender, used to determine
// the validation procedure and payload deserialization.
// +kubebuilder:validation:Enum=generic;github;gitlab;bitbucket;harbor
// +kubebuilder:validation:Enum=generic;github;gitlab;bitbucket;harbor;dockerhub
// +required
Type string `json:"type"`
@ -68,6 +68,7 @@ const (
GitLabReceiver string = "gitlab"
BitbucketReceiver string = "bitbucket"
HarborReceiver string = "harbor"
DockerHubReceiver string = "dockerhub"
)
func ReceiverReady(receiver Receiver, reason, message, url string) Receiver {

View File

@ -108,6 +108,7 @@ spec:
- gitlab
- bitbucket
- harbor
- dockerhub
type: string
required:
- resources

View File

@ -48,7 +48,7 @@ with an exponential backoff of maximum 30 seconds.
The notification controller handles webhook requests on a dedicated port.
This port can be used to create a Kubernetes LoadBalancer Service or
Ingress to expose the receiver endpoint outside the cluster
to be accessed by GitHub, GitLab, Bitbucket, Harbor, Jenkins, etc.
to be accessed by GitHub, GitLab, Bitbucket, Harbor, DockerHub, Jenkins, etc.
Receiver API:

View File

@ -9,7 +9,7 @@ reconciliation for a group of resources.
type ReceiverSpec struct {
// Type of webhook sender, used to determine
// the validation procedure and payload deserialization.
// +kubebuilder:validation:Enum=generic;github;gitlab;harbor
// +kubebuilder:validation:Enum=generic;github;gitlab;harbor;dockerhub
// +required
Type string `json:"type"`
@ -43,6 +43,7 @@ const (
GitLabReceiver string = "gitlab"
BitbucketReceiver string = "bitbucket"
HarborReceiver string = "harbor"
DockerHubReceiver string = "dockerhub"
)
```
@ -69,7 +70,7 @@ kubectl create secret generic webhook-token \
--from-literal=token=$TOKEN
```
GitHub receiver:
### GitHub receiver
```yaml
apiVersion: notification.toolkit.fluxcd.io/v1beta1
@ -94,7 +95,7 @@ spec:
Note that you have to set the generated token as the GitHub webhook secret value.
The controller uses the `X-Hub-Signature` HTTP header to verify that the request is legitimate.
GitLab receiver:
### GitLab receiver
```yaml
apiVersion: notification.toolkit.fluxcd.io/v1beta1
@ -119,7 +120,7 @@ spec:
Note that you have to configure the GitLab webhook with the generated token.
The controller uses the `X-Gitlab-Token` HTTP header to verify that the request is legitimate.
Bitbucket server receiver:
### Bitbucket server receiver
```yaml
apiVersion: notification.toolkit.fluxcd.io/v1beta1
@ -141,7 +142,7 @@ spec:
Note that you have to set the generated token as the Bitbucket server webhook secret value.
The controller uses the `X-Hub-Signature` HTTP header to verify that the request is legitimate.
Harbor receiver:
### Harbor receiver
```yaml
apiVersion: notification.toolkit.fluxcd.io/v1beta1
@ -163,7 +164,24 @@ spec:
Note that you have to set the generated token as the Harbor webhook authentication header.
The controller uses the `Authentication` HTTP header to verify that the request is legitimate.
Generic receiver:
### DockerHub receiver
```yaml
apiVersion: notification.toolkit.fluxcd.io/v1beta1
kind: Receiver
metadata:
name: dockerhub-receiver
namespace: default
spec:
type: dockerhub
secretRef:
name: webhook-token
resources:
- kind: ImageRepository
name: webapp
```
### Generic receiver
```yaml
apiVersion: notification.toolkit.fluxcd.io/v1beta1

View File

@ -18,6 +18,7 @@ package server
import (
"context"
"encoding/json"
"fmt"
"net/http"
"net/url"
@ -181,6 +182,24 @@ func (s *ReceiverServer) validate(ctx context.Context, receiver v1beta1.Receiver
s.logger.Info("handling Harbor event", "receiver", receiver.Name)
return nil
case v1beta1.DockerHubReceiver:
type payload struct {
PushData struct {
Tag string `json:"tag"`
} `json:"push_data"`
Repository struct {
URL string `json:"repo_url"`
} `json:"repository"`
}
var p payload
if err := json.NewDecoder(r.Body).Decode(&p); err != nil {
return fmt.Errorf("cannot decode DockerHub webhook payload")
}
s.logger.Info(
fmt.Sprintf("handling event from %s for tag %s", p.Repository.URL, p.PushData.Tag),
"receiver", receiver.Name)
return nil
}
return fmt.Errorf("recevier type '%s' not supported", receiver.Spec.Type)