Skip to content

Commit ae23439

Browse files
committed
Add possibility to specify write-back GIT repository as annotation.
1 parent 49825ec commit ae23439

File tree

6 files changed

+78
-13
lines changed

6 files changed

+78
-13
lines changed

docs/basics/update-methods.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,22 @@ kubectl -n argocd-image-updater create secret generic git-creds \
144144
--from-file=sshPrivateKey=~/.ssh/id_rsa
145145
```
146146

147+
### <a name="method-git-repository"></a>Specifying a repository when using a Helm repository in repoURL
148+
149+
By default, Argo CD Image Updater will use the value found in the Application
150+
spec at `.spec.source.repoURL` as Git repository to checkout. But when using
151+
a Helm repository as `.spec.source.repoURL` GIT will simply fail. To manually
152+
specify the repository to push the changes, specify the
153+
annotation `argocd-image-updater.argoproj.io/git-repository` on the Application
154+
manifest.
155+
156+
The value of this annotation will define the Git repository to use, for example the
157+
following would use a GitHub's repository:
158+
159+
```yaml
160+
argocd-image-updater.argoproj.io/git-repository: [email protected]:example/example.git
161+
```
162+
147163
### <a name="method-git-branch"></a>Specifying a branch to commit to
148164

149165
By default, Argo CD Image Updater will use the value found in the Application

pkg/argocd/git.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ func commitChangesGit(app *v1alpha1.Application, wbc *WriteBackConfig, changeLis
131131
logCtx := log.WithContext().AddField("application", app.GetName())
132132
creds, err := wbc.GetCreds(app)
133133
if err != nil {
134-
return fmt.Errorf("could not get creds for repo '%s': %v", app.Spec.Source.RepoURL, err)
134+
return fmt.Errorf("could not get creds for repo '%s': %v", wbc.GitRepo, err)
135135
}
136136
var gitC git.Client
137137
if wbc.GitClient == nil {
@@ -145,7 +145,7 @@ func commitChangesGit(app *v1alpha1.Application, wbc *WriteBackConfig, changeLis
145145
logCtx.Errorf("could not remove temp dir: %v", err)
146146
}
147147
}()
148-
gitC, err = git.NewClientExt(app.Spec.Source.RepoURL, tempRoot, creds, false, false, "")
148+
gitC, err = git.NewClientExt(wbc.GitRepo, tempRoot, creds, false, false, "")
149149
if err != nil {
150150
return err
151151
}

pkg/argocd/gitcreds.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,39 +14,39 @@ import (
1414
)
1515

1616
// getGitCredsSource returns git credentials source that loads credentials from the secret or from Argo CD settings
17-
func getGitCredsSource(creds string, kubeClient *kube.KubernetesClient) (GitCredsSource, error) {
17+
func getGitCredsSource(creds string, kubeClient *kube.KubernetesClient, wbc *WriteBackConfig) (GitCredsSource, error) {
1818
switch {
1919
case creds == "repocreds":
2020
return func(app *v1alpha1.Application) (git.Creds, error) {
21-
return getCredsFromArgoCD(app, kubeClient)
21+
return getCredsFromArgoCD(wbc, kubeClient)
2222
}, nil
2323
case strings.HasPrefix(creds, "secret:"):
2424
return func(app *v1alpha1.Application) (git.Creds, error) {
25-
return getCredsFromSecret(app, creds[len("secret:"):], kubeClient)
25+
return getCredsFromSecret(wbc, creds[len("secret:"):], kubeClient)
2626
}, nil
2727
}
2828
return nil, fmt.Errorf("unexpected credentials format. Expected 'repocreds' or 'secret:<namespace>/<secret>' but got '%s'", creds)
2929
}
3030

3131
// getCredsFromArgoCD loads repository credentials from Argo CD settings
32-
func getCredsFromArgoCD(app *v1alpha1.Application, kubeClient *kube.KubernetesClient) (git.Creds, error) {
32+
func getCredsFromArgoCD(wbc *WriteBackConfig, kubeClient *kube.KubernetesClient) (git.Creds, error) {
3333
ctx, cancel := context.WithCancel(context.Background())
3434
defer cancel()
3535

3636
settingsMgr := settings.NewSettingsManager(ctx, kubeClient.Clientset, kubeClient.Namespace)
3737
argocdDB := db.NewDB(kubeClient.Namespace, settingsMgr, kubeClient.Clientset)
38-
repo, err := argocdDB.GetRepository(ctx, app.Spec.Source.RepoURL)
38+
repo, err := argocdDB.GetRepository(ctx, wbc.GitRepo)
3939
if err != nil {
4040
return nil, err
4141
}
4242
if !repo.HasCredentials() {
43-
return nil, fmt.Errorf("credentials for '%s' are not configured in Argo CD settings", app.Spec.Source.RepoURL)
43+
return nil, fmt.Errorf("credentials for '%s' are not configured in Argo CD settings", wbc.GitRepo)
4444
}
4545
return repo.GetGitCreds(), nil
4646
}
4747

4848
// getCredsFromSecret loads repository credentials from secret
49-
func getCredsFromSecret(app *v1alpha1.Application, credentialsSecret string, kubeClient *kube.KubernetesClient) (git.Creds, error) {
49+
func getCredsFromSecret(wbc *WriteBackConfig, credentialsSecret string, kubeClient *kube.KubernetesClient) (git.Creds, error) {
5050
var credentials map[string][]byte
5151
var err error
5252
s := strings.SplitN(credentialsSecret, "/", 2)
@@ -59,13 +59,13 @@ func getCredsFromSecret(app *v1alpha1.Application, credentialsSecret string, kub
5959
return nil, fmt.Errorf("secret ref must be in format 'namespace/name', but is '%s'", credentialsSecret)
6060
}
6161

62-
if ok, _ := git.IsSSHURL(app.Spec.Source.RepoURL); ok {
62+
if ok, _ := git.IsSSHURL(wbc.GitRepo); ok {
6363
var sshPrivateKey []byte
6464
if sshPrivateKey, ok = credentials["sshPrivateKey"]; !ok {
6565
return nil, fmt.Errorf("invalid secret %s: does not contain field sshPrivateKey", credentialsSecret)
6666
}
6767
return git.NewSSHCreds(string(sshPrivateKey), "", true), nil
68-
} else if git.IsHTTPSURL(app.Spec.Source.RepoURL) {
68+
} else if git.IsHTTPSURL(wbc.GitRepo) {
6969
var username, password []byte
7070
if username, ok = credentials["username"]; !ok {
7171
return nil, fmt.Errorf("invalid secret %s: does not contain field username", credentialsSecret)

pkg/argocd/update.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ type WriteBackConfig struct {
6868
GitCommitMessage string
6969
KustomizeBase string
7070
Target string
71+
GitRepo string
7172
}
7273

7374
// The following are helper structs to only marshal the fields we require
@@ -476,7 +477,12 @@ func parseGitConfig(app *v1alpha1.Application, kubeClient *kube.KubernetesClient
476477
wbc.GitWriteBranch = branches[1]
477478
}
478479
}
479-
credsSource, err := getGitCredsSource(creds, kubeClient)
480+
wbc.GitRepo = app.Spec.Source.RepoURL
481+
repo, ok := app.Annotations[common.GitRepositoryAnnotation]
482+
if ok {
483+
wbc.GitRepo = repo
484+
}
485+
credsSource, err := getGitCredsSource(creds, kubeClient, wbc)
480486
if err != nil {
481487
return fmt.Errorf("invalid git credentials source: %v", err)
482488
}
@@ -486,7 +492,7 @@ func parseGitConfig(app *v1alpha1.Application, kubeClient *kube.KubernetesClient
486492

487493
func commitChangesLocked(app *v1alpha1.Application, wbc *WriteBackConfig, state *SyncIterationState, changeList []ChangeEntry) error {
488494
if wbc.RequiresLocking() {
489-
lock := state.GetRepositoryLock(app.Spec.Source.RepoURL)
495+
lock := state.GetRepositoryLock(wbc.GitRepo)
490496
lock.Lock()
491497
defer lock.Unlock()
492498
}

pkg/argocd/update_test.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1691,6 +1691,48 @@ func Test_GetGitCreds(t *testing.T) {
16911691
require.Error(t, err)
16921692
require.Nil(t, creds)
16931693
})
1694+
1695+
t.Run("SSH creds from Argo CD settings with Helm Chart repoURL", func(t *testing.T) {
1696+
argoClient := argomock.ArgoCD{}
1697+
argoClient.On("UpdateSpec", mock.Anything, mock.Anything).Return(nil, nil)
1698+
secret := fixture.NewSecret("argocd-image-updater", "git-creds", map[string][]byte{
1699+
"sshPrivateKey": []byte("foo"),
1700+
})
1701+
kubeClient := kube.KubernetesClient{
1702+
Clientset: fake.NewFakeClientsetWithResources(secret),
1703+
}
1704+
1705+
app := v1alpha1.Application{
1706+
ObjectMeta: v1.ObjectMeta{
1707+
Name: "testapp",
1708+
Annotations: map[string]string{
1709+
"argocd-image-updater.argoproj.io/image-list": "nginx",
1710+
"argocd-image-updater.argoproj.io/write-back-method": "git:secret:argocd-image-updater/git-creds",
1711+
"argocd-image-updater.argoproj.io/git-repository": "[email protected]:example/example.git",
1712+
},
1713+
},
1714+
Spec: v1alpha1.ApplicationSpec{
1715+
Source: v1alpha1.ApplicationSource{
1716+
RepoURL: "https://example-helm-repo.com/example",
1717+
TargetRevision: "main",
1718+
},
1719+
},
1720+
Status: v1alpha1.ApplicationStatus{
1721+
SourceType: v1alpha1.ApplicationSourceTypeKustomize,
1722+
},
1723+
}
1724+
1725+
wbc, err := getWriteBackConfig(&app, &kubeClient, &argoClient)
1726+
require.NoError(t, err)
1727+
require.Equal(t, wbc.GitRepo, "[email protected]:example/example.git")
1728+
1729+
creds, err := wbc.GetCreds(&app)
1730+
require.NoError(t, err)
1731+
require.NotNil(t, creds)
1732+
// Must have SSH creds
1733+
_, ok := creds.(git.SSHCreds)
1734+
require.True(t, ok)
1735+
})
16941736
}
16951737

16961738
func Test_CommitUpdates(t *testing.T) {

pkg/common/constants.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ const (
5050
const (
5151
WriteBackMethodAnnotation = ImageUpdaterAnnotationPrefix + "/write-back-method"
5252
GitBranchAnnotation = ImageUpdaterAnnotationPrefix + "/git-branch"
53+
GitRepositoryAnnotation = ImageUpdaterAnnotationPrefix + "/git-repository"
5354
WriteBackTargetAnnotation = ImageUpdaterAnnotationPrefix + "/write-back-target"
5455
KustomizationPrefix = "kustomization"
5556
)

0 commit comments

Comments
 (0)