Skip to content

Commit cb9f554

Browse files
Add support for GitHub app credentials (#235)
Co-authored-by: OneMatchFox <[email protected]>
1 parent 124d87b commit cb9f554

11 files changed

+283
-24
lines changed

argocd/resource_argocd_repository.go

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,16 @@ func resourceArgoCDRepositoryCreate(ctx context.Context, d *schema.ResourceData,
3939
}
4040

4141
c := *server.RepositoryClient
42-
repo := expandRepository(d)
42+
repo, err := expandRepository(d)
43+
if err != nil {
44+
return []diag.Diagnostic{
45+
{
46+
Severity: diag.Error,
47+
Summary: fmt.Sprintf("could not expand repository attributes: %s", err),
48+
Detail: err.Error(),
49+
},
50+
}
51+
}
4352

4453
featureProjectScopedRepositoriesSupported, err := server.isFeatureSupported(featureProjectScopedRepositories)
4554
if err != nil {
@@ -211,7 +220,16 @@ func resourceArgoCDRepositoryUpdate(ctx context.Context, d *schema.ResourceData,
211220
}
212221
}
213222
c := *server.RepositoryClient
214-
repo := expandRepository(d)
223+
repo, err := expandRepository(d)
224+
if err != nil {
225+
return []diag.Diagnostic{
226+
{
227+
Severity: diag.Error,
228+
Summary: fmt.Sprintf("could not expand repository attributes: %s", err),
229+
Detail: err.Error(),
230+
},
231+
}
232+
}
215233

216234
featureProjectScopedRepositoriesSupported, err := server.isFeatureSupported(featureProjectScopedRepositories)
217235
if err != nil {

argocd/resource_argocd_repository_credentials.go

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,16 @@ func resourceArgoCDRepositoryCredentialsCreate(ctx context.Context, d *schema.Re
3636
}
3737
}
3838
c := *server.RepoCredsClient
39-
repoCreds := expandRepositoryCredentials(d)
39+
repoCreds, err := expandRepositoryCredentials(d)
40+
if err != nil {
41+
return []diag.Diagnostic{
42+
{
43+
Severity: diag.Error,
44+
Summary: fmt.Sprintf("could not expand repository credential attributes: %s", err),
45+
Detail: err.Error(),
46+
},
47+
}
48+
}
4049

4150
tokenMutexConfiguration.Lock()
4251
rc, err := c.CreateRepositoryCredentials(
@@ -122,7 +131,16 @@ func resourceArgoCDRepositoryCredentialsUpdate(ctx context.Context, d *schema.Re
122131
}
123132
}
124133
c := *server.RepoCredsClient
125-
repoCreds := expandRepositoryCredentials(d)
134+
repoCreds, err := expandRepositoryCredentials(d)
135+
if err != nil {
136+
return []diag.Diagnostic{
137+
{
138+
Severity: diag.Error,
139+
Summary: fmt.Sprintf("could not expand repository credential attributes: %s", err),
140+
Detail: err.Error(),
141+
},
142+
}
143+
}
126144

127145
tokenMutexConfiguration.Lock()
128146
r, err := c.UpdateRepositoryCredentials(

argocd/resource_argocd_repository_credentials_test.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,44 @@ func TestAccArgoCDRepositoryCredentials(t *testing.T) {
5151
})
5252
}
5353

54+
func TestAccArgoCDRepositoryCredentials_GitHubApp(t *testing.T) {
55+
sshPrivateKey, err := generateSSHPrivateKey()
56+
assert.NoError(t, err)
57+
58+
resource.Test(t, resource.TestCase{
59+
PreCheck: func() { testAccPreCheck(t) },
60+
ProviderFactories: testAccProviders,
61+
Steps: []resource.TestStep{
62+
{
63+
Config: testAccArgoCDRepositoryCredentialsGitHubApp(
64+
"https://private-git-repository.argocd.svc.cluster.local/project-1.git",
65+
"123456",
66+
"987654321",
67+
"https://ghe.example.com/api/v3",
68+
sshPrivateKey,
69+
),
70+
Check: resource.ComposeAggregateTestCheckFunc(
71+
resource.TestCheckResourceAttr(
72+
"argocd_repository_credentials.githubapp",
73+
"githubapp_id",
74+
"123456",
75+
),
76+
resource.TestCheckResourceAttr(
77+
"argocd_repository_credentials.githubapp",
78+
"githubapp_installation_id",
79+
"987654321",
80+
),
81+
resource.TestCheckResourceAttr(
82+
"argocd_repository_credentials.githubapp",
83+
"githubapp_enterprise_base_url",
84+
"https://ghe.example.com/api/v3",
85+
),
86+
),
87+
},
88+
},
89+
})
90+
}
91+
5492
func testAccArgoCDRepositoryCredentialsSimple(repoUrl, username, sshPrivateKey string) string {
5593
return fmt.Sprintf(`
5694
resource "argocd_repository_credentials" "simple" {
@@ -80,6 +118,20 @@ resource "argocd_repository_credentials" "private" {
80118
`)
81119
}
82120

121+
func testAccArgoCDRepositoryCredentialsGitHubApp(repoUrl, id, installID, enterpriseBaseURL, appKey string) string {
122+
return fmt.Sprintf(`
123+
resource "argocd_repository_credentials" "githubapp" {
124+
url = "%s"
125+
githubapp_id = "%s"
126+
githubapp_installation_id = "%s"
127+
githubapp_enterprise_base_url = "%s"
128+
githubapp_private_key = <<EOT
129+
%s
130+
EOT
131+
}
132+
`, repoUrl, id, installID, enterpriseBaseURL, appKey)
133+
}
134+
83135
func generateSSHPrivateKey() (privateKey string, err error) {
84136
pk, err := rsa.GenerateKey(rand.Reader, 2048)
85137
if err != nil {

argocd/resource_argocd_repository_test.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
99
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
1010
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
11+
"github.com/stretchr/testify/assert"
1112
)
1213

1314
func TestAccArgoCDRepository(t *testing.T) {
@@ -136,6 +137,44 @@ func TestAccArgoCDRepositoryScoped_NotSupported_On_OlderVersions(t *testing.T) {
136137
})
137138
}
138139

140+
func TestAccArgoCDRepository_GitHubApp(t *testing.T) {
141+
sshPrivateKey, err := generateSSHPrivateKey()
142+
assert.NoError(t, err)
143+
144+
resource.Test(t, resource.TestCase{
145+
PreCheck: func() { testAccPreCheck(t) },
146+
ProviderFactories: testAccProviders,
147+
Steps: []resource.TestStep{
148+
{
149+
Config: testAccArgoCDRepositoryGitHubApp(
150+
"https://private-git-repository.argocd.svc.cluster.local/project-1.git",
151+
"123456",
152+
"987654321",
153+
"https://ghe.example.com/api/v3",
154+
sshPrivateKey,
155+
),
156+
Check: resource.ComposeAggregateTestCheckFunc(
157+
resource.TestCheckResourceAttr(
158+
"argocd_repository.githubapp",
159+
"githubapp_id",
160+
"123456",
161+
),
162+
resource.TestCheckResourceAttr(
163+
"argocd_repository.githubapp",
164+
"githubapp_installation_id",
165+
"987654321",
166+
),
167+
resource.TestCheckResourceAttr(
168+
"argocd_repository.githubapp",
169+
"githubapp_enterprise_base_url",
170+
"https://ghe.example.com/api/v3",
171+
),
172+
),
173+
},
174+
},
175+
})
176+
}
177+
139178
func testAccArgoCDRepositorySimple() string {
140179
return fmt.Sprintf(`
141180
resource "argocd_repository" "simple" {
@@ -227,6 +266,21 @@ resource "argocd_repository" "private" {
227266
`, repoCount)
228267
}
229268

269+
func testAccArgoCDRepositoryGitHubApp(repoUrl, id, installID, baseURL, appKey string) string {
270+
return fmt.Sprintf(`
271+
resource "argocd_repository" "githubapp" {
272+
project = "default"
273+
repo = "%s"
274+
githubapp_id = "%s"
275+
githubapp_installation_id = "%s"
276+
githubapp_enterprise_base_url = "%s"
277+
githubapp_private_key = <<EOT
278+
%s
279+
EOT
280+
}
281+
`, repoUrl, id, installID, baseURL, appKey)
282+
}
283+
230284
func testCheckMultipleResourceAttr(name, key, value string, count int) resource.TestCheckFunc {
231285
return func(s *terraform.State) error {
232286
for i := 0; i < count; i++ {

argocd/schema_repository.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,5 +92,29 @@ func repositorySchema() map[string]*schema.Schema {
9292
Type: schema.TypeString,
9393
Computed: true,
9494
},
95+
"githubapp_id": {
96+
Type: schema.TypeString,
97+
Description: "GitHub App id for authenticating at the repo server only for GitHub repos",
98+
ValidateFunc: validatePositiveInteger,
99+
Optional: true,
100+
},
101+
"githubapp_installation_id": {
102+
Type: schema.TypeString,
103+
Description: "GitHub App installation id for authenticating at the repo server only for GitHub repos",
104+
ValidateFunc: validatePositiveInteger,
105+
Optional: true,
106+
},
107+
"githubapp_enterprise_base_url": {
108+
Type: schema.TypeString,
109+
Description: "If using GitHub App for a GitHub Enterprise repository the host url is required",
110+
Optional: true,
111+
},
112+
"githubapp_private_key": {
113+
Type: schema.TypeString,
114+
Sensitive: true,
115+
Description: "Private key data (pem) of GitHub App for authenticating at the repo server only for GitHub repos",
116+
ValidateFunc: validateSSHPrivateKey,
117+
Optional: true,
118+
},
95119
}
96120
}

argocd/schema_repository_credentials.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,5 +47,29 @@ func repositoryCredentialsSchema() map[string]*schema.Schema {
4747
Description: "Specify whether the repo server should be viewed as OCI compliant",
4848
Optional: true,
4949
},
50+
"githubapp_id": {
51+
Type: schema.TypeString,
52+
Description: "GitHub App id for authenticating at the repo server only for GitHub repos",
53+
ValidateFunc: validatePositiveInteger,
54+
Optional: true,
55+
},
56+
"githubapp_installation_id": {
57+
Type: schema.TypeString,
58+
Description: "GitHub App installation id for authenticating at the repo server only for GitHub repos",
59+
ValidateFunc: validatePositiveInteger,
60+
Optional: true,
61+
},
62+
"githubapp_enterprise_base_url": {
63+
Type: schema.TypeString,
64+
Description: "If using GitHub App for a GitHub Enterprise repository the host url is required",
65+
Optional: true,
66+
},
67+
"githubapp_private_key": {
68+
Type: schema.TypeString,
69+
Sensitive: true,
70+
Description: "Private key data (pem) of GitHub App for authenticating at the repo server only for GitHub repos",
71+
ValidateFunc: validateSSHPrivateKey,
72+
Optional: true,
73+
},
5074
}
5175
}

argocd/structure_repository.go

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ import (
88

99
// Expand
1010

11-
func expandRepository(d *schema.ResourceData) *application.Repository {
11+
func expandRepository(d *schema.ResourceData) (*application.Repository, error) {
12+
var err error
13+
1214
repository := &application.Repository{}
1315
if v, ok := d.GetOk("repo"); ok {
1416
repository.Repo = v.(string)
@@ -49,7 +51,25 @@ func expandRepository(d *schema.ResourceData) *application.Repository {
4951
if v, ok := d.GetOk("type"); ok {
5052
repository.Type = v.(string)
5153
}
52-
return repository
54+
if v, ok := d.GetOk("githubapp_id"); ok {
55+
repository.GithubAppId, err = convertStringToInt64(v.(string))
56+
if err != nil {
57+
return nil, err
58+
}
59+
}
60+
if v, ok := d.GetOk("githubapp_installation_id"); ok {
61+
repository.GithubAppInstallationId, err = convertStringToInt64(v.(string))
62+
if err != nil {
63+
return nil, err
64+
}
65+
}
66+
if v, ok := d.GetOk("githubapp_enterprise_base_url"); ok {
67+
repository.GitHubAppEnterpriseBaseURL = v.(string)
68+
}
69+
if v, ok := d.GetOk("githubapp_private_key"); ok {
70+
repository.GithubAppPrivateKey = v.(string)
71+
}
72+
return repository, nil
5373
}
5474

5575
// Flatten
@@ -64,13 +84,20 @@ func flattenRepository(repository *application.Repository, d *schema.ResourceDat
6484
"name": repository.Name,
6585
"project": repository.Project,
6686
// TODO: in case of repositoryCredentials existence, will perma-diff
67-
//"username": repository.Username,
87+
//"username": repository.Username,
6888
// TODO: ArgoCD API does not return sensitive data!
69-
//"password": repository.Password,
70-
//"ssh_private_key": repository.SSHPrivateKey,
71-
//"tls_client_cert_key": repository.TLSClientCertKey,
72-
"tls_client_cert_data": repository.TLSClientCertData,
73-
"type": repository.Type,
89+
//"password": repository.Password,
90+
//"ssh_private_key": repository.SSHPrivateKey,
91+
//"tls_client_cert_key": repository.TLSClientCertKey,
92+
"tls_client_cert_data": repository.TLSClientCertData,
93+
"type": repository.Type,
94+
"githubapp_enterprise_base_url": repository.GitHubAppEnterpriseBaseURL,
95+
}
96+
if repository.GithubAppId > 0 {
97+
r["githubapp_id"] = convertInt64ToString(repository.GithubAppId)
98+
}
99+
if repository.GithubAppInstallationId > 0 {
100+
r["githubapp_installation_id"] = convertInt64ToString(repository.GithubAppInstallationId)
74101
}
75102
for k, v := range r {
76103
if err := persistToState(k, v, d); err != nil {

0 commit comments

Comments
 (0)