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

Add compatiblity for "source_namespaces" introduced in ArgoCD v2.5.0 #212

Merged
merged 30 commits into from
Dec 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
55ec616
add source_namespaces
karlschriek Oct 26, 2022
7720ec2
update pinned k8s.io versions
karlschriek Oct 26, 2022
c58c3fe
set: github.com/argoproj/gitops-engine => github.com/argoproj/gitops-…
karlschriek Oct 26, 2022
cd6b3b4
Add reference to issue
karlschriek Oct 26, 2022
5dd1703
Add additional tests, update test environment, update test instructio…
karlschriek Oct 26, 2022
d582f9b
remove source_namespaces from schemas V0 and V1
karlschriek Oct 27, 2022
a03263f
Add "AppNamespace" find to application queries
karlschriek Oct 27, 2022
560010d
Prepare an env that can test "application namespaces" feature
karlschriek Oct 27, 2022
5858bfa
Add "application namespaces" acceptance tests
karlschriek Oct 27, 2022
5e18651
Set argocd_version to 2.5.0 in automated tests
karlschriek Oct 27, 2022
1a011ff
Run "Application" acceptance tests against "test" AppProject
karlschriek Oct 27, 2022
6644683
bump go version to 1.19
karlschriek Oct 27, 2022
652b647
Bump go version on release pipeline
karlschriek Oct 27, 2022
bfa8829
Add older versions back into acceptane testing pipeline
karlschriek Oct 27, 2022
0119016
separate testdata for pre and post v2.5.0
karlschriek Oct 27, 2022
7814630
make a dedicated "testAccArgoCDProjectSimpleWithSourceNamespaces" test
karlschriek Oct 27, 2022
21e8a56
Fixes to argocd project changes
onematchfox Nov 11, 2022
fc8e480
Revert "separate testdata for pre and post v2.5.0"
karlschriek Oct 27, 2022
c25f806
Revert "Run "Application" acceptance tests against "test" AppProject"
karlschriek Oct 27, 2022
0d3710c
Revert "Add "application namespaces" acceptance tests"
karlschriek Oct 27, 2022
3dad704
Revert changes to `token_resource`
onematchfox Nov 22, 2022
bf95569
Patch default installation to support deployment of apps to specific …
onematchfox Nov 11, 2022
01a5720
Format application + tests
onematchfox Nov 22, 2022
3d84814
Add test deploying application to custom namespace
onematchfox Nov 22, 2022
67fbfe8
Use composite ID for ArgoCD applications
onematchfox Nov 22, 2022
13b3c39
Format test resource
onematchfox Nov 28, 2022
24699df
Fix typo in error message
onematchfox Nov 30, 2022
67def9c
Use `TypeSet ` instead of `List` for project `source_namespaces`
onematchfox Nov 30, 2022
255b2b7
Simplify `applicationSpecSchemaV3`
onematchfox Dec 6, 2022
a8a0362
Ensure test resources are created in correct order
onematchfox Dec 11, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
- name: Set up Go
uses: actions/setup-go@v2
with:
go-version: 1.17
go-version: 1.19

- name: Import GPG key
id: import_gpg
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ jobs:
strategy:
fail-fast: false
matrix:
argocd_version: ["v2.4.12", "v2.3.9"]
argocd_version: ["v2.5.0", "v2.4.12", "v2.3.9"]
steps:
- uses: actions/checkout@v2
- uses: actions/setup-go@v1
with:
go-version: 1.17
go-version: 1.19
id: go
- name: Restore Go cache
uses: actions/cache@v1
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -363,10 +363,10 @@ make testacc_clean_env

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

#### Troubleshooting during local development
Expand Down
2 changes: 2 additions & 0 deletions argocd/features.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const (
featureRepositoryCertificates
featureApplicationHelmSkipCrds
featureExecLogsPolicy
featureProjectSourceNamespaces
)

var featureVersionConstraintsMap = map[int]*semver.Version{
Expand All @@ -41,6 +42,7 @@ var featureVersionConstraintsMap = map[int]*semver.Version{
featureRepositoryCertificates: semver.MustParse("1.2.0"),
featureApplicationHelmSkipCrds: semver.MustParse("2.3.0"),
featureExecLogsPolicy: semver.MustParse("2.4.0"),
featureProjectSourceNamespaces: semver.MustParse("2.5.0"),
}

type ServerInterface struct {
Expand Down
52 changes: 37 additions & 15 deletions argocd/resource_argocd_application.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func resourceArgoCDApplication() *schema.Resource {
},
Schema: map[string]*schema.Schema{
"metadata": metadataSchema("applications.argoproj.io"),
"spec": applicationSpecSchemaV2(),
"spec": applicationSpecSchemaV3(),
"wait": {
Type: schema.TypeBool,
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.",
Expand All @@ -41,7 +41,7 @@ func resourceArgoCDApplication() *schema.Resource {
Default: true,
},
},
SchemaVersion: 2,
SchemaVersion: 3,
StateUpgraders: []schema.StateUpgrader{
{
Type: resourceArgoCDApplicationV0().CoreConfigSchema().ImpliedType(),
Expand All @@ -53,6 +53,11 @@ func resourceArgoCDApplication() *schema.Resource {
Upgrade: resourceArgoCDApplicationStateUpgradeV1,
Version: 1,
},
{
Type: resourceArgoCDApplicationV2().CoreConfigSchema().ImpliedType(),
Upgrade: resourceArgoCDApplicationStateUpgradeV2,
Version: 2,
},
},
Timeouts: &schema.ResourceTimeout{
Create: schema.DefaultTimeout(5 * time.Minute),
Expand All @@ -79,7 +84,8 @@ func resourceArgoCDApplicationCreate(ctx context.Context, d *schema.ResourceData
}
c := *server.ApplicationClient
app, err := c.Get(ctx, &applicationClient.ApplicationQuery{
Name: &objectMeta.Name,
Name: &objectMeta.Name,
AppNamespace: &objectMeta.Namespace,
})
if err != nil && !strings.Contains(err.Error(), "NotFound") {
return []diag.Diagnostic{
Expand Down Expand Up @@ -205,11 +211,14 @@ func resourceArgoCDApplicationCreate(ctx context.Context, d *schema.ResourceData
},
}
}
d.SetId(app.Name)

d.SetId(fmt.Sprintf("%s:%s", app.Name, objectMeta.Namespace))

if wait, ok := d.GetOk("wait"); ok && wait.(bool) {
err = resource.RetryContext(ctx, d.Timeout(schema.TimeoutCreate), func() *resource.RetryError {
a, err := c.Get(ctx, &applicationClient.ApplicationQuery{
Name: &app.Name,
Name: &app.Name,
AppNamespace: &app.Namespace,
})
if err != nil {
return resource.NonRetryableError(fmt.Errorf("error while waiting for application %s to be synced and healthy: %s", app.Name, err))
Expand Down Expand Up @@ -246,10 +255,16 @@ func resourceArgoCDApplicationRead(ctx context.Context, d *schema.ResourceData,
},
}
}

c := *server.ApplicationClient
appName := d.Id()

ids := strings.Split(d.Id(), ":")
appName := ids[0]
namespace := ids[1]

app, err := c.Get(ctx, &applicationClient.ApplicationQuery{
Name: &appName,
Name: &appName,
AppNamespace: &namespace,
})
if err != nil {
if strings.Contains(err.Error(), "NotFound") {
Expand Down Expand Up @@ -278,7 +293,9 @@ func resourceArgoCDApplicationRead(ctx context.Context, d *schema.ResourceData,
}

func resourceArgoCDApplicationUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
appName := d.Id()
ids := strings.Split(d.Id(), ":")
appName := ids[0]
namespace := ids[1]
if ok := d.HasChanges("metadata", "spec"); ok {
objectMeta, spec, diags := expandApplication(d)
if diags != nil {
Expand Down Expand Up @@ -384,9 +401,9 @@ func resourceArgoCDApplicationUpdate(ctx context.Context, d *schema.ResourceData
}
}
}

app, err := c.Get(ctx, &applicationClient.ApplicationQuery{
Name: &appName,
Name: &appName,
AppNamespace: &namespace,
})
if app != nil {
// Kubernetes API requires providing the up-to-date correct ResourceVersion for updates
Expand All @@ -406,7 +423,8 @@ func resourceArgoCDApplicationUpdate(ctx context.Context, d *schema.ResourceData
if wait, _ok := d.GetOk("wait"); _ok && wait.(bool) {
err = resource.RetryContext(ctx, d.Timeout(schema.TimeoutUpdate), func() *resource.RetryError {
a, err := c.Get(ctx, &applicationClient.ApplicationQuery{
Name: &app.Name,
Name: &app.Name,
AppNamespace: &app.Namespace,
})
if err != nil {
return resource.NonRetryableError(fmt.Errorf("error while waiting for application %s to be synced and healthy: %s", app.Name, err))
Expand Down Expand Up @@ -445,11 +463,14 @@ func resourceArgoCDApplicationDelete(ctx context.Context, d *schema.ResourceData
}
}
c := *server.ApplicationClient
appName := d.Id()
ids := strings.Split(d.Id(), ":")
appName := ids[0]
namespace := ids[1]
cascade := d.Get("cascade").(bool)
_, err := c.Delete(ctx, &applicationClient.ApplicationDeleteRequest{
Name: &appName,
Cascade: &cascade,
Name: &appName,
Cascade: &cascade,
AppNamespace: &namespace,
})
if err != nil && !strings.Contains(err.Error(), "NotFound") {
return []diag.Diagnostic{
Expand All @@ -463,7 +484,8 @@ func resourceArgoCDApplicationDelete(ctx context.Context, d *schema.ResourceData
if wait, ok := d.GetOk("wait"); ok && wait.(bool) {
err = resource.RetryContext(ctx, d.Timeout(schema.TimeoutDelete), func() *resource.RetryError {
_, err := c.Get(ctx, &applicationClient.ApplicationQuery{
Name: &appName,
Name: &appName,
AppNamespace: &namespace,
})
if err == nil {
return resource.RetryableError(fmt.Errorf("application %s is still present", appName))
Expand Down
107 changes: 98 additions & 9 deletions argocd/resource_argocd_application_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,8 @@ func TestAccArgoCDApplication_NoSyncPolicyBlock(t *testing.T) {
),
),
},
}})
},
})
}

func TestAccArgoCDApplication_Recurse(t *testing.T) {
Expand Down Expand Up @@ -419,7 +420,8 @@ func TestAccArgoCDApplication_Recurse(t *testing.T) {
),
),
},
}})
},
})
}

func TestAccArgoCDApplication_EmptySyncPolicyBlock(t *testing.T) {
Expand All @@ -444,7 +446,8 @@ func TestAccArgoCDApplication_EmptySyncPolicyBlock(t *testing.T) {
),
),
},
}})
},
})
}

func TestAccArgoCDApplication_NoAutomatedBlock(t *testing.T) {
Expand All @@ -469,7 +472,8 @@ func TestAccArgoCDApplication_NoAutomatedBlock(t *testing.T) {
),
),
},
}})
},
})
}

func TestAccArgoCDApplication_EmptyAutomatedBlock(t *testing.T) {
Expand All @@ -490,7 +494,8 @@ func TestAccArgoCDApplication_EmptyAutomatedBlock(t *testing.T) {
),
),
},
}})
},
})
}

func TestAccArgoCDApplication_OptionalPath(t *testing.T) {
Expand Down Expand Up @@ -542,7 +547,8 @@ func TestAccArgoCDApplication_OptionalPath(t *testing.T) {
),
),
},
}})
},
})
}

func TestAccArgoCDApplication_Info(t *testing.T) {
Expand Down Expand Up @@ -657,7 +663,8 @@ func TestAccArgoCDApplication_Info(t *testing.T) {
),
),
},
}})
},
})
}

func TestProvider_headers(t *testing.T) {
Expand Down Expand Up @@ -746,7 +753,8 @@ func TestAccArgoCDApplication_SkipCrds_NotSupported_On_OlderVersions(t *testing.
),
),
},
}})
},
})
}

func TestAccArgoCDApplication_SkipCrds(t *testing.T) {
Expand Down Expand Up @@ -798,7 +806,34 @@ func TestAccArgoCDApplication_SkipCrds(t *testing.T) {
),
),
},
}})
},
})
}

func TestAccArgoCDApplication_CustomNamespace(t *testing.T) {
name := acctest.RandomWithPrefix("test-acc-custom-namespace")

resource.ParallelTest(t, resource.TestCase{
PreCheck: func() { testAccPreCheck(t); testAccPreCheckFeatureSupported(t, featureProjectSourceNamespaces) },
ProviderFactories: testAccProviders,
Steps: []resource.TestStep{
{
Config: testAccArgoCDApplicationCustomNamespace(name),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet(
"argocd_application.simple",
"metadata.0.uid",
),
),
},
{
ResourceName: "argocd_application.simple",
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"wait", "cascade"},
},
},
})
}

func testAccArgoCDApplicationSimple(name string) string {
Expand Down Expand Up @@ -1659,6 +1694,60 @@ resource "argocd_application" "crds" {
`, name)
}

func testAccArgoCDApplicationCustomNamespace(name string) string {
return fmt.Sprintf(`
resource "argocd_project" "simple" {
metadata {
name = "%[1]s"
oboukili marked this conversation as resolved.
Show resolved Hide resolved
namespace = "argocd"
}

spec {
description = "project with source namespace"
source_repos = ["*"]
source_namespaces = ["mynamespace-1"]

destination {
server = "https://kubernetes.default.svc"
namespace = "default"
}
}
}

resource "argocd_application" "simple" {
metadata {
name = "%[1]s"
oboukili marked this conversation as resolved.
Show resolved Hide resolved
namespace = "mynamespace-1"
}

spec {
project = argocd_project.simple.metadata[0].name
source {
repo_url = "https://charts.bitnami.com/bitnami"
chart = "redis"
target_revision = "16.9.11"
helm {
parameter {
name = "image.tag"
value = "6.2.5"
}
parameter {
name = "architecture"
value = "standalone"
}
release_name = "testing"
}
}

destination {
server = "https://kubernetes.default.svc"
namespace = "default"
}
}
}
`, name)
}

func testAccSkipFeatureIgnoreDiffJQPathExpressions() (bool, error) {
p, _ := testAccProviders["argocd"]()
_ = p.Configure(context.Background(), &terraform.ResourceConfig{})
Expand Down
24 changes: 24 additions & 0 deletions argocd/resource_argocd_project.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,30 @@ func resourceArgoCDProjectCreate(ctx context.Context, d *schema.ResourceData, me
}
}

featureProjectSourceNamespacesSupported, err := server.isFeatureSupported(featureProjectSourceNamespaces)
if err != nil {
return []diag.Diagnostic{
{
Severity: diag.Error,
Summary: "feature not supported",
Detail: err.Error(),
},
}
}
if !featureProjectSourceNamespacesSupported {
_, sourceNamespacesOk := d.GetOk("spec.0.source_namespaces")
if sourceNamespacesOk {
return []diag.Diagnostic{
{
Severity: diag.Error,
Summary: fmt.Sprintf(
"project source_namespaces is only supported from ArgoCD %s onwards",
featureVersionConstraintsMap[featureProjectSourceNamespaces].String()),
},
}
}
}

tokenMutexProjectMap[projectName].Lock()
p, err = c.Create(ctx, &projectClient.ProjectCreateRequest{
Project: &application.AppProject{
Expand Down
Loading