Skip to content

Commit 1eae956

Browse files
committed
helmchart: add ExternalArtifact as a valid source kind
ExternalArtifact (source.toolkit.fluxcd.io/v1) was introduced in v1.7.0 but was never wired into the HelmChart controller. This commit adds the necessary plumbing so that a HelmChart can reference an ExternalArtifact as its source, enabling advanced source-composition patterns via the source-watcher controller. Changes: - Extend LocalHelmChartSourceReference.Kind enum to include ExternalArtifact - Register a Watch for ExternalArtifact in SetupWithManager - Add ExternalArtifactKind case to getSource() - Add *sourcev1.ExternalArtifact case to reconcileSource() - Add requestsForExternalArtifactChange() reconcile-trigger helper ExternalArtifact exposes a tarball artifact identical in structure to Bucket and GitRepository, so it reuses the existing buildFromTarballArtifact path with no new builder code required. Signed-off-by: Rajit Shah <rajit219@gmail.com>
1 parent 3f4f40a commit 1eae956

File tree

2 files changed

+46
-3
lines changed

2 files changed

+46
-3
lines changed

api/v1/helmchart_types.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,8 @@ type LocalHelmChartSourceReference struct {
105105
APIVersion string `json:"apiVersion,omitempty"`
106106

107107
// Kind of the referent, valid values are ('HelmRepository', 'GitRepository',
108-
// 'Bucket').
109-
// +kubebuilder:validation:Enum=HelmRepository;GitRepository;Bucket
108+
// 'Bucket', 'ExternalArtifact').
109+
// +kubebuilder:validation:Enum=HelmRepository;GitRepository;Bucket;ExternalArtifact
110110
// +required
111111
Kind string `json:"kind"`
112112

internal/controller/helmchart_controller.go

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,11 @@ func (r *HelmChartReconciler) SetupWithManager(ctx context.Context, mgr ctrl.Man
201201
handler.EnqueueRequestsFromMapFunc(r.requestsForBucketChange),
202202
builder.WithPredicates(SourceRevisionChangePredicate{}),
203203
).
204+
Watches(
205+
&sourcev1.ExternalArtifact{},
206+
handler.EnqueueRequestsFromMapFunc(r.requestsForExternalArtifactChange),
207+
builder.WithPredicates(SourceRevisionChangePredicate{}),
208+
).
204209
WithOptions(controller.Options{
205210
RateLimiter: opts.RateLimiter,
206211
}).
@@ -508,6 +513,8 @@ func (r *HelmChartReconciler) reconcileSource(ctx context.Context, sp *patch.Ser
508513
return r.buildFromHelmRepository(ctx, obj, typedSource, build)
509514
case *sourcev1.GitRepository, *sourcev1.Bucket:
510515
return r.buildFromTarballArtifact(ctx, obj, *typedSource.GetArtifact(), build)
516+
case *sourcev1.ExternalArtifact:
517+
return r.buildFromTarballArtifact(ctx, obj, *typedSource.GetArtifact(), build)
511518
default:
512519
// Ending up here should generally not be possible
513520
// as getSource already validates
@@ -931,9 +938,15 @@ func (r *HelmChartReconciler) getSource(ctx context.Context, obj *sourcev1.HelmC
931938
return nil, err
932939
}
933940
s = &bucket
941+
case sourcev1.ExternalArtifactKind:
942+
var ea sourcev1.ExternalArtifact
943+
if err := r.Client.Get(ctx, namespacedName, &ea); err != nil {
944+
return nil, err
945+
}
946+
s = &ea
934947
default:
935948
return nil, fmt.Errorf("unsupported source kind '%s', must be one of: %v", obj.Spec.SourceRef.Kind, []string{
936-
sourcev1.HelmRepositoryKind, sourcev1.GitRepositoryKind, sourcev1.BucketKind})
949+
sourcev1.HelmRepositoryKind, sourcev1.GitRepositoryKind, sourcev1.BucketKind, sourcev1.ExternalArtifactKind})
937950
}
938951
return s, nil
939952
}
@@ -1202,6 +1215,36 @@ func (r *HelmChartReconciler) requestsForBucketChange(ctx context.Context, o cli
12021215
return reqs
12031216
}
12041217

1218+
func (r *HelmChartReconciler) requestsForExternalArtifactChange(ctx context.Context, o client.Object) []reconcile.Request {
1219+
ea, ok := o.(*sourcev1.ExternalArtifact)
1220+
if !ok {
1221+
ctrl.LoggerFrom(ctx).Error(fmt.Errorf("expected an ExternalArtifact, got %T", o),
1222+
"failed to get reconcile requests for ExternalArtifact change")
1223+
return nil
1224+
}
1225+
1226+
// If we do not have an artifact, we have no requests to make
1227+
if ea.GetArtifact() == nil {
1228+
return nil
1229+
}
1230+
1231+
var list sourcev1.HelmChartList
1232+
if err := r.List(ctx, &list, client.MatchingFields{
1233+
indexKeyHelmChartSource: fmt.Sprintf("%s/%s", sourcev1.ExternalArtifactKind, ea.Name),
1234+
}); err != nil {
1235+
ctrl.LoggerFrom(ctx).Error(err, "failed to list HelmCharts for ExternalArtifact change")
1236+
return nil
1237+
}
1238+
1239+
var reqs []reconcile.Request
1240+
for i, v := range list.Items {
1241+
if !ea.GetArtifact().HasRevision(v.Status.ObservedSourceArtifactRevision) {
1242+
reqs = append(reqs, reconcile.Request{NamespacedName: client.ObjectKeyFromObject(&list.Items[i])})
1243+
}
1244+
}
1245+
return reqs
1246+
}
1247+
12051248
// eventLogf records events, and logs at the same time.
12061249
//
12071250
// This log is different from the debug log in the EventRecorder, in the sense

0 commit comments

Comments
 (0)