Skip to content

Commit c6cfdfd

Browse files
committed
✨ Add condition for Helm operations
Adding a new condition that gives precise information about the status of the operations regarding helm templating Signed-off-by: janiskemper <[email protected]>
1 parent 61bb596 commit c6cfdfd

File tree

2 files changed

+138
-43
lines changed

2 files changed

+138
-43
lines changed

api/v1alpha1/conditions_const.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,23 @@ const (
4545
HelmChartMissingReason = "HelmChartMissing"
4646
)
4747

48+
const (
49+
// HelmChartTemplatedCondition reports on whether the relevant helm chart has been templated properly.
50+
HelmChartTemplatedCondition clusterv1.ConditionType = "HelmChartTemplated"
51+
52+
// TemplateOldClusterStackOverwriteFailedReason is used when old cluster stack overwrite.yaml is wrong.
53+
TemplateOldClusterStackOverwriteFailedReason = "TemplateOldClusterStackOverwriteFailed"
54+
55+
// TemplateOldClusterStackFailedReason is used when there is a issue doing helm template for the old cluster stack.
56+
TemplateOldClusterStackFailedReason = "TemplateOldClusterStackFailed"
57+
58+
// TemplateNewClusterStackOverwriteFailedReason is used when new cluster stack overwrite.yaml is wrong.
59+
TemplateNewClusterStackOverwriteFailedReason = "TemplateNewClusterStackOverwriteFailed"
60+
61+
// TemplateNewClusterStackFailedReason is used when there is a issue doing helm template for the new cluster stack.
62+
TemplateNewClusterStackFailedReason = "TemplateNewClusterStackFailed"
63+
)
64+
4865
const (
4966
// HelmChartAppliedCondition reports on whether the relevant helm chart has been applied.
5067
HelmChartAppliedCondition clusterv1.ConditionType = "HelmChartApplied"

internal/controller/clusteraddon_controller.go

Lines changed: 121 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -742,11 +742,6 @@ func (r *ClusterAddonReconciler) templateAndApplyClusterAddonHelmChart(ctx conte
742742
func (r *ClusterAddonReconciler) executeStage(ctx context.Context, stage *clusteraddon.Stage, in *templateAndApplyClusterAddonInput) (bool, error) {
743743
logger := log.FromContext(ctx)
744744

745-
var (
746-
shouldRequeue bool
747-
err error
748-
)
749-
750745
_, exists := in.chartMap[stage.Name]
751746
if !exists {
752747
// do not reconcile by returning error, just create an event.
@@ -794,10 +789,28 @@ check:
794789

795790
case csov1alpha1.StagePhaseApplyingOrDeleting:
796791
if stage.Action == clusteraddon.Apply {
797-
logger.V(1).Info("starting to apply helm chart", "clusterStack", in.clusterAddon.Spec.ClusterStack, "name", stage.Name, "hook", in.clusterAddon.Spec.Hook)
798-
shouldRequeue, err = r.templateAndApplyNewClusterStackAddonHelmChart(ctx, in, stage.Name)
792+
logger.V(1).Info("starting to template helm chart", "clusterStack", in.clusterAddon.Spec.ClusterStack, "name", stage.Name, "hook", in.clusterAddon.Spec.Hook)
793+
shouldReturn, oldTemplate, newTemplate, err := r.templateNewClusterStackAddonHelmChart(ctx, in, stage.Name)
799794
if err != nil {
800-
return false, fmt.Errorf("failed to helm template and apply: %w", err)
795+
return false, fmt.Errorf("failed to helm template: %w", err)
796+
}
797+
if shouldReturn {
798+
return false, nil
799+
}
800+
801+
logger.V(1).Info("finished templating helm chart and starting to apply helm chart", "clusterStack", in.clusterAddon.Spec.ClusterStack, "name", stage.Name, "hook", in.clusterAddon.Spec.Hook)
802+
803+
newResources, shouldRequeue, err := in.kubeClient.ApplyNewClusterStack(ctx, oldTemplate, newTemplate)
804+
if err != nil {
805+
conditions.MarkFalse(
806+
in.clusterAddon,
807+
csov1alpha1.HelmChartAppliedCondition,
808+
csov1alpha1.FailedToApplyObjectsReason,
809+
clusterv1.ConditionSeverityInfo,
810+
"failed to successfully apply helm chart: %q: %s", stage.Name, err.Error(),
811+
)
812+
813+
return false, fmt.Errorf("failed to apply objects from cluster addon Helm chart: %w", err)
801814
}
802815
if shouldRequeue {
803816
conditions.MarkFalse(
@@ -810,21 +823,38 @@ check:
810823

811824
return true, nil
812825
}
826+
827+
// This is for the current stage objects and will be removed once done.
828+
in.clusterAddon.Status.Resources = newResources
813829
logger.V(1).Info("finished applying helm chart", "clusterStack", in.clusterAddon.Spec.ClusterStack, "name", stage.Name, "hook", in.clusterAddon.Spec.Hook)
814830

831+
// delete the false condition with failed to apply reason
832+
conditions.Delete(in.clusterAddon, csov1alpha1.HelmChartAppliedCondition)
833+
815834
// remove status resource if applied successfully
816835
in.clusterAddon.Status.Resources = make([]*csov1alpha1.Resource, 0)
817836

818837
in.clusterAddon.SetStagePhase(stage.Name, stage.Action, csov1alpha1.StagePhaseWaitingForPostCondition)
819838
goto check
820839
} else {
821840
// Delete part
822-
logger.V(1).Info("starting to delete helm chart", "clusterStack", in.clusterAddon.Spec.ClusterStack, "name", stage.Name, "hook", in.clusterAddon.Spec.Hook)
823-
shouldRequeue, err = helmTemplateAndDeleteNewClusterStack(ctx, in, stage.Name)
841+
logger.V(1).Info("starting to template helm chart", "clusterStack", in.clusterAddon.Spec.ClusterStack, "name", stage.Name, "hook", in.clusterAddon.Spec.Hook)
842+
helmTemplate, err := helmTemplateNewClusterStack(in, stage.Name)
824843
if err != nil {
825-
return false, fmt.Errorf("failed to delete helm chart: %w", err)
844+
conditions.MarkFalse(
845+
in.clusterAddon,
846+
csov1alpha1.HelmChartTemplatedCondition,
847+
csov1alpha1.TemplateNewClusterStackFailedReason,
848+
clusterv1.ConditionSeverityError,
849+
"failed to template new helm chart: %s", err.Error(),
850+
)
851+
852+
return false, nil
826853
}
827-
if shouldRequeue {
854+
logger.V(1).Info("finished templating helm chart and starting to delete helm chart", "clusterStack", in.clusterAddon.Spec.ClusterStack, "name", stage.Name, "hook", in.clusterAddon.Spec.Hook)
855+
856+
deletedResources, shouldRequeue, err := in.kubeClient.DeleteNewClusterStack(ctx, helmTemplate)
857+
if err != nil {
828858
conditions.MarkFalse(
829859
in.clusterAddon,
830860
csov1alpha1.HelmChartDeletedCondition,
@@ -833,13 +863,22 @@ check:
833863
"failed to successfully delete helm chart: %q", stage.Name,
834864
)
835865

866+
return false, fmt.Errorf("failed to delete objects from cluster addon Helm chart: %w", err)
867+
}
868+
if shouldRequeue {
836869
return true, nil
837870
}
871+
872+
// This is for the current stage objects and will be removed once done.
873+
in.clusterAddon.Status.Resources = deletedResources
838874
logger.V(1).Info("finished deleting helm chart", "clusterStack", in.clusterAddon.Spec.ClusterStack, "name", stage.Name, "hook", in.clusterAddon.Spec.Hook)
839875

840876
// remove status resource if deleted successfully
841877
in.clusterAddon.Status.Resources = make([]*csov1alpha1.Resource, 0)
842878

879+
// delete the false condition with failed to apply reason
880+
conditions.Delete(in.clusterAddon, csov1alpha1.HelmChartDeletedCondition)
881+
843882
in.clusterAddon.SetStagePhase(stage.Name, stage.Action, csov1alpha1.StagePhaseWaitingForPostCondition)
844883
goto check
845884
}
@@ -940,12 +979,13 @@ func (r *ClusterAddonReconciler) downloadOldClusterStackRelease(ctx context.Cont
940979
return &releaseAsset, false, nil
941980
}
942981

943-
func (r *ClusterAddonReconciler) templateAndApplyNewClusterStackAddonHelmChart(ctx context.Context, in *templateAndApplyClusterAddonInput, name string) (bool, error) {
982+
func (r *ClusterAddonReconciler) templateNewClusterStackAddonHelmChart(ctx context.Context, in *templateAndApplyClusterAddonInput, name string) (shouldReturn bool, oldTemplate, newTemplate []byte, err error) { //nolint:revive // ignoring the 4 return values
944983
var (
945-
oldHelmTemplate []byte
946984
oldBuildTemplate []byte
985+
oldHelmTemplate []byte
986+
947987
newBuildTemplate []byte
948-
err error
988+
newHelmTemplate []byte
949989
)
950990

951991
if in.oldDestinationClusterAddonChartDir != "" {
@@ -955,12 +995,40 @@ func (r *ClusterAddonReconciler) templateAndApplyNewClusterStackAddonHelmChart(c
955995
if _, err := os.Stat(filepath.Join(oldClusterStackSubDirPath, release.OverwriteYaml)); err == nil {
956996
oldBuildTemplate, err = buildTemplateFromClusterAddonValues(ctx, filepath.Join(oldClusterStackSubDirPath, release.OverwriteYaml), in.cluster, r.Client)
957997
if err != nil {
958-
return false, fmt.Errorf("failed to build template from old cluster addon values: %w", err)
998+
conditions.MarkFalse(
999+
in.clusterAddon,
1000+
csov1alpha1.HelmChartTemplatedCondition,
1001+
csov1alpha1.TemplateOldClusterStackOverwriteFailedReason,
1002+
clusterv1.ConditionSeverityError,
1003+
"failed to build template from old cluster addon values: %s", err.Error(),
1004+
)
1005+
1006+
record.Warnf(
1007+
in.clusterAddon,
1008+
csov1alpha1.TemplateOldClusterStackOverwriteFailedReason,
1009+
"failed to build template from old cluster addon values: %s", err.Error(),
1010+
)
1011+
1012+
return true, nil, nil, nil
9591013
}
9601014

9611015
oldHelmTemplate, err = helmTemplateClusterAddon(oldClusterStackSubDirPath, oldBuildTemplate)
9621016
if err != nil {
963-
return false, fmt.Errorf("failed to template old helm chart: %w", err)
1017+
conditions.MarkFalse(
1018+
in.clusterAddon,
1019+
csov1alpha1.HelmChartTemplatedCondition,
1020+
csov1alpha1.TemplateOldClusterStackFailedReason,
1021+
clusterv1.ConditionSeverityError,
1022+
"failed to template old helm chart: %s", err.Error(),
1023+
)
1024+
1025+
record.Warnf(
1026+
in.clusterAddon,
1027+
csov1alpha1.TemplateOldClusterStackFailedReason,
1028+
"failed to template old helm chart: %s", err.Error(),
1029+
)
1030+
1031+
return true, nil, nil, nil
9641032
}
9651033
}
9661034
}
@@ -970,47 +1038,57 @@ func (r *ClusterAddonReconciler) templateAndApplyNewClusterStackAddonHelmChart(c
9701038
if _, err := os.Stat(filepath.Join(newClusterStackSubDirPath, release.OverwriteYaml)); err == nil {
9711039
newBuildTemplate, err = buildTemplateFromClusterAddonValues(ctx, filepath.Join(newClusterStackSubDirPath, release.OverwriteYaml), in.cluster, r.Client)
9721040
if err != nil {
973-
return false, fmt.Errorf("failed to build template from new cluster addon values: %w", err)
1041+
conditions.MarkFalse(
1042+
in.clusterAddon,
1043+
csov1alpha1.HelmChartTemplatedCondition,
1044+
csov1alpha1.TemplateNewClusterStackOverwriteFailedReason,
1045+
clusterv1.ConditionSeverityError,
1046+
"failed to build template from new cluster addon values: %s", err.Error(),
1047+
)
1048+
1049+
record.Eventf(
1050+
in.clusterAddon,
1051+
csov1alpha1.TemplateNewClusterStackOverwriteFailedReason,
1052+
"failed to build template from new cluster addon values: %s", err.Error(),
1053+
)
1054+
1055+
return true, nil, nil, nil
9741056
}
9751057
}
9761058

977-
newHelmTemplate, err := helmTemplateClusterAddon(newClusterStackSubDirPath, newBuildTemplate)
1059+
newHelmTemplate, err = helmTemplateClusterAddon(newClusterStackSubDirPath, newBuildTemplate)
9781060
if err != nil {
979-
return false, fmt.Errorf("failed to template new helm chart: %w", err)
980-
}
1061+
conditions.MarkFalse(
1062+
in.clusterAddon,
1063+
csov1alpha1.HelmChartTemplatedCondition,
1064+
csov1alpha1.TemplateNewClusterStackFailedReason,
1065+
clusterv1.ConditionSeverityError,
1066+
"failed to template new helm chart: %s", err.Error(),
1067+
)
9811068

982-
newResources, shouldRequeue, err := in.kubeClient.ApplyNewClusterStack(ctx, oldHelmTemplate, newHelmTemplate)
983-
if err != nil {
984-
return false, fmt.Errorf("failed to apply objects from cluster addon Helm chart: %w", err)
985-
}
1069+
record.Eventf(
1070+
in.clusterAddon,
1071+
csov1alpha1.TemplateNewClusterStackFailedReason,
1072+
"failed to template new helm chart: %s", err.Error(),
1073+
)
9861074

987-
// This is for the current stage objects and will be removed once done.
988-
in.clusterAddon.Status.Resources = newResources
1075+
return true, nil, nil, nil
1076+
}
1077+
conditions.Delete(in.clusterAddon, csov1alpha1.HelmChartTemplatedCondition)
9891078

990-
return shouldRequeue, nil
1079+
return false, oldHelmTemplate, newHelmTemplate, nil
9911080
}
9921081

993-
func helmTemplateAndDeleteNewClusterStack(ctx context.Context, in *templateAndApplyClusterAddonInput, name string) (bool, error) {
994-
var (
995-
buildTemplate []byte
996-
err error
997-
)
1082+
func helmTemplateNewClusterStack(in *templateAndApplyClusterAddonInput, name string) (newTemplate []byte, err error) {
1083+
var buildTemplate []byte
9981084

9991085
newClusterStackSubDirPath := filepath.Join(in.newDestinationClusterAddonChartDir, name)
10001086
newHelmTemplate, err := helmTemplateClusterAddon(newClusterStackSubDirPath, buildTemplate)
10011087
if err != nil {
1002-
return false, fmt.Errorf("failed to template new helm chart: %w", err)
1003-
}
1004-
1005-
deletedResources, shouldRequeue, err := in.kubeClient.DeleteNewClusterStack(ctx, newHelmTemplate)
1006-
if err != nil {
1007-
return false, fmt.Errorf("failed to delete objects from cluster addon Helm chart: %w", err)
1088+
return nil, fmt.Errorf("failed to template new helm chart: %w", err)
10081089
}
10091090

1010-
// This is for the current stage objects and will be removed once done.
1011-
in.clusterAddon.Status.Resources = deletedResources
1012-
1013-
return shouldRequeue, nil
1091+
return newHelmTemplate, nil
10141092
}
10151093

10161094
func getDynamicResourceAndEvaluateCEL(ctx context.Context, dynamicClient *dynamic.DynamicClient, discoveryClient *discovery.DiscoveryClient, waitCondition clusteraddon.WaitForCondition) error {

0 commit comments

Comments
 (0)