Skip to content

Commit e43ca4d

Browse files
authored
Merge pull request #1384 from cappyzawa/issues/1381
Add ServerSideApply field to HelmRelease API
2 parents 0747d86 + 280192a commit e43ca4d

File tree

16 files changed

+442
-0
lines changed

16 files changed

+442
-0
lines changed

.github/workflows/e2e.yaml

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,80 @@ jobs:
6363
kubectl -n helm-system wait helmreleases/podinfo-git --for=condition=ready --timeout=4m
6464
kubectl -n helm-system wait helmreleases/podinfo-oci --for=condition=ready --timeout=4m
6565
kubectl -n helm-system delete -f config/testdata/podinfo
66+
- name: Run server-side apply test
67+
run: |
68+
test_name=server-side-apply
69+
kubectl -n helm-system apply -f config/testdata/$test_name/install.yaml
70+
kubectl -n helm-system wait helmreleases/$test_name --for=condition=ready --timeout=4m
71+
72+
# Verify the release is deployed with SSA.
73+
APPLY_METHOD=$(kubectl -n helm-system get secret sh.helm.release.v1.$test_name.v1 -o jsonpath='{.data.release}' | base64 -d | base64 -d | gunzip | jq -r '.apply_method')
74+
if [ "$APPLY_METHOD" != "ssa" ]; then
75+
echo -e "Unexpected apply method: $APPLY_METHOD (expected: ssa)"
76+
exit 1
77+
fi
78+
79+
# Upgrade with SSA.
80+
kubectl -n helm-system apply -f config/testdata/$test_name/upgrade.yaml
81+
kubectl -n helm-system wait helmreleases/$test_name --for=condition=ready --timeout=4m
82+
83+
# Validate release was upgraded.
84+
REVISION_COUNT=$(helm -n helm-system history -o json $test_name | jq 'length')
85+
if [ "$REVISION_COUNT" != 2 ]; then
86+
echo -e "Unexpected revision count: $REVISION_COUNT"
87+
exit 1
88+
fi
89+
90+
kubectl -n helm-system delete -f config/testdata/$test_name/install.yaml
91+
- name: Run server-side apply rollback test
92+
run: |
93+
test_name=server-side-apply-rollback
94+
kubectl -n helm-system apply -f config/testdata/server-side-apply/rollback-install.yaml
95+
kubectl -n helm-system wait helmreleases/$test_name --for=condition=ready --timeout=4m
96+
97+
# Verify the release is deployed with SSA.
98+
APPLY_METHOD=$(kubectl -n helm-system get secret sh.helm.release.v1.$test_name.v1 -o jsonpath='{.data.release}' | base64 -d | base64 -d | gunzip | jq -r '.apply_method')
99+
if [ "$APPLY_METHOD" != "ssa" ]; then
100+
echo -e "Unexpected apply method: $APPLY_METHOD (expected: ssa)"
101+
exit 1
102+
fi
103+
104+
# Upgrade with failing config to trigger rollback.
105+
kubectl -n helm-system apply -f config/testdata/server-side-apply/rollback-upgrade.yaml
106+
echo -n ">>> Waiting for rollback"
107+
count=0
108+
until [ 'true' == "$( kubectl -n helm-system get helmrelease/$test_name -o json | jq '.status.conditions | map( { (.type): .status } ) | add | .Released=="False" and .Ready=="False" and .Remediated=="True"' )" ]; do
109+
echo -n '.'
110+
sleep 5
111+
count=$((count + 1))
112+
if [[ ${count} -eq 24 ]]; then
113+
echo ' No more retries left!'
114+
exit 1
115+
fi
116+
done
117+
echo ' done'
118+
119+
# Validate rollback happened with SSA (revision 3 = rollback to 1).
120+
HISTORY=$(helm -n helm-system history -o json $test_name)
121+
REVISION_COUNT=$(echo "$HISTORY" | jq 'length')
122+
if [ "$REVISION_COUNT" != 3 ]; then
123+
echo -e "Unexpected revision count: $REVISION_COUNT"
124+
exit 1
125+
fi
126+
LAST_REVISION_DESCRIPTION=$(echo "$HISTORY" | jq -r 'last | .description')
127+
if [ "$LAST_REVISION_DESCRIPTION" != "Rollback to 1" ]; then
128+
echo -e "Unexpected last revision description: $LAST_REVISION_DESCRIPTION"
129+
exit 1
130+
fi
131+
132+
# Verify the rollback release used SSA.
133+
APPLY_METHOD=$(kubectl -n helm-system get secret sh.helm.release.v1.$test_name.v3 -o jsonpath='{.data.release}' | base64 -d | base64 -d | gunzip | jq -r '.apply_method')
134+
if [ "$APPLY_METHOD" != "ssa" ]; then
135+
echo -e "Unexpected apply method after rollback: $APPLY_METHOD (expected: ssa)"
136+
exit 1
137+
fi
138+
139+
kubectl -n helm-system delete -f config/testdata/server-side-apply/rollback-install.yaml
66140
- name: Run dependency tests
67141
run: |
68142
kubectl -n helm-system apply -f config/testdata/dependencies

api/v2/helmrelease_types.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,11 @@ type Install struct {
541541
// On uninstall, the namespace will not be garbage collected.
542542
// +optional
543543
CreateNamespace bool `json:"createNamespace,omitempty"`
544+
545+
// ServerSideApply enables server-side apply for resources during install.
546+
// Defaults to true (or false when UseHelm3Defaults feature gate is enabled).
547+
// +optional
548+
ServerSideApply *bool `json:"serverSideApply,omitempty"`
544549
}
545550

546551
// GetTimeout returns the configured timeout for the Helm install action,
@@ -679,6 +684,21 @@ const (
679684
CreateReplace CRDsPolicy = "CreateReplace"
680685
)
681686

687+
// ServerSideApplyMode defines the server-side apply mode for Helm upgrade and
688+
// rollback actions.
689+
type ServerSideApplyMode string
690+
691+
var (
692+
// ServerSideApplyEnabled enables server-side apply for resources.
693+
ServerSideApplyEnabled ServerSideApplyMode = "enabled"
694+
695+
// ServerSideApplyDisabled disables server-side apply for resources.
696+
ServerSideApplyDisabled ServerSideApplyMode = "disabled"
697+
698+
// ServerSideApplyAuto uses the release's previous apply method.
699+
ServerSideApplyAuto ServerSideApplyMode = "auto"
700+
)
701+
682702
// Upgrade holds the configuration for Helm upgrade actions for this
683703
// HelmRelease.
684704
type Upgrade struct {
@@ -763,6 +783,14 @@ type Upgrade struct {
763783
// +kubebuilder:validation:Enum=Skip;Create;CreateReplace
764784
// +optional
765785
CRDs CRDsPolicy `json:"crds,omitempty"`
786+
787+
// ServerSideApply enables server-side apply for resources during upgrade.
788+
// Can be "enabled", "disabled", or "auto".
789+
// When "auto", server-side apply usage will be based on the release's previous usage.
790+
// Defaults to "auto".
791+
// +kubebuilder:validation:Enum=enabled;disabled;auto
792+
// +optional
793+
ServerSideApply ServerSideApplyMode `json:"serverSideApply,omitempty"`
766794
}
767795

768796
// GetTimeout returns the configured timeout for the Helm upgrade action, or the
@@ -1021,6 +1049,14 @@ type Rollback struct {
10211049
// rollback action when it fails.
10221050
// +optional
10231051
CleanupOnFail bool `json:"cleanupOnFail,omitempty"`
1052+
1053+
// ServerSideApply enables server-side apply for resources during rollback.
1054+
// Can be "enabled", "disabled", or "auto".
1055+
// When "auto", server-side apply usage will be based on the release's previous usage.
1056+
// Defaults to "auto".
1057+
// +kubebuilder:validation:Enum=enabled;disabled;auto
1058+
// +optional
1059+
ServerSideApply ServerSideApplyMode `json:"serverSideApply,omitempty"`
10241060
}
10251061

10261062
// GetTimeout returns the configured timeout for the Helm rollback action, or

api/v2/zz_generated.deepcopy.go

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/crd/bases/helm.toolkit.fluxcd.io_helmreleases.yaml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,11 @@ spec:
439439
Replace tells the Helm install action to re-use the 'ReleaseName', but only
440440
if that name is a deleted release which remains in the history.
441441
type: boolean
442+
serverSideApply:
443+
description: |-
444+
ServerSideApply enables server-side apply for resources during install.
445+
Defaults to true (or false when UseHelm3Defaults feature gate is enabled).
446+
type: boolean
442447
skipCRDs:
443448
description: |-
444449
SkipCRDs tells the Helm install action to not install any CRDs. By default,
@@ -727,6 +732,17 @@ spec:
727732
warning if set to true. It will also be removed in a
728733
future release.
729734
type: boolean
735+
serverSideApply:
736+
description: |-
737+
ServerSideApply enables server-side apply for resources during rollback.
738+
Can be "enabled", "disabled", or "auto".
739+
When "auto", server-side apply usage will be based on the release's previous usage.
740+
Defaults to "auto".
741+
enum:
742+
- enabled
743+
- disabled
744+
- auto
745+
type: string
730746
timeout:
731747
description: |-
732748
Timeout is the time to wait for any individual Kubernetes operation (like
@@ -945,6 +961,17 @@ spec:
945961
- uninstall
946962
type: string
947963
type: object
964+
serverSideApply:
965+
description: |-
966+
ServerSideApply enables server-side apply for resources during upgrade.
967+
Can be "enabled", "disabled", or "auto".
968+
When "auto", server-side apply usage will be based on the release's previous usage.
969+
Defaults to "auto".
970+
enum:
971+
- enabled
972+
- disabled
973+
- auto
974+
type: string
948975
strategy:
949976
description: |-
950977
Strategy defines the upgrade strategy to use for this HelmRelease.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
apiVersion: helm.toolkit.fluxcd.io/v2
2+
kind: HelmRelease
3+
metadata:
4+
name: server-side-apply
5+
spec:
6+
interval: 5m
7+
install:
8+
serverSideApply: true
9+
chart:
10+
spec:
11+
chart: podinfo
12+
version: '>=6.0.0 <7.0.0'
13+
sourceRef:
14+
kind: HelmRepository
15+
name: podinfo
16+
interval: 1m
17+
values:
18+
resources:
19+
requests:
20+
cpu: 100m
21+
memory: 64Mi
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
apiVersion: helm.toolkit.fluxcd.io/v2
2+
kind: HelmRelease
3+
metadata:
4+
name: server-side-apply-rollback
5+
spec:
6+
interval: 30s
7+
install:
8+
serverSideApply: true
9+
chart:
10+
spec:
11+
chart: podinfo
12+
version: '>=6.0.0 <7.0.0'
13+
sourceRef:
14+
kind: HelmRepository
15+
name: podinfo
16+
interval: 10m
17+
values:
18+
resources:
19+
requests:
20+
cpu: 100m
21+
memory: 64Mi
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
apiVersion: helm.toolkit.fluxcd.io/v2
2+
kind: HelmRelease
3+
metadata:
4+
name: server-side-apply-rollback
5+
spec:
6+
interval: 30s
7+
install:
8+
serverSideApply: true
9+
upgrade:
10+
serverSideApply: enabled
11+
remediation:
12+
remediateLastFailure: true
13+
rollback:
14+
serverSideApply: enabled
15+
chart:
16+
spec:
17+
chart: podinfo
18+
version: '>=6.0.0 <7.0.0'
19+
sourceRef:
20+
kind: HelmRepository
21+
name: podinfo
22+
interval: 10m
23+
values:
24+
resources:
25+
requests:
26+
cpu: 100m
27+
memory: 64Mi
28+
# Make wait fail to trigger rollback
29+
replicaCount: 2
30+
faults:
31+
unready: true
32+
timeout: 3s
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
apiVersion: helm.toolkit.fluxcd.io/v2
2+
kind: HelmRelease
3+
metadata:
4+
name: server-side-apply
5+
spec:
6+
interval: 5m
7+
install:
8+
serverSideApply: true
9+
upgrade:
10+
serverSideApply: enabled
11+
chart:
12+
spec:
13+
chart: podinfo
14+
version: '>=6.0.0 <7.0.0'
15+
sourceRef:
16+
kind: HelmRepository
17+
name: podinfo
18+
interval: 1m
19+
values:
20+
resources:
21+
requests:
22+
cpu: 100m
23+
memory: 64Mi
24+
replicaCount: 2

docs/api/v2/helm.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2109,6 +2109,19 @@ HelmReleaseSpec.TargetNamespace if it does not exist yet.
21092109
On uninstall, the namespace will not be garbage collected.</p>
21102110
</td>
21112111
</tr>
2112+
<tr>
2113+
<td>
2114+
<code>serverSideApply</code><br>
2115+
<em>
2116+
bool
2117+
</em>
2118+
</td>
2119+
<td>
2120+
<em>(Optional)</em>
2121+
<p>ServerSideApply enables server-side apply for resources during install.
2122+
Defaults to true (or false when UseHelm3Defaults feature gate is enabled).</p>
2123+
</td>
2124+
</tr>
21122125
</tbody>
21132126
</table>
21142127
</div>
@@ -2449,10 +2462,36 @@ bool
24492462
rollback action when it fails.</p>
24502463
</td>
24512464
</tr>
2465+
<tr>
2466+
<td>
2467+
<code>serverSideApply</code><br>
2468+
<em>
2469+
<a href="#helm.toolkit.fluxcd.io/v2.ServerSideApplyMode">
2470+
ServerSideApplyMode
2471+
</a>
2472+
</em>
2473+
</td>
2474+
<td>
2475+
<em>(Optional)</em>
2476+
<p>ServerSideApply enables server-side apply for resources during rollback.
2477+
Can be &ldquo;enabled&rdquo;, &ldquo;disabled&rdquo;, or &ldquo;auto&rdquo;.
2478+
When &ldquo;auto&rdquo;, server-side apply usage will be based on the release&rsquo;s previous usage.
2479+
Defaults to &ldquo;auto&rdquo;.</p>
2480+
</td>
2481+
</tr>
24522482
</tbody>
24532483
</table>
24542484
</div>
24552485
</div>
2486+
<h3 id="helm.toolkit.fluxcd.io/v2.ServerSideApplyMode">ServerSideApplyMode
2487+
(<code>string</code> alias)</h3>
2488+
<p>
2489+
(<em>Appears on:</em>
2490+
<a href="#helm.toolkit.fluxcd.io/v2.Rollback">Rollback</a>,
2491+
<a href="#helm.toolkit.fluxcd.io/v2.Upgrade">Upgrade</a>)
2492+
</p>
2493+
<p>ServerSideApplyMode defines the server-side apply mode for Helm upgrade and
2494+
rollback actions.</p>
24562495
<h3 id="helm.toolkit.fluxcd.io/v2.Snapshot">Snapshot
24572496
</h3>
24582497
<p>Snapshot captures a point-in-time copy of the status information for a Helm release,
@@ -3098,6 +3137,23 @@ option users can opt-in to CRD upgrade, which is not (yet) natively supported by
30983137
<a href="https://helm.sh/docs/chart_best_practices/custom_resource_definitions">https://helm.sh/docs/chart_best_practices/custom_resource_definitions</a>.</p>
30993138
</td>
31003139
</tr>
3140+
<tr>
3141+
<td>
3142+
<code>serverSideApply</code><br>
3143+
<em>
3144+
<a href="#helm.toolkit.fluxcd.io/v2.ServerSideApplyMode">
3145+
ServerSideApplyMode
3146+
</a>
3147+
</em>
3148+
</td>
3149+
<td>
3150+
<em>(Optional)</em>
3151+
<p>ServerSideApply enables server-side apply for resources during upgrade.
3152+
Can be &ldquo;enabled&rdquo;, &ldquo;disabled&rdquo;, or &ldquo;auto&rdquo;.
3153+
When &ldquo;auto&rdquo;, server-side apply usage will be based on the release&rsquo;s previous usage.
3154+
Defaults to &ldquo;auto&rdquo;.</p>
3155+
</td>
3156+
</tr>
31013157
</tbody>
31023158
</table>
31033159
</div>

internal/action/install.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ func newInstall(config *helmaction.Configuration, obj *v2.HelmRelease, opts []In
7575
default:
7676
install.ServerSideApply = true
7777
}
78+
if ssa := obj.GetInstall().ServerSideApply; ssa != nil {
79+
install.ServerSideApply = *ssa
80+
}
7881

7982
install.ReleaseName = release.ShortenName(obj.GetReleaseName())
8083
install.Namespace = obj.GetReleaseNamespace()

0 commit comments

Comments
 (0)