Skip to content

Commit b629c74

Browse files
committed
WIP: Refactor HelmChartReconciler
Signed-off-by: Hidde Beydals <hello@hidde.co>
1 parent 77f314c commit b629c74

17 files changed

+1016
-2054
lines changed

api/v1beta1/condition_types.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ const (
2424
SourceVerifiedCondition string = "SourceVerified"
2525

2626
ArtifactAvailableCondition string = "ArtifactAvailable"
27+
28+
SourceRefReadyCondition string = "SourceRefReady"
2729
)
2830

2931
const (

api/v1beta1/helmchart_types.go

Lines changed: 15 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,19 @@ package v1beta1
1818

1919
import (
2020
"github.com/fluxcd/pkg/apis/meta"
21-
apimeta "k8s.io/apimachinery/pkg/api/meta"
2221
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2322
)
2423

2524
// HelmChartKind is the string representation of a HelmChart.
2625
const HelmChartKind = "HelmChart"
2726

27+
const (
28+
DependenciesBuildCondition string = "DependenciesBuild"
29+
ValuesFilesMergedCondition string = "ValuesFilesMerged"
30+
ChartPackagedCondition string = "ChartPackaged"
31+
ChartReconciled string = "ChartReconciled"
32+
)
33+
2834
// HelmChartSpec defines the desired state of a Helm chart.
2935
type HelmChartSpec struct {
3036
// The name or path the Helm chart is available at in the SourceRef.
@@ -122,52 +128,20 @@ const (
122128
ChartPackageSucceededReason string = "ChartPackageSucceeded"
123129
)
124130

125-
// HelmChartProgressing resets the conditions of the HelmChart to meta.Condition
126-
// of type meta.ReadyCondition with status 'Unknown' and meta.ProgressingReason
127-
// reason and message. It returns the modified HelmChart.
128-
func HelmChartProgressing(chart HelmChart) HelmChart {
129-
chart.Status.ObservedGeneration = chart.Generation
130-
chart.Status.URL = ""
131-
chart.Status.Conditions = []metav1.Condition{}
132-
meta.SetResourceCondition(&chart, meta.ReadyCondition, metav1.ConditionUnknown, meta.ProgressingReason, "reconciliation in progress")
133-
return chart
134-
}
135-
136-
// HelmChartReady sets the given Artifact and URL on the HelmChart and sets the
137-
// meta.ReadyCondition to 'True', with the given reason and message. It returns
138-
// the modified HelmChart.
139-
func HelmChartReady(chart HelmChart, artifact Artifact, url, reason, message string) HelmChart {
140-
chart.Status.Artifact = &artifact
141-
chart.Status.URL = url
142-
meta.SetResourceCondition(&chart, meta.ReadyCondition, metav1.ConditionTrue, reason, message)
143-
return chart
144-
}
145-
146-
// HelmChartNotReady sets the meta.ReadyCondition on the given HelmChart to
147-
// 'False', with the given reason and message. It returns the modified
148-
// HelmChart.
149-
func HelmChartNotReady(chart HelmChart, reason, message string) HelmChart {
150-
meta.SetResourceCondition(&chart, meta.ReadyCondition, metav1.ConditionFalse, reason, message)
151-
return chart
152-
}
153-
154-
// HelmChartReadyMessage returns the message of the meta.ReadyCondition with
155-
// status 'True', or an empty string.
156-
func HelmChartReadyMessage(chart HelmChart) string {
157-
if c := apimeta.FindStatusCondition(chart.Status.Conditions, meta.ReadyCondition); c != nil {
158-
if c.Status == metav1.ConditionTrue {
159-
return c.Message
160-
}
161-
}
162-
return ""
163-
}
164-
165131
// GetArtifact returns the latest artifact from the source if present in the
166132
// status sub-resource.
167133
func (in *HelmChart) GetArtifact() *Artifact {
168134
return in.Status.Artifact
169135
}
170136

137+
func (in HelmChart) GetConditions() []metav1.Condition {
138+
return in.Status.Conditions
139+
}
140+
141+
func (in *HelmChart) SetConditions(conditions []metav1.Condition) {
142+
in.Status.Conditions = conditions
143+
}
144+
171145
// GetStatusConditions returns a pointer to the Status.Conditions slice
172146
func (in *HelmChart) GetStatusConditions() *[]metav1.Condition {
173147
return &in.Status.Conditions

api/v1beta1/source.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package v1beta1
1818

1919
import (
2020
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
21+
"k8s.io/apimachinery/pkg/runtime"
2122
)
2223

2324
const (
@@ -29,9 +30,15 @@ const (
2930
// Source interface must be supported by all API types.
3031
// +k8s:deepcopy-gen=false
3132
type Source interface {
33+
metav1.Object
34+
runtime.Object
35+
3236
// GetArtifact returns the latest artifact from the source if present in the
3337
// status sub-resource.
3438
GetArtifact() *Artifact
39+
// GetConditions returns the conditions of the source if present in the
40+
// status sub-resource.
41+
GetConditions() []metav1.Condition
3542
// GetInterval returns the interval at which the source is updated.
3643
GetInterval() metav1.Duration
3744
}

api/v1beta1/zz_generated.deepcopy.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

controllers/bucket_controller.go

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -147,10 +147,16 @@ func (r *BucketReconciler) Reconcile(ctx context.Context, req ctrl.Request) (res
147147
// We have now observed this generation
148148
patchOpts = append(patchOpts, patch.WithStatusObservedGeneration{})
149149

150-
if readyCondition := conditions.Get(obj, meta.ReadyCondition); readyCondition.Status == metav1.ConditionFalse {
151-
// As we are no longer reconciling, and the end-state
150+
readyCondition := conditions.Get(obj, meta.ReadyCondition)
151+
switch readyCondition.Status {
152+
case metav1.ConditionFalse:
153+
// As we are no longer reconciling and the end-state
152154
// is not ready, the reconciliation has stalled
153155
conditions.MarkTrue(obj, meta.StalledCondition, readyCondition.Reason, readyCondition.Message)
156+
case metav1.ConditionTrue:
157+
// As we are no longer reconciling and the end-state
158+
// is ready, the reconciliation is no longer stalled
159+
conditions.Delete(obj, meta.StalledCondition)
154160
}
155161
}
156162

@@ -357,7 +363,7 @@ func (r *BucketReconciler) reconcileArtifact(ctx context.Context, obj *sourcev1.
357363
// The artifact is up-to-date
358364
if obj.GetArtifact().HasRevision(artifact.Revision) {
359365
logr.FromContext(ctx).Info("Artifact is up-to-date")
360-
conditions.MarkTrue(obj, sourcev1.ArtifactAvailableCondition, "ArchivedArtifact", "Artifact revision %s", artifact.Revision)
366+
conditions.MarkTrue(obj, sourcev1.ArtifactAvailableCondition, "ArchivedArtifact", "Compressed source to artifact with revision %s", artifact.Revision)
361367
return ctrl.Result{RequeueAfter: obj.GetInterval().Duration}, nil
362368
}
363369

@@ -392,7 +398,7 @@ func (r *BucketReconciler) reconcileArtifact(ctx context.Context, obj *sourcev1.
392398

393399
// Record it on the object
394400
obj.Status.Artifact = artifact.DeepCopy()
395-
conditions.MarkTrue(obj, sourcev1.ArtifactAvailableCondition, "ArchivedArtifact", "Artifact revision %s", artifact.Revision)
401+
conditions.MarkTrue(obj, sourcev1.ArtifactAvailableCondition, "ArchivedArtifact", "Compressed source to artifact with revision %s", artifact.Revision)
396402
r.Events.Eventf(ctx, obj, map[string]string{
397403
"revision": obj.GetArtifact().Revision,
398404
}, events.EventSeverityInfo, sourcev1.GitOperationSucceedReason, conditions.Get(obj, sourcev1.ArtifactAvailableCondition).Message)

controllers/bucket_controller_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ import (
4141

4242
const (
4343
bucketInterval = 1 * time.Second
44-
bucketTimeout = 30 * time.Second
44+
bucketTimeout = 30 * time.Second
4545
)
4646

4747
func TestBucketReconciler_Reconcile(t *testing.T) {

controllers/gitrepository_controller.go

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -154,10 +154,16 @@ func (r *GitRepositoryReconciler) Reconcile(ctx context.Context, req ctrl.Reques
154154
// We have now observed this generation
155155
patchOpts = append(patchOpts, patch.WithStatusObservedGeneration{})
156156

157-
if readyCondition := conditions.Get(obj, meta.ReadyCondition); readyCondition.Status == metav1.ConditionFalse {
158-
// As we are no longer reconciling, and the end-state
157+
readyCondition := conditions.Get(obj, meta.ReadyCondition)
158+
switch readyCondition.Status {
159+
case metav1.ConditionFalse:
160+
// As we are no longer reconciling and the end-state
159161
// is not ready, the reconciliation has stalled
160162
conditions.MarkTrue(obj, meta.StalledCondition, readyCondition.Reason, readyCondition.Message)
163+
case metav1.ConditionTrue:
164+
// As we are no longer reconciling and the end-state
165+
// is ready, the reconciliation is no longer stalled
166+
conditions.Delete(obj, meta.StalledCondition)
161167
}
162168
}
163169

@@ -329,7 +335,7 @@ func (r *GitRepositoryReconciler) reconcileSource(ctx context.Context, obj *sour
329335

330336
// Create potential new artifact
331337
*artifact = r.Storage.NewArtifactFor(obj.Kind, obj, revision, fmt.Sprintf("%s.tar.gz", commit.Hash()))
332-
conditions.MarkTrue(obj, sourcev1.SourceAvailableCondition, sourcev1.GitOperationSucceedReason, "Checked out revision %s from %s", revision, obj.Spec.URL)
338+
conditions.MarkTrue(obj, sourcev1.SourceAvailableCondition, sourcev1.GitOperationSucceedReason, "Checked out revision %s", revision)
333339

334340
return ctrl.Result{RequeueAfter: obj.Spec.Interval.Duration}, nil
335341
}
@@ -391,7 +397,7 @@ func (r *GitRepositoryReconciler) reconcileArtifact(ctx context.Context, obj *so
391397
// Record it on the object
392398
obj.Status.Artifact = artifact.DeepCopy()
393399
obj.Status.IncludedArtifacts = includes
394-
conditions.MarkTrue(obj, sourcev1.ArtifactAvailableCondition, "ArchivedArtifact", "Artifact revision %s", artifact.Revision)
400+
conditions.MarkTrue(obj, sourcev1.ArtifactAvailableCondition, "ArchivedArtifact", "Compressed source to artifact with revision %s", artifact.Revision)
395401
r.Events.Eventf(ctx, obj, map[string]string{
396402
"revision": obj.GetArtifact().Revision,
397403
}, events.EventSeverityInfo, sourcev1.GitOperationSucceedReason, conditions.Get(obj, sourcev1.ArtifactAvailableCondition).Message)

controllers/gitrepository_controller_test.go

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,7 @@ func TestGitRepositoryReconciler_reconcileSource_authStrategy(t *testing.T) {
160160
protocol: "http",
161161
want: ctrl.Result{RequeueAfter: mockInterval},
162162
assertConditions: []metav1.Condition{
163-
*conditions.TrueCondition(sourcev1.SourceAvailableCondition, "SuccessfulCheckout", "Checked out revision master/<commit> from <url>"),
163+
*conditions.TrueCondition(sourcev1.SourceAvailableCondition, sourcev1.GitOperationSucceedReason, "Checked out revision master/<commit>"),
164164
},
165165
},
166166
{
@@ -184,7 +184,7 @@ func TestGitRepositoryReconciler_reconcileSource_authStrategy(t *testing.T) {
184184
},
185185
want: ctrl.Result{RequeueAfter: mockInterval},
186186
assertConditions: []metav1.Condition{
187-
*conditions.TrueCondition(sourcev1.SourceAvailableCondition, "SuccessfulCheckout", "Checked out revision master/<commit> from <url>"),
187+
*conditions.TrueCondition(sourcev1.SourceAvailableCondition, sourcev1.GitOperationSucceedReason, "Checked out revision master/<commit>"),
188188
},
189189
},
190190
{
@@ -208,7 +208,7 @@ func TestGitRepositoryReconciler_reconcileSource_authStrategy(t *testing.T) {
208208
},
209209
want: ctrl.Result{RequeueAfter: mockInterval},
210210
assertConditions: []metav1.Condition{
211-
*conditions.TrueCondition(sourcev1.SourceAvailableCondition, "SuccessfulCheckout", "Checked out revision master/<commit> from <url>"),
211+
*conditions.TrueCondition(sourcev1.SourceAvailableCondition, sourcev1.GitOperationSucceedReason, "Checked out revision master/<commit>"),
212212
},
213213
},
214214
{
@@ -281,7 +281,7 @@ func TestGitRepositoryReconciler_reconcileSource_authStrategy(t *testing.T) {
281281
},
282282
want: ctrl.Result{RequeueAfter: mockInterval},
283283
assertConditions: []metav1.Condition{
284-
*conditions.TrueCondition(sourcev1.SourceAvailableCondition, "SuccessfulCheckout", "Checked out revision master/<commit> from <url>"),
284+
*conditions.TrueCondition(sourcev1.SourceAvailableCondition, sourcev1.GitOperationSucceedReason, "Checked out revision master/<commit>"),
285285
},
286286
},
287287
{
@@ -305,7 +305,7 @@ func TestGitRepositoryReconciler_reconcileSource_authStrategy(t *testing.T) {
305305
},
306306
want: ctrl.Result{RequeueAfter: mockInterval},
307307
assertConditions: []metav1.Condition{
308-
*conditions.TrueCondition(sourcev1.SourceAvailableCondition, "SuccessfulCheckout", "Checked out revision master/<commit> from <url>"),
308+
*conditions.TrueCondition(sourcev1.SourceAvailableCondition, sourcev1.GitOperationSucceedReason, "Checked out revision master/<commit>"),
309309
},
310310
},
311311
{
@@ -319,7 +319,7 @@ func TestGitRepositoryReconciler_reconcileSource_authStrategy(t *testing.T) {
319319
},
320320
want: ctrl.Result{RequeueAfter: mockInterval},
321321
assertConditions: []metav1.Condition{
322-
*conditions.FalseCondition(sourcev1.SourceAvailableCondition, "AuthenticationFailed", "Failed to get auth secret /non-existing: secrets \"non-existing\" not found"),
322+
*conditions.FalseCondition(sourcev1.SourceAvailableCondition, "AuthenticationFailed", "Failed to get secret /non-existing: secrets \"non-existing\" not found"),
323323
},
324324
},
325325
}
@@ -593,7 +593,7 @@ func TestGitRepositoryReconciler_reconcileArtifact(t *testing.T) {
593593
},
594594
want: ctrl.Result{RequeueAfter: mockInterval},
595595
assertConditions: []metav1.Condition{
596-
*conditions.TrueCondition(sourcev1.ArtifactAvailableCondition, "ArchivedArtifact", "Artifact revision main/revision"),
596+
*conditions.TrueCondition(sourcev1.ArtifactAvailableCondition, "ArchivedArtifact", "Compressed source to artifact with revision main/revision"),
597597
},
598598
},
599599
{
@@ -625,7 +625,7 @@ func TestGitRepositoryReconciler_reconcileArtifact(t *testing.T) {
625625
},
626626
want: ctrl.Result{RequeueAfter: mockInterval},
627627
assertConditions: []metav1.Condition{
628-
*conditions.TrueCondition(sourcev1.ArtifactAvailableCondition, "ArchivedArtifact", "Archived artifact revision main/revision"),
628+
*conditions.TrueCondition(sourcev1.ArtifactAvailableCondition, "ArchivedArtifact", "Compressed source to artifact with revision main/revision"),
629629
},
630630
},
631631
}
@@ -1054,6 +1054,12 @@ func TestMain(m *testing.M) {
10541054

10551055
eventsHelper = controller.MakeEvents(newTestEnv, "test", nil)
10561056
metricsHelper = controller.MustMakeMetrics(newTestEnv)
1057+
getters := getter.Providers{
1058+
getter.Provider{
1059+
Schemes: []string{"http", "https"},
1060+
New: getter.NewHTTPGetter,
1061+
},
1062+
}
10571063

10581064
if err := (&GitRepositoryReconciler{
10591065
Client: newTestEnv,
@@ -1068,12 +1074,7 @@ func TestMain(m *testing.M) {
10681074
Client: newTestEnv,
10691075
Events: eventsHelper,
10701076
Metrics: metricsHelper,
1071-
Getters: getter.Providers{
1072-
getter.Provider{
1073-
Schemes: []string{"http", "https"},
1074-
New: getter.NewHTTPGetter,
1075-
},
1076-
},
1077+
Getters: getters,
10771078
Storage: storage,
10781079
}).SetupWithManager(newTestEnv); err != nil {
10791080
panic(fmt.Sprintf("Failed to start HelmRepositoryReconciler: %v", err))
@@ -1088,6 +1089,16 @@ func TestMain(m *testing.M) {
10881089
panic(fmt.Sprintf("Failed to start BucketReconciler: %v", err))
10891090
}
10901091

1092+
if err := (&HelmChartReconciler{
1093+
Client: newTestEnv,
1094+
Events: eventsHelper,
1095+
Metrics: metricsHelper,
1096+
Getters: getters,
1097+
Storage: storage,
1098+
}).SetupWithManager(newTestEnv); err != nil {
1099+
panic(fmt.Sprintf("Failed to start HelmChartReconciler: %v", err))
1100+
}
1101+
10911102
go func() {
10921103
fmt.Println("Starting the test environment manager")
10931104
if err := newTestEnv.StartManager(ctx); err != nil {

0 commit comments

Comments
 (0)