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

chore!: remove legacy repo support (#19768) #21249

Merged
merged 12 commits into from
Feb 3, 2025
Merged
70 changes: 2 additions & 68 deletions cmd/argocd/commands/admin/admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,12 @@ import (
"k8s.io/client-go/dynamic"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
"sigs.k8s.io/yaml"

cmdutil "github.com/argoproj/argo-cd/v3/cmd/util"
"github.com/argoproj/argo-cd/v3/common"
argocdclient "github.com/argoproj/argo-cd/v3/pkg/apiclient"
"github.com/argoproj/argo-cd/v3/util/errors"
"github.com/argoproj/argo-cd/v3/util/settings"

"github.com/argoproj/argo-cd/v3/pkg/apis/application"
"github.com/argoproj/argo-cd/v3/util/errors"
)

const (
Expand Down Expand Up @@ -95,76 +92,13 @@ func newArgoCDClientsets(config *rest.Config, namespace string) *argoCDClientset
}
}

// getReferencedSecrets examines the argocd-cm config for any referenced repo secrets and returns a
// map of all referenced secrets.
func getReferencedSecrets(un unstructured.Unstructured) map[string]bool {
var cm corev1.ConfigMap
err := runtime.DefaultUnstructuredConverter.FromUnstructured(un.Object, &cm)
errors.CheckError(err)
referencedSecrets := make(map[string]bool)

// Referenced repository secrets
if reposRAW, ok := cm.Data["repositories"]; ok {
repos := make([]settings.Repository, 0)
err := yaml.Unmarshal([]byte(reposRAW), &repos)
errors.CheckError(err)
for _, cred := range repos {
if cred.PasswordSecret != nil {
referencedSecrets[cred.PasswordSecret.Name] = true
}
if cred.SSHPrivateKeySecret != nil {
referencedSecrets[cred.SSHPrivateKeySecret.Name] = true
}
if cred.UsernameSecret != nil {
referencedSecrets[cred.UsernameSecret.Name] = true
}
if cred.TLSClientCertDataSecret != nil {
referencedSecrets[cred.TLSClientCertDataSecret.Name] = true
}
if cred.TLSClientCertKeySecret != nil {
referencedSecrets[cred.TLSClientCertKeySecret.Name] = true
}
}
}

// Referenced repository credentials secrets
if reposRAW, ok := cm.Data["repository.credentials"]; ok {
creds := make([]settings.RepositoryCredentials, 0)
err := yaml.Unmarshal([]byte(reposRAW), &creds)
errors.CheckError(err)
for _, cred := range creds {
if cred.PasswordSecret != nil {
referencedSecrets[cred.PasswordSecret.Name] = true
}
if cred.SSHPrivateKeySecret != nil {
referencedSecrets[cred.SSHPrivateKeySecret.Name] = true
}
if cred.UsernameSecret != nil {
referencedSecrets[cred.UsernameSecret.Name] = true
}
if cred.TLSClientCertDataSecret != nil {
referencedSecrets[cred.TLSClientCertDataSecret.Name] = true
}
if cred.TLSClientCertKeySecret != nil {
referencedSecrets[cred.TLSClientCertKeySecret.Name] = true
}
}
}
return referencedSecrets
}

// isArgoCDSecret returns whether or not the given secret is a part of Argo CD configuration
// (e.g. argocd-secret, repo credentials, or cluster credentials)
func isArgoCDSecret(repoSecretRefs map[string]bool, un unstructured.Unstructured) bool {
func isArgoCDSecret(un unstructured.Unstructured) bool {
secretName := un.GetName()
if secretName == common.ArgoCDSecretName {
return true
}
if repoSecretRefs != nil {
if _, ok := repoSecretRefs[secretName]; ok {
return true
}
}
if labels := un.GetLabels(); labels != nil {
if _, ok := labels[common.LabelKeySecretType]; ok {
return true
Expand Down
12 changes: 3 additions & 9 deletions cmd/argocd/commands/admin/backup.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,14 @@ func NewExportCommand() *cobra.Command {
errors.CheckError(err)
export(writer, *acdTLSCertsConfigMap, namespace)

referencedSecrets := getReferencedSecrets(*acdConfigMap)
secrets, err := acdClients.secrets.List(ctx, metav1.ListOptions{})
errors.CheckError(err)
for _, secret := range secrets.Items {
if isArgoCDSecret(referencedSecrets, secret) {
if isArgoCDSecret(secret) {
export(writer, secret, namespace)
}
}

projects, err := acdClients.projects.List(ctx, metav1.ListOptions{})
errors.CheckError(err)
for _, proj := range projects.Items {
Expand Down Expand Up @@ -190,22 +190,16 @@ func NewImportCommand() *cobra.Command {
pruneObjects := make(map[kube.ResourceKey]unstructured.Unstructured)
configMaps, err := acdClients.configMaps.List(ctx, metav1.ListOptions{})
errors.CheckError(err)
// referencedSecrets holds any secrets referenced in the argocd-cm configmap. These
// secrets need to be imported too
var referencedSecrets map[string]bool
for _, cm := range configMaps.Items {
if isArgoCDConfigMap(cm.GetName()) {
pruneObjects[kube.ResourceKey{Group: "", Kind: "ConfigMap", Name: cm.GetName(), Namespace: cm.GetNamespace()}] = cm
}
if cm.GetName() == common.ArgoCDConfigMapName {
referencedSecrets = getReferencedSecrets(cm)
}
}

secrets, err := acdClients.secrets.List(ctx, metav1.ListOptions{})
errors.CheckError(err)
for _, secret := range secrets.Items {
if isArgoCDSecret(referencedSecrets, secret) {
if isArgoCDSecret(secret) {
pruneObjects[kube.ResourceKey{Group: "", Kind: "Secret", Name: secret.GetName(), Namespace: secret.GetNamespace()}] = secret
}
}
Expand Down
13 changes: 0 additions & 13 deletions cmd/argocd/commands/admin/settings.go
Original file line number Diff line number Diff line change
Expand Up @@ -247,19 +247,6 @@ var validatorsByGroup = map[string]settingValidator{
}
return summary, err
},
"repositories": joinValidators(func(manager *settings.SettingsManager) (string, error) {
repos, err := manager.GetRepositories()
if err != nil {
return "", err
}
return fmt.Sprintf("%d repositories", len(repos)), nil
}, func(manager *settings.SettingsManager) (string, error) {
creds, err := manager.GetRepositoryCredentials()
if err != nil {
return "", err
}
return fmt.Sprintf("%d repository credentials", len(creds)), nil
}),
"accounts": func(manager *settings.SettingsManager) (string, error) {
accounts, err := manager.GetAccounts()
if err != nil {
Expand Down
9 changes: 0 additions & 9 deletions cmd/argocd/commands/admin/settings_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,15 +157,6 @@ clientSecret: aaaabbbbccccddddeee`,
},
containsSummary: "updated-options",
},
"Repositories": {
validator: "repositories",
data: map[string]string{
"repositories": `
- url: https://github.com/argoproj/my-private-repository1
- url: https://github.com/argoproj/my-private-repository2`,
},
containsSummary: "2 repositories",
},
"Accounts": {
validator: "accounts",
data: map[string]string{
Expand Down
37 changes: 0 additions & 37 deletions docs/operator-manual/declarative-setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -498,43 +498,6 @@ stringData:

A note on noProxy: Argo CD uses exec to interact with different tools such as helm and kustomize. Not all of these tools support the same noProxy syntax as the [httpproxy go package](https://cs.opensource.google/go/x/net/+/internal-branch.go1.21-vendor:http/httpproxy/proxy.go;l=38-50) does. In case you run in trouble with noProxy not beeing respected you might want to try using the full domain instead of a wildcard pattern or IP range to find a common syntax that all tools support.

### Legacy behaviour

In Argo CD version 2.0 and earlier, repositories were stored as part of the `argocd-cm` config map. For
backward-compatibility, Argo CD will still honor repositories in the config map, but this style of repository
configuration is deprecated and support for it will be removed in a future version.

```yaml
apiVersion: v1
kind: ConfigMap
data:
repositories: |
- url: https://github.com/argoproj/my-private-repository
passwordSecret:
name: my-secret
key: password
usernameSecret:
name: my-secret
key: username
repository.credentials: |
- url: https://github.com/argoproj
passwordSecret:
name: my-secret
key: password
usernameSecret:
name: my-secret
key: username
---
apiVersion: v1
kind: Secret
metadata:
name: my-secret
namespace: argocd
stringData:
password: my-password
username: my-username
```

## Clusters

Cluster credentials are stored in secrets same as repositories or repository credentials. Each secret must have label
Expand Down
21 changes: 21 additions & 0 deletions docs/operator-manual/upgrading/2.14-3.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,27 @@ [email protected]_conn_i%
If authenticating with the CLI, make sure to use the new version as well to obtain an authentication token with the
appropriate claims.

### Removed support for legacy repo config in argocd-cm

Before repositories were managed as Secrets, they were configured in the argocd-cm ConfigMap. The argocd-cm option has
been deprecated for some time and is no longer available in Argo CD 3.0.

#### Detection

To check whether you have any repositories configured in argocd-cm, run the following command:

```shell
kubectl get cm argocd-cm -o=jsonpath="[{.data.repositories}, {.data['repository.credentials']}, {.data['helm.repositories']}]"
```

If you have no repositories configured in argocd-cm, the output will be `[, , ]`, and you are not impacted by this
change.

#### Migration

To convert your repositories to Secrets, follow the documentation for
[declarative management of repositories](../declarative-setup.md#repositories).

## Other changes

### Using `cluster.inClusterEnabled: "false"`
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion test/e2e/fixture/admin/utils/backup.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ type ExportedResources []unstructured.Unstructured

func GetExportedResourcesFromOutput(output string) (ExportedResources, error) {
var resources []unstructured.Unstructured
docs := strings.Split(output, "---")
docs := strings.Split(output, "\n---\n")

for _, doc := range docs {
doc = strings.TrimSpace(doc)
Expand Down
22 changes: 0 additions & 22 deletions test/e2e/fixture/fixture.go
Original file line number Diff line number Diff line change
Expand Up @@ -541,28 +541,6 @@ func SetResourceFilter(filters settings.ResourcesFilter) error {
})
}

func SetHelmRepos(repos ...settings.HelmRepoCredentials) error {
return updateSettingConfigMap(func(cm *corev1.ConfigMap) error {
yamlBytes, err := yaml.Marshal(repos)
if err != nil {
return err
}
cm.Data["helm.repositories"] = string(yamlBytes)
return nil
})
}

func SetRepos(repos ...settings.RepositoryCredentials) error {
return updateSettingConfigMap(func(cm *corev1.ConfigMap) error {
yamlBytes, err := yaml.Marshal(repos)
if err != nil {
return err
}
cm.Data["repositories"] = string(yamlBytes)
return nil
})
}

func SetProjectSpec(project string, spec v1alpha1.AppProjectSpec) error {
proj, err := AppClientset.ArgoprojV1alpha1().AppProjects(TestNamespace()).Get(context.Background(), project, metav1.GetOptions{})
if err != nil {
Expand Down
70 changes: 17 additions & 53 deletions test/e2e/helm_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package e2e

import (
"context"
"fmt"
"net"
"net/http"
Expand All @@ -13,16 +12,12 @@ import (
. "github.com/argoproj/gitops-engine/pkg/sync/common"
"github.com/stretchr/testify/assert"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"

. "github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"
"github.com/argoproj/argo-cd/v3/test/e2e/fixture"
. "github.com/argoproj/argo-cd/v3/test/e2e/fixture/app"
projectFixture "github.com/argoproj/argo-cd/v3/test/e2e/fixture/project"
"github.com/argoproj/argo-cd/v3/test/e2e/fixture/repos"
. "github.com/argoproj/argo-cd/v3/util/errors"
"github.com/argoproj/argo-cd/v3/util/settings"
)

func TestHelmHooksAreCreated(t *testing.T) {
Expand Down Expand Up @@ -436,7 +431,23 @@ func TestHelmValuesHiddenDirectory(t *testing.T) {

func TestHelmWithDependencies(t *testing.T) {
fixture.SkipOnEnv(t, "HELM")
testHelmWithDependencies(t, "helm-with-dependencies", false)

ctx := Given(t).
CustomCACertAdded().
// these are slow tests
Timeout(30).
HelmPassCredentials()

ctx = ctx.HelmRepoAdded("custom-repo")

helmVer := ""

ctx.Path("helm-with-dependencies").
When().
CreateApp("--helm-version", helmVer).
Sync().
Then().
Expect(SyncStatusIs(SyncStatusCodeSynced))
}

func TestHelmWithMultipleDependencies(t *testing.T) {
Expand Down Expand Up @@ -494,53 +505,6 @@ func TestHelmDependenciesPermissionDenied(t *testing.T) {
Expect(Error("", expectedErr))
}

func TestHelmWithDependenciesLegacyRepo(t *testing.T) {
fixture.SkipOnEnv(t, "HELM")
testHelmWithDependencies(t, "helm-with-dependencies", true)
}

func testHelmWithDependencies(t *testing.T, chartPath string, legacyRepo bool) {
t.Helper()
ctx := Given(t).
CustomCACertAdded().
// these are slow tests
Timeout(30).
HelmPassCredentials()
if legacyRepo {
ctx.And(func() {
FailOnErr(fixture.Run("", "kubectl", "create", "secret", "generic", "helm-repo",
"-n", fixture.TestNamespace(),
"--from-file=certSecret="+repos.CertPath,
"--from-file=keySecret="+repos.CertKeyPath,
"--from-literal=username="+fixture.GitUsername,
"--from-literal=password="+fixture.GitPassword,
))
FailOnErr(fixture.KubeClientset.CoreV1().Secrets(fixture.TestNamespace()).Patch(context.Background(),
"helm-repo", types.MergePatchType, []byte(`{"metadata": { "labels": {"e2e.argoproj.io": "true"} }}`), metav1.PatchOptions{}))

CheckError(fixture.SetHelmRepos(settings.HelmRepoCredentials{
URL: fixture.RepoURL(fixture.RepoURLTypeHelm),
Name: "custom-repo",
KeySecret: &corev1.SecretKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: "helm-repo"}, Key: "keySecret"},
CertSecret: &corev1.SecretKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: "helm-repo"}, Key: "certSecret"},
UsernameSecret: &corev1.SecretKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: "helm-repo"}, Key: "username"},
PasswordSecret: &corev1.SecretKeySelector{LocalObjectReference: corev1.LocalObjectReference{Name: "helm-repo"}, Key: "password"},
}))
})
} else {
ctx = ctx.HelmRepoAdded("custom-repo")
}

helmVer := ""

ctx.Path(chartPath).
When().
CreateApp("--helm-version", helmVer).
Sync().
Then().
Expect(SyncStatusIs(SyncStatusCodeSynced))
}

func TestHelm3CRD(t *testing.T) {
fixture.SkipOnEnv(t, "HELM")
Given(t).
Expand Down
Loading