Trigger ImageRepository reconciliation with webhook receivers

- Add ImageRepository to the Receiver API known kinds and RBAC
- Trigger container image updates to Git by annotating ImageRepository objects

Signed-off-by: Stefan Prodan <stefan.prodan@gmail.com>
This commit is contained in:
Stefan Prodan 2021-01-14 12:55:00 +02:00
parent d5cabbde8f
commit c148d6a036
No known key found for this signature in database
GPG Key ID: 3299AEB0E4085BAF
10 changed files with 67 additions and 7 deletions

View File

@ -24,7 +24,7 @@ type CrossNamespaceObjectReference struct {
APIVersion string `json:"apiVersion,omitempty"`
// Kind of the referent
// +kubebuilder:validation:Enum=Bucket;GitRepository;Kustomization;HelmRelease;HelmChart;HelmRepository
// +kubebuilder:validation:Enum=Bucket;GitRepository;Kustomization;HelmRelease;HelmChart;HelmRepository;ImageRepository
// +required
Kind string `json:"kind,omitempty"`

View File

@ -73,6 +73,7 @@ spec:
- HelmRelease
- HelmChart
- HelmRepository
- ImageRepository
type: string
name:
description: Name of the referent

View File

@ -70,6 +70,7 @@ spec:
- HelmRelease
- HelmChart
- HelmRepository
- ImageRepository
type: string
name:
description: Name of the referent

View File

@ -14,6 +14,22 @@ rules:
- get
- list
- watch
- apiGroups:
- image.fluxcd.io
resources:
- imagerepositories
verbs:
- get
- list
- patch
- update
- watch
- apiGroups:
- image.fluxcd.io
resources:
- imagerepositories/status
verbs:
- get
- apiGroups:
- notification.toolkit.fluxcd.io
resources:
@ -74,6 +90,22 @@ rules:
- get
- patch
- update
- apiGroups:
- source.fluxcd.io
resources:
- buckets
verbs:
- get
- list
- patch
- update
- watch
- apiGroups:
- source.fluxcd.io
resources:
- buckets/status
verbs:
- get
- apiGroups:
- source.fluxcd.io
resources:

View File

@ -44,10 +44,14 @@ type ReceiverReconciler struct {
// +kubebuilder:rbac:groups=notification.toolkit.fluxcd.io,resources=receivers,verbs=get;list;watch;create;update;patch;delete
// +kubebuilder:rbac:groups=notification.toolkit.fluxcd.io,resources=receivers/status,verbs=get;update;patch
// +kubebuilder:rbac:groups=source.fluxcd.io,resources=buckets,verbs=get;list;watch;update;patch
// +kubebuilder:rbac:groups=source.fluxcd.io,resources=buckets/status,verbs=get
// +kubebuilder:rbac:groups=source.fluxcd.io,resources=gitrepositories,verbs=get;list;watch;update;patch
// +kubebuilder:rbac:groups=source.fluxcd.io,resources=gitrepositories/status,verbs=get
// +kubebuilder:rbac:groups=source.fluxcd.io,resources=helmrepositories,verbs=get;list;watch;update;patch
// +kubebuilder:rbac:groups=source.fluxcd.io,resources=helmrepositories/status,verbs=get
// +kubebuilder:rbac:groups=image.fluxcd.io,resources=imagerepositories,verbs=get;list;watch;update;patch
// +kubebuilder:rbac:groups=image.fluxcd.io,resources=imagerepositories/status,verbs=get
// +kubebuilder:rbac:groups="",resources=secrets,verbs=get;list;watch
func (r *ReceiverReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {

View File

@ -156,6 +156,8 @@ spec:
resources:
- kind: HelmRepository
name: webapp
- kind: ImageRepository
name: webapp
```
Note that you have to set the generated token as the Harbor webhook authentication header.
@ -174,6 +176,8 @@ spec:
secretRef:
name: webhook-token
resources:
- kind: ImageRepository
name: webapp
- kind: GitRepository
name: webapp
- kind: HelmRepository

1
go.mod
View File

@ -5,6 +5,7 @@ go 1.15
replace github.com/fluxcd/notification-controller/api => ./api
require (
github.com/fluxcd/image-reflector-controller/api v0.2.0
github.com/fluxcd/notification-controller/api v0.6.0
github.com/fluxcd/pkg/apis/meta v0.5.0
github.com/fluxcd/pkg/recorder v0.0.6

2
go.sum
View File

@ -91,6 +91,8 @@ github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLi
github.com/evanphx/json-patch v4.9.0+incompatible h1:kLcOMZeuLAJvL2BPWLMIj5oaZQobrkAqrL+WFZwQses=
github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fluxcd/image-reflector-controller/api v0.2.0 h1:/qAamO2y1Bq4rn/JedB33V9kOkSeXIYxwpnEHBz0HeE=
github.com/fluxcd/image-reflector-controller/api v0.2.0/go.mod h1:2KC4Zijp+iIbkID/KT+hhH4iSSQP3Hrzh0t971tjWjk=
github.com/fluxcd/pkg/apis/meta v0.5.0 h1:FaU++mQY0g4sVVl+hG+vk0CXBLbb4EVfRuzs3IjLXvo=
github.com/fluxcd/pkg/apis/meta v0.5.0/go.mod h1:aEUuZIawboAAFLlYz/juVJ7KNmlWbBtJFYkOWWmGUR4=
github.com/fluxcd/pkg/recorder v0.0.6 h1:me/n8syeeGXz50OXoPX3jgIj9AtinvhHdKT9Dy+MbHs=

View File

@ -23,6 +23,7 @@ import (
"net/url"
"strings"
imagev1 "github.com/fluxcd/image-reflector-controller/api/v1alpha1"
"github.com/fluxcd/pkg/apis/meta"
sourcev1 "github.com/fluxcd/source-controller/api/v1beta1"
"github.com/google/go-github/v32/github"
@ -221,38 +222,50 @@ func (s *ReceiverServer) annotate(ctx context.Context, resource v1beta1.CrossNam
case sourcev1.BucketKind:
var source sourcev1.Bucket
if err := s.kubeClient.Get(ctx, resourceName, &source); err != nil {
return fmt.Errorf("unable to read Bucket '%s' error: %w", resourceName, err)
return fmt.Errorf("unable to read %s '%s' error: %w", resource.Kind, resourceName, err)
}
if source.Annotations == nil {
source.Annotations = make(map[string]string)
}
source.Annotations[meta.ReconcileRequestAnnotation] = metav1.Now().String()
if err := s.kubeClient.Update(ctx, &source); err != nil {
return fmt.Errorf("unable to annotate Bucket '%s' error: %w", resourceName, err)
return fmt.Errorf("unable to annotate %s '%s' error: %w", resource.Kind, resourceName, err)
}
case sourcev1.GitRepositoryKind:
var source sourcev1.GitRepository
if err := s.kubeClient.Get(ctx, resourceName, &source); err != nil {
return fmt.Errorf("unable to read GitRepository '%s' error: %w", resourceName, err)
return fmt.Errorf("unable to read %s '%s' error: %w", resource.Kind, resourceName, err)
}
if source.Annotations == nil {
source.Annotations = make(map[string]string)
}
source.Annotations[meta.ReconcileRequestAnnotation] = metav1.Now().String()
if err := s.kubeClient.Update(ctx, &source); err != nil {
return fmt.Errorf("unable to annotate GitRepository '%s' error: %w", resourceName, err)
return fmt.Errorf("unable to annotate %s '%s' error: %w", resource.Kind, resourceName, err)
}
case sourcev1.HelmRepositoryKind:
var source sourcev1.HelmRepository
if err := s.kubeClient.Get(ctx, resourceName, &source); err != nil {
return fmt.Errorf("unable to read HelmRepository '%s' error: %w", resourceName, err)
return fmt.Errorf("unable to read %s '%s' error: %w", resource.Kind, resourceName, err)
}
if source.Annotations == nil {
source.Annotations = make(map[string]string)
}
source.Annotations[meta.ReconcileRequestAnnotation] = metav1.Now().String()
if err := s.kubeClient.Update(ctx, &source); err != nil {
return fmt.Errorf("unable to annotate HelmRepository '%s' error: %w", resourceName, err)
return fmt.Errorf("unable to annotate %s '%s' error: %w", resource.Kind, resourceName, err)
}
case imagev1.ImageRepositoryKind:
var source imagev1.ImageRepository
if err := s.kubeClient.Get(ctx, resourceName, &source); err != nil {
return fmt.Errorf("unable to read %s '%s' error: %w", resource.Kind, resourceName, err)
}
if source.Annotations == nil {
source.Annotations = make(map[string]string)
}
source.Annotations[meta.ReconcileRequestAnnotation] = metav1.Now().String()
if err := s.kubeClient.Update(ctx, &source); err != nil {
return fmt.Errorf("unable to annotate %s '%s' error: %w", resource.Kind, resourceName, err)
}
default:
return fmt.Errorf("kind '%s not suppored", resource.Kind)

View File

@ -27,6 +27,7 @@ import (
ctrl "sigs.k8s.io/controller-runtime"
crtlmetrics "sigs.k8s.io/controller-runtime/pkg/metrics"
imagev1 "github.com/fluxcd/image-reflector-controller/api/v1alpha1"
"github.com/fluxcd/pkg/runtime/logger"
"github.com/fluxcd/pkg/runtime/metrics"
"github.com/fluxcd/pkg/runtime/probes"
@ -48,6 +49,7 @@ func init() {
_ = v1beta1.AddToScheme(scheme)
_ = sourcev1.AddToScheme(scheme)
_ = imagev1.AddToScheme(scheme)
// +kubebuilder:scaffold:scheme
}