Skip to content

Commit bf3c417

Browse files
karlschriekonematchfoxoboukili
authored
Add compatiblity for "source_namespaces" introduced in ArgoCD v2.5.0 (#212)
* add source_namespaces * update pinned k8s.io versions * set: github.com/argoproj/gitops-engine => github.com/argoproj/gitops-engine v0.7.1-0.20220804190909-2bc3fef13e07 * Add reference to issue * Add additional tests, update test environment, update test instructions in README * remove source_namespaces from schemas V0 and V1 * Add "AppNamespace" find to application queries * Prepare an env that can test "application namespaces" feature * Add "application namespaces" acceptance tests * Set argocd_version to 2.5.0 in automated tests * Run "Application" acceptance tests against "test" AppProject * bump go version to 1.19 * Bump go version on release pipeline * Add older versions back into acceptane testing pipeline * separate testdata for pre and post v2.5.0 * make a dedicated "testAccArgoCDProjectSimpleWithSourceNamespaces" test * Fixes to argocd project changes - Mark source_namespaces as Optional - Add feature/version constraint - Add test for project with source namespaces * Revert "separate testdata for pre and post v2.5.0" This reverts commit 0119016. * Revert "Run "Application" acceptance tests against "test" AppProject" This reverts commit 1a011ff. * Revert "Add "application namespaces" acceptance tests" This reverts commit 5858bfa. * Revert changes to `token_resource` * Patch default installation to support deployment of apps to specific namespace * Format application + tests * Add test deploying application to custom namespace * Use composite ID for ArgoCD applications To be able to import existing resources in custom namespaces we need to store the namespace as part of the ID on the ArgoCD application resource. * Format test resource * Fix typo in error message Co-authored-by: Olivier Boukili <[email protected]> * Use `TypeSet ` instead of `List` for project `source_namespaces` * Simplify `applicationSpecSchemaV3` Schema for `application.spec` has not changed. * Ensure test resources are created in correct order Co-authored-by: Brian Fox <[email protected]> Co-authored-by: Olivier Boukili <[email protected]>
1 parent 47115ea commit bf3c417

20 files changed

+584
-292
lines changed

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ jobs:
1717
- name: Set up Go
1818
uses: actions/setup-go@v2
1919
with:
20-
go-version: 1.17
20+
go-version: 1.19
2121

2222
- name: Import GPG key
2323
id: import_gpg

.github/workflows/tests.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@ jobs:
1414
strategy:
1515
fail-fast: false
1616
matrix:
17-
argocd_version: ["v2.4.12", "v2.3.9"]
17+
argocd_version: ["v2.5.0", "v2.4.12", "v2.3.9"]
1818
steps:
1919
- uses: actions/checkout@v2
2020
- uses: actions/setup-go@v1
2121
with:
22-
go-version: 1.17
22+
go-version: 1.19
2323
id: go
2424
- name: Restore Go cache
2525
uses: actions/cache@v1

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -363,10 +363,10 @@ make testacc_clean_env
363363

364364
For example if you use Docker as your local container runtime:
365365
```shell
366-
docker pull argoproj/argocd:v1.8.3
366+
docker pull quay.io/argoproj/argocd:v2.5.0
367367
docker pull ghcr.io/dexidp/dex:v2.27.0
368368
docker pull redis:6.2.4-alpine
369-
docker pull bitnami/redis:6.2.5
369+
docker pull alpine:3
370370
```
371371

372372
#### Troubleshooting during local development

argocd/features.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ const (
2929
featureRepositoryCertificates
3030
featureApplicationHelmSkipCrds
3131
featureExecLogsPolicy
32+
featureProjectSourceNamespaces
3233
)
3334

3435
var featureVersionConstraintsMap = map[int]*semver.Version{
@@ -41,6 +42,7 @@ var featureVersionConstraintsMap = map[int]*semver.Version{
4142
featureRepositoryCertificates: semver.MustParse("1.2.0"),
4243
featureApplicationHelmSkipCrds: semver.MustParse("2.3.0"),
4344
featureExecLogsPolicy: semver.MustParse("2.4.0"),
45+
featureProjectSourceNamespaces: semver.MustParse("2.5.0"),
4446
}
4547

4648
type ServerInterface struct {

argocd/resource_argocd_application.go

Lines changed: 37 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ func resourceArgoCDApplication() *schema.Resource {
2727
},
2828
Schema: map[string]*schema.Schema{
2929
"metadata": metadataSchema("applications.argoproj.io"),
30-
"spec": applicationSpecSchemaV2(),
30+
"spec": applicationSpecSchemaV3(),
3131
"wait": {
3232
Type: schema.TypeBool,
3333
Description: "Upon application creation or update, wait for application health/sync status to be healthy/Synced, upon application deletion, wait for application to be removed, when set to true.",
@@ -41,7 +41,7 @@ func resourceArgoCDApplication() *schema.Resource {
4141
Default: true,
4242
},
4343
},
44-
SchemaVersion: 2,
44+
SchemaVersion: 3,
4545
StateUpgraders: []schema.StateUpgrader{
4646
{
4747
Type: resourceArgoCDApplicationV0().CoreConfigSchema().ImpliedType(),
@@ -53,6 +53,11 @@ func resourceArgoCDApplication() *schema.Resource {
5353
Upgrade: resourceArgoCDApplicationStateUpgradeV1,
5454
Version: 1,
5555
},
56+
{
57+
Type: resourceArgoCDApplicationV2().CoreConfigSchema().ImpliedType(),
58+
Upgrade: resourceArgoCDApplicationStateUpgradeV2,
59+
Version: 2,
60+
},
5661
},
5762
Timeouts: &schema.ResourceTimeout{
5863
Create: schema.DefaultTimeout(5 * time.Minute),
@@ -79,7 +84,8 @@ func resourceArgoCDApplicationCreate(ctx context.Context, d *schema.ResourceData
7984
}
8085
c := *server.ApplicationClient
8186
app, err := c.Get(ctx, &applicationClient.ApplicationQuery{
82-
Name: &objectMeta.Name,
87+
Name: &objectMeta.Name,
88+
AppNamespace: &objectMeta.Namespace,
8389
})
8490
if err != nil && !strings.Contains(err.Error(), "NotFound") {
8591
return []diag.Diagnostic{
@@ -205,11 +211,14 @@ func resourceArgoCDApplicationCreate(ctx context.Context, d *schema.ResourceData
205211
},
206212
}
207213
}
208-
d.SetId(app.Name)
214+
215+
d.SetId(fmt.Sprintf("%s:%s", app.Name, objectMeta.Namespace))
216+
209217
if wait, ok := d.GetOk("wait"); ok && wait.(bool) {
210218
err = resource.RetryContext(ctx, d.Timeout(schema.TimeoutCreate), func() *resource.RetryError {
211219
a, err := c.Get(ctx, &applicationClient.ApplicationQuery{
212-
Name: &app.Name,
220+
Name: &app.Name,
221+
AppNamespace: &app.Namespace,
213222
})
214223
if err != nil {
215224
return resource.NonRetryableError(fmt.Errorf("error while waiting for application %s to be synced and healthy: %s", app.Name, err))
@@ -246,10 +255,16 @@ func resourceArgoCDApplicationRead(ctx context.Context, d *schema.ResourceData,
246255
},
247256
}
248257
}
258+
249259
c := *server.ApplicationClient
250-
appName := d.Id()
260+
261+
ids := strings.Split(d.Id(), ":")
262+
appName := ids[0]
263+
namespace := ids[1]
264+
251265
app, err := c.Get(ctx, &applicationClient.ApplicationQuery{
252-
Name: &appName,
266+
Name: &appName,
267+
AppNamespace: &namespace,
253268
})
254269
if err != nil {
255270
if strings.Contains(err.Error(), "NotFound") {
@@ -278,7 +293,9 @@ func resourceArgoCDApplicationRead(ctx context.Context, d *schema.ResourceData,
278293
}
279294

280295
func resourceArgoCDApplicationUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
281-
appName := d.Id()
296+
ids := strings.Split(d.Id(), ":")
297+
appName := ids[0]
298+
namespace := ids[1]
282299
if ok := d.HasChanges("metadata", "spec"); ok {
283300
objectMeta, spec, diags := expandApplication(d)
284301
if diags != nil {
@@ -384,9 +401,9 @@ func resourceArgoCDApplicationUpdate(ctx context.Context, d *schema.ResourceData
384401
}
385402
}
386403
}
387-
388404
app, err := c.Get(ctx, &applicationClient.ApplicationQuery{
389-
Name: &appName,
405+
Name: &appName,
406+
AppNamespace: &namespace,
390407
})
391408
if app != nil {
392409
// Kubernetes API requires providing the up-to-date correct ResourceVersion for updates
@@ -406,7 +423,8 @@ func resourceArgoCDApplicationUpdate(ctx context.Context, d *schema.ResourceData
406423
if wait, _ok := d.GetOk("wait"); _ok && wait.(bool) {
407424
err = resource.RetryContext(ctx, d.Timeout(schema.TimeoutUpdate), func() *resource.RetryError {
408425
a, err := c.Get(ctx, &applicationClient.ApplicationQuery{
409-
Name: &app.Name,
426+
Name: &app.Name,
427+
AppNamespace: &app.Namespace,
410428
})
411429
if err != nil {
412430
return resource.NonRetryableError(fmt.Errorf("error while waiting for application %s to be synced and healthy: %s", app.Name, err))
@@ -445,11 +463,14 @@ func resourceArgoCDApplicationDelete(ctx context.Context, d *schema.ResourceData
445463
}
446464
}
447465
c := *server.ApplicationClient
448-
appName := d.Id()
466+
ids := strings.Split(d.Id(), ":")
467+
appName := ids[0]
468+
namespace := ids[1]
449469
cascade := d.Get("cascade").(bool)
450470
_, err := c.Delete(ctx, &applicationClient.ApplicationDeleteRequest{
451-
Name: &appName,
452-
Cascade: &cascade,
471+
Name: &appName,
472+
Cascade: &cascade,
473+
AppNamespace: &namespace,
453474
})
454475
if err != nil && !strings.Contains(err.Error(), "NotFound") {
455476
return []diag.Diagnostic{
@@ -463,7 +484,8 @@ func resourceArgoCDApplicationDelete(ctx context.Context, d *schema.ResourceData
463484
if wait, ok := d.GetOk("wait"); ok && wait.(bool) {
464485
err = resource.RetryContext(ctx, d.Timeout(schema.TimeoutDelete), func() *resource.RetryError {
465486
_, err := c.Get(ctx, &applicationClient.ApplicationQuery{
466-
Name: &appName,
487+
Name: &appName,
488+
AppNamespace: &namespace,
467489
})
468490
if err == nil {
469491
return resource.RetryableError(fmt.Errorf("application %s is still present", appName))

argocd/resource_argocd_application_test.go

Lines changed: 98 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,8 @@ func TestAccArgoCDApplication_NoSyncPolicyBlock(t *testing.T) {
340340
),
341341
),
342342
},
343-
}})
343+
},
344+
})
344345
}
345346

346347
func TestAccArgoCDApplication_Recurse(t *testing.T) {
@@ -419,7 +420,8 @@ func TestAccArgoCDApplication_Recurse(t *testing.T) {
419420
),
420421
),
421422
},
422-
}})
423+
},
424+
})
423425
}
424426

425427
func TestAccArgoCDApplication_EmptySyncPolicyBlock(t *testing.T) {
@@ -444,7 +446,8 @@ func TestAccArgoCDApplication_EmptySyncPolicyBlock(t *testing.T) {
444446
),
445447
),
446448
},
447-
}})
449+
},
450+
})
448451
}
449452

450453
func TestAccArgoCDApplication_NoAutomatedBlock(t *testing.T) {
@@ -469,7 +472,8 @@ func TestAccArgoCDApplication_NoAutomatedBlock(t *testing.T) {
469472
),
470473
),
471474
},
472-
}})
475+
},
476+
})
473477
}
474478

475479
func TestAccArgoCDApplication_EmptyAutomatedBlock(t *testing.T) {
@@ -490,7 +494,8 @@ func TestAccArgoCDApplication_EmptyAutomatedBlock(t *testing.T) {
490494
),
491495
),
492496
},
493-
}})
497+
},
498+
})
494499
}
495500

496501
func TestAccArgoCDApplication_OptionalPath(t *testing.T) {
@@ -542,7 +547,8 @@ func TestAccArgoCDApplication_OptionalPath(t *testing.T) {
542547
),
543548
),
544549
},
545-
}})
550+
},
551+
})
546552
}
547553

548554
func TestAccArgoCDApplication_Info(t *testing.T) {
@@ -657,7 +663,8 @@ func TestAccArgoCDApplication_Info(t *testing.T) {
657663
),
658664
),
659665
},
660-
}})
666+
},
667+
})
661668
}
662669

663670
func TestProvider_headers(t *testing.T) {
@@ -746,7 +753,8 @@ func TestAccArgoCDApplication_SkipCrds_NotSupported_On_OlderVersions(t *testing.
746753
),
747754
),
748755
},
749-
}})
756+
},
757+
})
750758
}
751759

752760
func TestAccArgoCDApplication_SkipCrds(t *testing.T) {
@@ -798,7 +806,34 @@ func TestAccArgoCDApplication_SkipCrds(t *testing.T) {
798806
),
799807
),
800808
},
801-
}})
809+
},
810+
})
811+
}
812+
813+
func TestAccArgoCDApplication_CustomNamespace(t *testing.T) {
814+
name := acctest.RandomWithPrefix("test-acc-custom-namespace")
815+
816+
resource.ParallelTest(t, resource.TestCase{
817+
PreCheck: func() { testAccPreCheck(t); testAccPreCheckFeatureSupported(t, featureProjectSourceNamespaces) },
818+
ProviderFactories: testAccProviders,
819+
Steps: []resource.TestStep{
820+
{
821+
Config: testAccArgoCDApplicationCustomNamespace(name),
822+
Check: resource.ComposeTestCheckFunc(
823+
resource.TestCheckResourceAttrSet(
824+
"argocd_application.simple",
825+
"metadata.0.uid",
826+
),
827+
),
828+
},
829+
{
830+
ResourceName: "argocd_application.simple",
831+
ImportState: true,
832+
ImportStateVerify: true,
833+
ImportStateVerifyIgnore: []string{"wait", "cascade"},
834+
},
835+
},
836+
})
802837
}
803838

804839
func testAccArgoCDApplicationSimple(name string) string {
@@ -1659,6 +1694,60 @@ resource "argocd_application" "crds" {
16591694
`, name)
16601695
}
16611696

1697+
func testAccArgoCDApplicationCustomNamespace(name string) string {
1698+
return fmt.Sprintf(`
1699+
resource "argocd_project" "simple" {
1700+
metadata {
1701+
name = "%[1]s"
1702+
namespace = "argocd"
1703+
}
1704+
1705+
spec {
1706+
description = "project with source namespace"
1707+
source_repos = ["*"]
1708+
source_namespaces = ["mynamespace-1"]
1709+
1710+
destination {
1711+
server = "https://kubernetes.default.svc"
1712+
namespace = "default"
1713+
}
1714+
}
1715+
}
1716+
1717+
resource "argocd_application" "simple" {
1718+
metadata {
1719+
name = "%[1]s"
1720+
namespace = "mynamespace-1"
1721+
}
1722+
1723+
spec {
1724+
project = argocd_project.simple.metadata[0].name
1725+
source {
1726+
repo_url = "https://charts.bitnami.com/bitnami"
1727+
chart = "redis"
1728+
target_revision = "16.9.11"
1729+
helm {
1730+
parameter {
1731+
name = "image.tag"
1732+
value = "6.2.5"
1733+
}
1734+
parameter {
1735+
name = "architecture"
1736+
value = "standalone"
1737+
}
1738+
release_name = "testing"
1739+
}
1740+
}
1741+
1742+
destination {
1743+
server = "https://kubernetes.default.svc"
1744+
namespace = "default"
1745+
}
1746+
}
1747+
}
1748+
`, name)
1749+
}
1750+
16621751
func testAccSkipFeatureIgnoreDiffJQPathExpressions() (bool, error) {
16631752
p, _ := testAccProviders["argocd"]()
16641753
_ = p.Configure(context.Background(), &terraform.ResourceConfig{})

argocd/resource_argocd_project.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,30 @@ func resourceArgoCDProjectCreate(ctx context.Context, d *schema.ResourceData, me
9595
}
9696
}
9797

98+
featureProjectSourceNamespacesSupported, err := server.isFeatureSupported(featureProjectSourceNamespaces)
99+
if err != nil {
100+
return []diag.Diagnostic{
101+
{
102+
Severity: diag.Error,
103+
Summary: "feature not supported",
104+
Detail: err.Error(),
105+
},
106+
}
107+
}
108+
if !featureProjectSourceNamespacesSupported {
109+
_, sourceNamespacesOk := d.GetOk("spec.0.source_namespaces")
110+
if sourceNamespacesOk {
111+
return []diag.Diagnostic{
112+
{
113+
Severity: diag.Error,
114+
Summary: fmt.Sprintf(
115+
"project source_namespaces is only supported from ArgoCD %s onwards",
116+
featureVersionConstraintsMap[featureProjectSourceNamespaces].String()),
117+
},
118+
}
119+
}
120+
}
121+
98122
tokenMutexProjectMap[projectName].Lock()
99123
p, err = c.Create(ctx, &projectClient.ProjectCreateRequest{
100124
Project: &application.AppProject{

0 commit comments

Comments
 (0)