Skip to content

Commit 752dead

Browse files
authored
feat: add resource argocd_repository_certificate (#185)
* feat: add resource argocd_certificate (ssh) * feat: https certificate + explicit ssh/https first-level resource property * RetryContext around repository creation in case of we just created a repository certificate * feat: add feature check for RepositoryCertificates * docs: argocd_certificate * test: more argocd_certificate * fix: remove argocd_certificate import since it cannot be updated * fix: guard against already existing https cert * rename resource argocd_certificate to argocd_repository_certificate * fix: race-condition in resourceArgoCDRepositoryCertificates existing check
1 parent 5de35cc commit 752dead

9 files changed

+1114
-33
lines changed

argocd/features.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"github.com/Masterminds/semver"
99
"github.com/argoproj/argo-cd/v2/pkg/apiclient"
1010
"github.com/argoproj/argo-cd/v2/pkg/apiclient/application"
11+
"github.com/argoproj/argo-cd/v2/pkg/apiclient/certificate"
1112
"github.com/argoproj/argo-cd/v2/pkg/apiclient/cluster"
1213
"github.com/argoproj/argo-cd/v2/pkg/apiclient/project"
1314
"github.com/argoproj/argo-cd/v2/pkg/apiclient/repocreds"
@@ -25,6 +26,7 @@ const (
2526
featureTokenIDs
2627
featureProjectScopedClusters
2728
featureClusterMetadata
29+
featureRepositoryCertificates
2830
)
2931

3032
var (
@@ -35,12 +37,14 @@ var (
3537
featureTokenIDs: semver.MustParse("1.5.3"),
3638
featureProjectScopedClusters: semver.MustParse("2.2.0"),
3739
featureClusterMetadata: semver.MustParse("2.2.0"),
40+
featureRepositoryCertificates: semver.MustParse("1.2.0"),
3841
}
3942
)
4043

4144
type ServerInterface struct {
4245
ApiClient *apiclient.Client
4346
ApplicationClient *application.ApplicationServiceClient
47+
CertificateClient *certificate.CertificateServiceClient
4448
ClusterClient *cluster.ClusterServiceClient
4549
ProjectClient *project.ProjectServiceClient
4650
RepositoryClient *repository.RepositoryServiceClient
@@ -79,6 +83,14 @@ func (p *ServerInterface) initClients() error {
7983
p.ClusterClient = &clusterClient
8084
}
8185

86+
if p.CertificateClient == nil {
87+
_, certClient, err := (*p.ApiClient).NewCertClient()
88+
if err != nil {
89+
return err
90+
}
91+
p.CertificateClient = &certClient
92+
}
93+
8294
if p.ApplicationClient == nil {
8395
_, applicationClient, err := (*p.ApiClient).NewApplicationClient()
8496
if err != nil {

argocd/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ func Provider() *schema.Provider {
156156

157157
ResourcesMap: map[string]*schema.Resource{
158158
"argocd_application": resourceArgoCDApplication(),
159+
"argocd_repository_certificate": resourceArgoCDRepositoryCertificates(),
159160
"argocd_cluster": resourceArgoCDCluster(),
160161
"argocd_project": resourceArgoCDProject(),
161162
"argocd_project_token": resourceArgoCDProjectToken(),

argocd/resource_argocd_repository.go

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@ package argocd
33
import (
44
"context"
55
"fmt"
6+
"regexp"
67
"strings"
78

89
"github.com/argoproj/argo-cd/v2/pkg/apiclient/repository"
910
application "github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
1011
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
12+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
1113
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
1214
)
1315

@@ -40,46 +42,44 @@ func resourceArgoCDRepositoryCreate(ctx context.Context, d *schema.ResourceData,
4042
c := *server.RepositoryClient
4143
repo := expandRepository(d)
4244

43-
tokenMutexConfiguration.Lock()
44-
r, err := c.CreateRepository(
45-
ctx,
46-
&repository.RepoCreateRequest{
47-
Repo: repo,
48-
Upsert: false,
49-
},
50-
)
51-
tokenMutexConfiguration.Unlock()
52-
53-
if err != nil {
54-
return []diag.Diagnostic{
55-
{
56-
Severity: diag.Error,
57-
Summary: fmt.Sprintf("Repository %s not found", repo.Repo),
58-
Detail: err.Error(),
45+
err := resource.RetryContext(ctx, d.Timeout(schema.TimeoutCreate), func() *resource.RetryError {
46+
tokenMutexConfiguration.Lock()
47+
r, err := c.CreateRepository(
48+
ctx,
49+
&repository.RepoCreateRequest{
50+
Repo: repo,
51+
Upsert: false,
5952
},
53+
)
54+
tokenMutexConfiguration.Unlock()
55+
56+
if err != nil {
57+
// TODO: better way to detect ssh handshake failing ?
58+
if matched, _ := regexp.MatchString("ssh: handshake failed: knownhosts: key is unknown", err.Error()); matched {
59+
return resource.RetryableError(fmt.Errorf("Hanshake failed for repository %s, retrying in case a repository certificate has been set recently", repo.Repo))
60+
}
61+
return resource.NonRetryableError(fmt.Errorf("Repository %s not found: %s", repo.Repo, err))
6062
}
61-
}
62-
if r == nil {
63-
return []diag.Diagnostic{
64-
{
65-
Severity: diag.Error,
66-
Summary: fmt.Sprintf("ArgoCD did not return an error or a repository result"),
67-
},
63+
if r == nil {
64+
return resource.NonRetryableError(fmt.Errorf("ArgoCD did not return an error or a repository result: %s", err))
6865
}
69-
}
70-
if r.ConnectionState.Status == application.ConnectionStatusFailed {
66+
if r.ConnectionState.Status == application.ConnectionStatusFailed {
67+
return resource.NonRetryableError(fmt.Errorf("could not connect to repository %s: %s", repo.Repo, r.ConnectionState.Message))
68+
}
69+
d.SetId(r.Repo)
70+
return nil
71+
})
72+
73+
if err != nil {
7174
return []diag.Diagnostic{
7275
{
7376
Severity: diag.Error,
74-
Summary: fmt.Sprintf(
75-
"could not connect to repository %s: %s",
76-
repo.Repo,
77-
r.ConnectionState.Message,
78-
),
77+
Summary: fmt.Sprintf("Error while creating repository %s", repo.Name),
78+
Detail: err.Error(),
7979
},
8080
}
8181
}
82-
d.SetId(r.Repo)
82+
8383
return resourceArgoCDRepositoryRead(ctx, d, meta)
8484
}
8585

0 commit comments

Comments
 (0)