Skip to content

Commit a9a0c7b

Browse files
authored
fix: revert kubeVersion change to preserve trailing + (cherry-pick #24066) (#24104)
Signed-off-by: Alexandre Gaudreault <[email protected]>
1 parent 1c1c176 commit a9a0c7b

File tree

4 files changed

+63
-25
lines changed

4 files changed

+63
-25
lines changed

docs/operator-manual/upgrading/3.0-3.1.md

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,5 @@
11
# v3.0 to 3.1
22

3-
## No more KubeVersions variable modification
4-
5-
Until v3.0, Argo CD removed `+` identifier from `kubeVersions` in Helm, Kustomize and Plugins. For example, if Argo CD receive `kubeVersions` as vX.Y.Z+, we convert to vX.Y.Z internally. Starting with v3.1, the internal conversation is entirely removed.
6-
7-
### Detection
8-
9-
To detect if you are affected, check the `kubeVersions` you are using. If you use `kubeVersions` including `+` identifier, the application must be failed when you upgrade from v3.0 to v3.1.
10-
11-
### Remediation
12-
13-
The plus symbol was originally removed [because Helm did not support it](https://github.com/argoproj/argo-cd/issues/2303). Helm no longer enforces this restriction, so apps should work fine even if your kubeVersions include `+`.
14-
15-
However, since Argo CD now sends unmodified kubeVersions to Helm, the generated manifests may differ due to the changed kubeVersions. For apps which require extra caution, it may be advisable to disable auto-sync, upgrade, check any diffs, and then reenable auto-sync.
16-
173
## Symlink protection in API `--staticassets` directory
184

195
The `--staticassets` directory in the API server (`/app/shared` by default) is now protected against out-of-bounds

docs/user-guide/build-environment.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
[Custom tools](../operator-manual/config-management-plugins.md), [Helm](helm.md), [Jsonnet](jsonnet.md), and [Kustomize](kustomize.md) support the following build env vars:
44

55
| Variable | Description |
6-
|-------------------------------------|-------------------------------------------------------------------------|
6+
| ----------------------------------- | ----------------------------------------------------------------------- |
77
| `ARGOCD_APP_NAME` | The name of the application. |
88
| `ARGOCD_APP_NAMESPACE` | The destination namespace of the application. |
99
| `ARGOCD_APP_PROJECT_NAME` | The name of the project the application belongs to. |
@@ -13,7 +13,7 @@
1313
| `ARGOCD_APP_SOURCE_PATH` | The path of the app within the source repo. |
1414
| `ARGOCD_APP_SOURCE_REPO_URL` | The source repo URL. |
1515
| `ARGOCD_APP_SOURCE_TARGET_REVISION` | The target revision from the spec, e.g. `master`. |
16-
| `KUBE_VERSION` | The version of Kubernetes. |
16+
| `KUBE_VERSION` | The semantic version of Kubernetes without trailing metadata. |
1717
| `KUBE_API_VERSIONS` | The version of the Kubernetes API. |
1818

1919
In case you don't want a variable to be interpolated, `$` can be escaped via `$$`.

reposerver/repository/repository.go

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import (
4040
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
4141
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
4242
"k8s.io/apimachinery/pkg/runtime"
43+
k8sversion "k8s.io/apimachinery/pkg/util/version"
4344
kubeyaml "k8s.io/apimachinery/pkg/util/yaml"
4445

4546
pluginclient "github.com/argoproj/argo-cd/v3/cmpserver/apiclient"
@@ -1167,17 +1168,36 @@ func isSourcePermitted(url string, repos []string) bool {
11671168
return p.IsSourcePermitted(v1alpha1.ApplicationSource{RepoURL: url})
11681169
}
11691170

1171+
// parseKubeVersion is an helper function to remove the non-semantic information supported by kubernetes
1172+
// that may not be supported in all helm versions: https://github.com/helm/helm/pull/31091
1173+
func parseKubeVersion(version string) (string, error) {
1174+
if version == "" {
1175+
return "", nil
1176+
}
1177+
1178+
kubeVersion, err := k8sversion.ParseGeneric(version)
1179+
if err != nil {
1180+
return "", err
1181+
}
1182+
return kubeVersion.String(), nil
1183+
}
1184+
11701185
func helmTemplate(appPath string, repoRoot string, env *v1alpha1.Env, q *apiclient.ManifestRequest, isLocal bool, gitRepoPaths utilio.TempPaths) ([]*unstructured.Unstructured, string, error) {
11711186
// We use the app name as Helm's release name property, which must not
11721187
// contain any underscore characters and must not exceed 53 characters.
11731188
// We are not interested in the fully qualified application name while
11741189
// templating, thus, we just use the name part of the identifier.
11751190
appName, _ := argo.ParseInstanceName(q.AppName, "")
11761191

1192+
kubeVersion, err := parseKubeVersion(q.ApplicationSource.GetKubeVersionOrDefault(q.KubeVersion))
1193+
if err != nil {
1194+
return nil, "", fmt.Errorf("could not parse kubernetes version %s: %w", q.ApplicationSource.GetKubeVersionOrDefault(q.KubeVersion), err)
1195+
}
1196+
11771197
templateOpts := &helm.TemplateOpts{
11781198
Name: appName,
11791199
Namespace: q.ApplicationSource.GetNamespaceOrDefault(q.Namespace),
1180-
KubeVersion: q.ApplicationSource.GetKubeVersionOrDefault(q.KubeVersion),
1200+
KubeVersion: kubeVersion,
11811201
APIVersions: q.ApplicationSource.GetAPIVersionsOrDefault(q.ApiVersions),
11821202
Set: map[string]string{},
11831203
SetString: map[string]string{},
@@ -1502,9 +1522,14 @@ func GenerateManifests(ctx context.Context, appPath, repoRoot, revision string,
15021522
if q.KustomizeOptions != nil {
15031523
kustomizeBinary = q.KustomizeOptions.BinaryPath
15041524
}
1525+
var kubeVersion string
1526+
kubeVersion, err = parseKubeVersion(q.ApplicationSource.GetKubeVersionOrDefault(q.KubeVersion))
1527+
if err != nil {
1528+
return nil, fmt.Errorf("could not parse kubernetes version %s: %w", q.ApplicationSource.GetKubeVersionOrDefault(q.KubeVersion), err)
1529+
}
15051530
k := kustomize.NewKustomizeApp(repoRoot, appPath, q.Repo.GetGitCreds(gitCredsStore), repoURL, kustomizeBinary, q.Repo.Proxy, q.Repo.NoProxy)
15061531
targetObjs, _, commands, err = k.Build(q.ApplicationSource.Kustomize, q.KustomizeOptions, env, &kustomize.BuildOpts{
1507-
KubeVersion: q.ApplicationSource.GetKubeVersionOrDefault(q.KubeVersion),
1532+
KubeVersion: kubeVersion,
15081533
APIVersions: q.ApplicationSource.GetAPIVersionsOrDefault(q.ApiVersions),
15091534
})
15101535
case v1alpha1.ApplicationSourceTypePlugin:
@@ -2023,8 +2048,12 @@ func makeJsonnetVM(appPath string, repoRoot string, sourceJsonnet v1alpha1.Appli
20232048
}
20242049

20252050
func getPluginEnvs(env *v1alpha1.Env, q *apiclient.ManifestRequest) ([]string, error) {
2051+
kubeVersion, err := parseKubeVersion(q.KubeVersion)
2052+
if err != nil {
2053+
return nil, fmt.Errorf("could not parse kubernetes version %s: %w", q.KubeVersion, err)
2054+
}
20262055
envVars := env.Environ()
2027-
envVars = append(envVars, "KUBE_VERSION="+q.KubeVersion)
2056+
envVars = append(envVars, "KUBE_VERSION="+kubeVersion)
20282057
envVars = append(envVars, "KUBE_API_VERSIONS="+strings.Join(q.ApiVersions, ","))
20292058

20302059
return getPluginParamEnvs(envVars, q.ApplicationSource.Plugin)

reposerver/repository/repository_test.go

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1102,6 +1102,27 @@ func TestManifestGenErrorCacheRespectsNoCache(t *testing.T) {
11021102
assert.True(t, strings.HasPrefix(err.Error(), cachedManifestGenerationPrefix))
11031103
}
11041104

1105+
func TestGenerateHelmKubeVersion(t *testing.T) {
1106+
service := newService(t, "../../util/helm/testdata/redis")
1107+
1108+
res, err := service.GenerateManifest(t.Context(), &apiclient.ManifestRequest{
1109+
Repo: &v1alpha1.Repository{},
1110+
AppName: "test",
1111+
ApplicationSource: &v1alpha1.ApplicationSource{
1112+
Path: ".",
1113+
Helm: &v1alpha1.ApplicationSourceHelm{
1114+
KubeVersion: "1.30.11+IKS",
1115+
},
1116+
},
1117+
ProjectName: "something",
1118+
ProjectSourceRepos: []string{"*"},
1119+
})
1120+
1121+
require.NoError(t, err)
1122+
assert.Len(t, res.Commands, 1)
1123+
assert.Contains(t, res.Commands[0], "--kube-version 1.30.11")
1124+
}
1125+
11051126
func TestGenerateHelmWithValues(t *testing.T) {
11061127
service := newService(t, "../../util/helm/testdata/redis")
11071128

@@ -4275,7 +4296,7 @@ func Test_GenerateManifests_Commands(t *testing.T) {
42754296
q := apiclient.ManifestRequest{
42764297
AppName: "test-app",
42774298
Namespace: "test-namespace",
4278-
KubeVersion: "1.2.3",
4299+
KubeVersion: "1.2.3+something",
42794300
ApiVersions: []string{"v1/Test", "v2/Test"},
42804301
Repo: &v1alpha1.Repository{},
42814302
ApplicationSource: &v1alpha1.ApplicationSource{
@@ -4321,7 +4342,7 @@ func Test_GenerateManifests_Commands(t *testing.T) {
43214342
t.Run("with overrides", func(t *testing.T) {
43224343
// These can be set explicitly instead of using inferred values. Make sure the overrides apply.
43234344
q.ApplicationSource.Helm.APIVersions = []string{"v3", "v4"}
4324-
q.ApplicationSource.Helm.KubeVersion = "5.6.7"
4345+
q.ApplicationSource.Helm.KubeVersion = "5.6.7+something"
43254346
q.ApplicationSource.Helm.Namespace = "different-namespace"
43264347
q.ApplicationSource.Helm.ReleaseName = "different-release-name"
43274348

@@ -4396,9 +4417,12 @@ images:
43964417
q := apiclient.ManifestRequest{
43974418
AppName: "test-app",
43984419
Namespace: "test-namespace",
4399-
KubeVersion: "1.2.3",
4420+
KubeVersion: "1.2.3+something",
44004421
ApiVersions: []string{"v1/Test", "v2/Test"},
44014422
Repo: &v1alpha1.Repository{},
4423+
KustomizeOptions: &v1alpha1.KustomizeOptions{
4424+
BuildOptions: "--enable-helm",
4425+
},
44024426
ApplicationSource: &v1alpha1.ApplicationSource{
44034427
Path: ".",
44044428
Kustomize: &v1alpha1.ApplicationSourceKustomize{
@@ -4417,7 +4441,7 @@ images:
44174441
Images: v1alpha1.KustomizeImages{
44184442
"image=override",
44194443
},
4420-
KubeVersion: "5.6.7",
4444+
KubeVersion: "5.6.7+something",
44214445
LabelWithoutSelector: true,
44224446
LabelIncludeTemplates: true,
44234447
NamePrefix: "test-prefix",
@@ -4436,7 +4460,6 @@ images:
44364460
}
44374461

44384462
res, err := service.GenerateManifest(t.Context(), &q)
4439-
44404463
require.NoError(t, err)
44414464
assert.Equal(t, []string{
44424465
"kustomize edit set nameprefix -- test-prefix",
@@ -4447,7 +4470,7 @@ images:
44474470
"kustomize edit add annotation --force test:annotation-test-app",
44484471
"kustomize edit set namespace -- override-namespace",
44494472
"kustomize edit add component component",
4450-
"kustomize build .",
4473+
"kustomize build . --enable-helm --helm-kube-version 5.6.7 --helm-api-versions v1 --helm-api-versions v2",
44514474
}, res.Commands)
44524475
})
44534476
}

0 commit comments

Comments
 (0)