Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix error when syncing HelmChart #3873

Merged
merged 4 commits into from
Jul 25, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions core/fluxsync/adapters.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ type SourceRef interface {
Namespace() string
}

// Automation objects are Kustomizations and HelmReleases.
// These are the only object types that can be triggered
// to be reconciled with their source.
type Automation interface {
Reconcilable
SourceRef() SourceRef
Expand Down
2 changes: 2 additions & 0 deletions core/server/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ func getFluxObject(kind string) (fluxsync.Reconcilable, error) {
return &fluxsync.GitRepositoryAdapter{GitRepository: &sourcev1.GitRepository{}}, nil
case sourcev1.BucketKind:
return &fluxsync.BucketAdapter{Bucket: &sourcev1.Bucket{}}, nil
case sourcev1.HelmChartKind:
return &fluxsync.HelmChartAdapter{HelmChart: &sourcev1.HelmChart{}}, nil
case sourcev1.HelmRepositoryKind:
return &fluxsync.HelmRepositoryAdapter{HelmRepository: &sourcev1.HelmRepository{}}, nil
case sourcev1.OCIRepositoryKind:
Expand Down
147 changes: 114 additions & 33 deletions core/server/sync_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,70 +48,115 @@ func TestSync(t *testing.T) {
helmRepo := makeHelmRepo(name, *ns)
hr := makeHelmRelease(name, *ns, helmRepo, chart)

g.Expect(k.Create(ctx, gitRepo)).Should(Succeed())
bucket := makeBucket(name, *ns)
ociRepo := makeOCIRepo(name, *ns)

g.Expect(k.Create(ctx, kust)).Should(Succeed())
g.Expect(k.Create(ctx, hr)).Should(Succeed())

g.Expect(k.Create(ctx, bucket)).Should(Succeed())
g.Expect(k.Create(ctx, chart)).Should(Succeed())
g.Expect(k.Create(ctx, helmRepo)).Should(Succeed())
g.Expect(k.Create(ctx, hr)).Should(Succeed())
g.Expect(k.Create(ctx, gitRepo)).Should(Succeed())
g.Expect(k.Create(ctx, ociRepo)).Should(Succeed())

tests := []struct {
name string
msg *pb.SyncFluxObjectRequest
automation fluxsync.Automation
source fluxsync.Reconcilable
name string
msg *pb.SyncFluxObjectRequest
reconcilable fluxsync.Reconcilable
source fluxsync.Reconcilable
}{{
name: "helm release no source",
msg: &pb.SyncFluxObjectRequest{
Objects: []*pb.ObjectRef{{ClusterName: "Default",
Kind: helmv2.HelmReleaseKind}},
WithSource: false,
},
reconcilable: fluxsync.HelmReleaseAdapter{HelmRelease: hr},
}, {
name: "helm release with source",
msg: &pb.SyncFluxObjectRequest{
Objects: []*pb.ObjectRef{{ClusterName: "Default",
Kind: helmv2.HelmReleaseKind}},
WithSource: true,
},
reconcilable: fluxsync.HelmReleaseAdapter{HelmRelease: hr},
source: fluxsync.NewReconcileable(helmRepo),
}, {
name: "kustomization no source",
msg: &pb.SyncFluxObjectRequest{
Objects: []*pb.ObjectRef{{ClusterName: "Default",
Kind: kustomizev1.KustomizationKind}},
WithSource: false,
},
automation: fluxsync.KustomizationAdapter{Kustomization: kust},
reconcilable: fluxsync.KustomizationAdapter{Kustomization: kust},
}, {
name: "kustomization with source",
msg: &pb.SyncFluxObjectRequest{
Objects: []*pb.ObjectRef{{ClusterName: "Default",
Kind: kustomizev1.KustomizationKind}},
WithSource: true,
},
automation: fluxsync.KustomizationAdapter{Kustomization: kust},
source: fluxsync.NewReconcileable(gitRepo),
reconcilable: fluxsync.KustomizationAdapter{Kustomization: kust},
source: fluxsync.NewReconcileable(gitRepo),
}, {
name: "helm release no source",
name: "gitrepository",
msg: &pb.SyncFluxObjectRequest{
Objects: []*pb.ObjectRef{{ClusterName: "Default",
Kind: helmv2.HelmReleaseKind}},
Kind: sourcev1.GitRepositoryKind}},
WithSource: false,
},
automation: fluxsync.HelmReleaseAdapter{HelmRelease: hr},
reconcilable: fluxsync.GitRepositoryAdapter{GitRepository: gitRepo},
}, {
name: "helm release with source",
name: "bucket",
msg: &pb.SyncFluxObjectRequest{
Objects: []*pb.ObjectRef{{ClusterName: "Default",
Kind: sourcev1.BucketKind}},
WithSource: false,
},
reconcilable: fluxsync.BucketAdapter{Bucket: bucket},
}, {
name: "helmchart",
msg: &pb.SyncFluxObjectRequest{
Objects: []*pb.ObjectRef{{ClusterName: "Default",
Kind: sourcev1.HelmChartKind}},
WithSource: false,
},
reconcilable: fluxsync.HelmChartAdapter{HelmChart: chart},
}, {
name: "helmrepository",
msg: &pb.SyncFluxObjectRequest{
Objects: []*pb.ObjectRef{{ClusterName: "Default",
Kind: sourcev1.HelmRepositoryKind}},
WithSource: false,
},
reconcilable: fluxsync.HelmRepositoryAdapter{HelmRepository: helmRepo},
}, {
name: "ocirepository",
msg: &pb.SyncFluxObjectRequest{
Objects: []*pb.ObjectRef{{ClusterName: "Default",
Kind: sourcev1.OCIRepositoryKind}},
WithSource: false,
},
reconcilable: fluxsync.OCIRepositoryAdapter{OCIRepository: ociRepo},
}, {
name: "multiple objects",
msg: &pb.SyncFluxObjectRequest{
Objects: []*pb.ObjectRef{{ClusterName: "Default",
Kind: helmv2.HelmReleaseKind}, {ClusterName: "Default",
Kind: helmv2.HelmReleaseKind}},
WithSource: true,
},
automation: fluxsync.HelmReleaseAdapter{HelmRelease: hr},
source: fluxsync.NewReconcileable(helmRepo),
},
{
name: "multiple objects",
msg: &pb.SyncFluxObjectRequest{
Objects: []*pb.ObjectRef{{ClusterName: "Default",
Kind: helmv2.HelmReleaseKind}, {ClusterName: "Default",
Kind: helmv2.HelmReleaseKind}},
WithSource: true,
},
automation: fluxsync.HelmReleaseAdapter{HelmRelease: hr},
source: fluxsync.NewReconcileable(helmRepo),
}}
reconcilable: fluxsync.HelmReleaseAdapter{HelmRelease: hr},
source: fluxsync.NewReconcileable(helmRepo),
}}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
msg := tt.msg
for _, msg := range msg.Objects {
msg.Name = tt.automation.GetName()
msg.Namespace = tt.automation.GetNamespace()
msg.Name = tt.reconcilable.GetName()
msg.Namespace = tt.reconcilable.GetNamespace()
}

done := make(chan error)
Expand Down Expand Up @@ -144,7 +189,7 @@ func TestSync(t *testing.T) {
}

an := types.NamespacedName{Name: name, Namespace: ns.Name}
if err := simulateReconcile(ctx, k, an, tt.automation.AsClientObject()); err != nil {
if err := simulateReconcile(ctx, k, an, tt.reconcilable.AsClientObject()); err != nil {
t.Fatal(err)
}

Expand All @@ -161,14 +206,15 @@ func TestSync(t *testing.T) {

func simulateReconcile(ctx context.Context, k client.Client, name types.NamespacedName, o client.Object) error {
switch obj := o.(type) {
case *sourcev1.GitRepository:
case *helmv2.HelmRelease:
if err := k.Get(ctx, name, obj); err != nil {
return err
}

obj.Status.SetLastHandledReconcileRequest(time.Now().Format(time.RFC3339Nano))

return k.Status().Update(ctx, obj)

case *kustomizev1.Kustomization:
if err := k.Get(ctx, name, obj); err != nil {
return err
Expand All @@ -178,7 +224,7 @@ func simulateReconcile(ctx context.Context, k client.Client, name types.Namespac

return k.Status().Update(ctx, obj)

case *sourcev1.HelmRepository:
case *sourcev1.Bucket:
if err := k.Get(ctx, name, obj); err != nil {
return err
}
Expand All @@ -187,7 +233,7 @@ func simulateReconcile(ctx context.Context, k client.Client, name types.Namespac

return k.Status().Update(ctx, obj)

case *helmv2.HelmRelease:
case *sourcev1.GitRepository:
if err := k.Get(ctx, name, obj); err != nil {
return err
}
Expand All @@ -203,6 +249,24 @@ func simulateReconcile(ctx context.Context, k client.Client, name types.Namespac

obj.Status.SetLastHandledReconcileRequest(time.Now().Format(time.RFC3339Nano))

return k.Status().Update(ctx, obj)

case *sourcev1.HelmRepository:
if err := k.Get(ctx, name, obj); err != nil {
return err
}

obj.Status.SetLastHandledReconcileRequest(time.Now().Format(time.RFC3339Nano))

return k.Status().Update(ctx, obj)

case *sourcev1.OCIRepository:
if err := k.Get(ctx, name, obj); err != nil {
return err
}

obj.Status.SetLastHandledReconcileRequest(time.Now().Format(time.RFC3339Nano))

return k.Status().Update(ctx, obj)
}

Expand Down Expand Up @@ -331,3 +395,20 @@ func makeHelmRelease(name string, ns corev1.Namespace, repo *sourcev1.HelmReposi
},
}
}

func makeOCIRepo(name string, ns corev1.Namespace) *sourcev1.OCIRepository {
return &sourcev1.OCIRepository{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: ns.Name,
},
Spec: sourcev1.OCIRepositorySpec{
URL: "oci://ghcr.io/some/chart",
},
Status: sourcev1.OCIRepositoryStatus{
ReconcileRequestStatus: meta.ReconcileRequestStatus{
LastHandledReconcileAt: time.Now().Format(time.RFC3339Nano),
},
},
}
}
Loading