Skip to content

Commit

Permalink
support jq path expressions in ignore_difference block (argoproj-labs…
Browse files Browse the repository at this point in the history
…#108)

* Add support for jq path expressions in ignore_differences block

* Proper tf formatting

* Remove single quotes

* Fixes for dev/ci environments

* Add jq path expressions version contraint, skip acceptance test if not supported
  • Loading branch information
jarrod-manwaring authored Oct 22, 2021
1 parent eff2e35 commit 59bb5dc
Show file tree
Hide file tree
Showing 13 changed files with 196 additions and 25 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
strategy:
fail-fast: false
matrix:
argocd_version: ["v2.1.2", "v2.0.5", "v.1.8.7"]
argocd_version: ["v2.1.3", "v2.0.5", "v1.8.7"]
steps:
- uses: actions/checkout@v2
- uses: actions/setup-go@v1
Expand Down Expand Up @@ -42,8 +42,8 @@ jobs:
- name: Set up ArgoCD ${{ matrix.argocd_version }}
env:
ARGOCD_VERSION: ${{ matrix.argocd_version }}
ARGOCD_CI: true
run: |
curl https://raw.githubusercontent.com/argoproj/argo-cd/${ARGOCD_VERSION}/manifests/install.yaml > manifests/install/install.yml
sh scripts/testacc_prepare_env.sh
until $(nc -z 127.0.0.1 8080); do sleep 2;done
netstat -tulpn
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
terraform-provider-argocd
./manifests/install/install.yml
/manifests/install/argocd.yml
/bin
.idea
.vscode
# Env variables settings
Expand Down
2 changes: 2 additions & 0 deletions argocd/features.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,15 @@ import (

const (
featureApplicationLevelSyncOptions = iota
featureIgnoreDiffJQPathExpressions
featureRepositoryGet
featureTokenIDs
)

var (
featureVersionConstraintsMap = map[int]*semver.Version{
featureApplicationLevelSyncOptions: semver.MustParse("1.5.0"),
featureIgnoreDiffJQPathExpressions: semver.MustParse("2.1.0"),
featureRepositoryGet: semver.MustParse("1.6.0"),
featureTokenIDs: semver.MustParse("1.5.3"),
}
Expand Down
60 changes: 60 additions & 0 deletions argocd/resource_argocd_application.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,36 @@ func resourceArgoCDApplicationCreate(ctx context.Context, d *schema.ResourceData
}
}

featureIgnoreDiffJQPathExpressionsSupported, err := server.isFeatureSupported(featureIgnoreDiffJQPathExpressions)
if err != nil {
return []diag.Diagnostic{
{
Severity: diag.Error,
Summary: "feature not supported",
Detail: err.Error(),
},
}
}
hasJQPathExpressions := false
if spec.IgnoreDifferences != nil {
for _, id := range spec.IgnoreDifferences {
if id.JQPathExpressions != nil {
hasJQPathExpressions = true
}
}
}
if !featureIgnoreDiffJQPathExpressionsSupported && hasJQPathExpressions {
return []diag.Diagnostic{
{
Severity: diag.Error,
Summary: fmt.Sprintf(
"jq path expressions are only supported from ArgoCD %s onwards",
featureVersionConstraintsMap[featureIgnoreDiffJQPathExpressions].String()),
Detail: err.Error(),
},
}
}

app, err = c.Create(ctx, &applicationClient.ApplicationCreateRequest{
Application: application.Application{

Expand Down Expand Up @@ -256,6 +286,36 @@ func resourceArgoCDApplicationUpdate(ctx context.Context, d *schema.ResourceData
}
}

featureIgnoreDiffJQPathExpressionsSupported, err := server.isFeatureSupported(featureIgnoreDiffJQPathExpressions)
if err != nil {
return []diag.Diagnostic{
{
Severity: diag.Error,
Summary: "feature not supported",
Detail: err.Error(),
},
}
}
hasJQPathExpressions := false
if spec.IgnoreDifferences != nil {
for _, id := range spec.IgnoreDifferences {
if id.JQPathExpressions != nil {
hasJQPathExpressions = true
}
}
}
if !featureIgnoreDiffJQPathExpressionsSupported && hasJQPathExpressions {
return []diag.Diagnostic{
{
Severity: diag.Error,
Summary: fmt.Sprintf(
"jq path expressions are only supported from ArgoCD %s onwards",
featureVersionConstraintsMap[featureIgnoreDiffJQPathExpressions].String()),
Detail: err.Error(),
},
}
}

app, err := c.Get(ctx, &applicationClient.ApplicationQuery{
Name: &appName,
})
Expand Down
90 changes: 87 additions & 3 deletions argocd/resource_argocd_application_test.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package argocd

import (
"context"
"fmt"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
)

func TestAccArgoCDApplication(t *testing.T) {
Expand Down Expand Up @@ -190,6 +192,27 @@ ingress:
),
),
},
{
SkipFunc: testAccSkipFeatureIgnoreDiffJQPathExpressions,
Config: testAccArgoCDApplicationIgnoreDiffJQPathExpressions(
acctest.RandomWithPrefix("test-acc")),
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet(
"argocd_application.ignore_differences_jqpe",
"metadata.0.uid",
),
resource.TestCheckResourceAttr(
"argocd_application.ignore_differences_jqpe",
"spec.0.ignore_difference.0.jq_path_expressions.0",
".spec.replicas",
),
resource.TestCheckResourceAttr(
"argocd_application.ignore_differences_jqpe",
"spec.0.ignore_difference.1.jq_path_expressions.1",
".spec.template.spec.metadata.labels.somelabel",
),
),
},
},
})
}
Expand Down Expand Up @@ -482,9 +505,9 @@ resource "argocd_application" "ignore_differences" {
}
ignore_difference {
group = "apps"
kind = "Deployment"
json_pointers = ["/spec/replicas"]
group = "apps"
kind = "Deployment"
json_pointers = ["/spec/replicas"]
}
ignore_difference {
Expand All @@ -500,3 +523,64 @@ resource "argocd_application" "ignore_differences" {
}
`, name)
}

func testAccArgoCDApplicationIgnoreDiffJQPathExpressions(name string) string {
return fmt.Sprintf(`
resource "argocd_application" "ignore_differences_jqpe" {
metadata {
name = "%s"
namespace = "argocd"
labels = {
acceptance = "true"
}
}
spec {
source {
repo_url = "https://charts.bitnami.com/bitnami"
chart = "redis"
target_revision = "15.3.0"
}
destination {
server = "https://kubernetes.default.svc"
namespace = "default"
}
ignore_difference {
group = "apps"
kind = "Deployment"
jq_path_expressions = [".spec.replicas"]
}
ignore_difference {
group = "apps"
kind = "StatefulSet"
name = "someStatefulSet"
jq_path_expressions = [
".spec.replicas",
".spec.template.spec.metadata.labels.somelabel",
]
}
}
}
`, name)
}

func testAccSkipFeatureIgnoreDiffJQPathExpressions() (bool, error) {
p, _ := testAccProviders["argocd"]()
_ = p.Configure(context.Background(), &terraform.ResourceConfig{})
server := p.Meta().(*ServerInterface)
err := server.initClients()
if err != nil {
return false, err
}
featureSupported, err := server.isFeatureSupported(featureIgnoreDiffJQPathExpressions)
if err != nil {
return false, err
}
if !featureSupported {
return true, nil
}
return false, nil
}
8 changes: 8 additions & 0 deletions argocd/schema_application.go
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,14 @@ func applicationSpecSchema() *schema.Schema {
Type: schema.TypeString,
},
},
"jq_path_expressions": {
Type: schema.TypeSet,
Set: schema.HashString,
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
},
},
},
Expand Down
17 changes: 12 additions & 5 deletions argocd/structure_application.go
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,12 @@ func expandApplicationIgnoreDifferences(ids []interface{}) (
elem.JSONPointers = append(elem.JSONPointers, jp.(string))
}
}
if v, ok := id["jq_path_expressions"]; ok {
jqpes := v.(*schema.Set).List()
for _, jqpe := range jqpes {
elem.JQPathExpressions = append(elem.JQPathExpressions, jqpe.(string))
}
}
result = append(result, elem)
}
return
Expand Down Expand Up @@ -473,11 +479,12 @@ func flattenApplicationIgnoreDifferences(ids []application.ResourceIgnoreDiffere
result []map[string]interface{}) {
for _, id := range ids {
result = append(result, map[string]interface{}{
"group": id.Group,
"kind": id.Kind,
"name": id.Name,
"namespace": id.Namespace,
"json_pointers": id.JSONPointers,
"group": id.Group,
"kind": id.Kind,
"name": id.Name,
"namespace": id.Namespace,
"json_pointers": id.JSONPointers,
"jq_path_expressions": id.JQPathExpressions,
})
}
return
Expand Down
6 changes: 6 additions & 0 deletions docs/resources/application.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ resource "argocd_application" "kustomize" {
"/spec/replicas",
"/spec/template/spec/metadata/labels/bar",
]
# Only available from ArgoCD 2.1.0 onwards
jq_path_expressions = [
".spec.replicas",
".spec.template.spec.metadata.labels.bar",
]
}
}
}
Expand Down Expand Up @@ -174,6 +179,7 @@ Each `ignore_difference` block can have the following attributes:
* `name` - (Optional) The targeted Kubernetes resource name.
* `namespace` - (Optional) The targeted Kubernetes resource namespace.
* `json_pointers` - (Optional) List of JSONPaths strings targeting the field(s) to ignore.
* `jq_path_expressions` - (Optional) List of jq path expression strings targeting the field(s) to ignore (only available from ArgoCD 2.1.0 onwards).

The `source` block has the following attributes:
* `repo_url` - (Required) string, repository URL of the application manifests.
Expand Down
2 changes: 1 addition & 1 deletion manifests/install/git-private-repository.yml
Original file line number Diff line number Diff line change
Expand Up @@ -109,4 +109,4 @@ spec:
- port: 22
targetPort: sshd
name: sshd
protocol: TCP
protocol: TCP
2 changes: 1 addition & 1 deletion manifests/install/kustomization.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ kind: Kustomization
namespace: argocd
resources:
- namespace.yml
- https://raw.githubusercontent.com/argoproj/argo-cd/v1.8.3/manifests/install.yaml
- argocd.yml
- git-private-repository.yml
- proxy-service.yml
patchesStrategicMerge:
Expand Down
2 changes: 1 addition & 1 deletion scripts/kind-config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ nodes:
- containerPort: 30123
hostPort: 8080
listenAddress: "0.0.0.0"
protocol: TCP
protocol: TCP
2 changes: 1 addition & 1 deletion scripts/testacc.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ ARGOCD_SERVER=127.0.0.1:8080 \
ARGOCD_AUTH_USERNAME=admin \
ARGOCD_AUTH_PASSWORD=acceptancetesting \
ARGOCD_CONTEXT=kind-argocd \
TF_ACC=1 go test $(go list ./... |grep -v 'vendor') -v -timeout 5m
TF_ACC=1 go test $(go list ./... |grep -v 'vendor') -v -timeout 5m
23 changes: 13 additions & 10 deletions scripts/testacc_prepare_env.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,31 @@

export PATH=$PATH:.

echo '--- Kustomize sanity checks'
echo "\n--- Kustomize sanity checks\n"
kustomize version || exit 1

echo '--- Create Kind cluster\n\n'
echo "\n--- Create Kind cluster\n"
kind create cluster --name argocd --config scripts/kind-config.yml --image kindest/node:${ARGOCD_KUBERNETES_VERSION:-v1.19.7}

echo '--- Kind sanity checks\n\n'
echo "\n--- Kind sanity checks\n"
kubectl get nodes -o wide
kubectl get pods --all-namespaces -o wide
kubectl get services --all-namespaces -o wide

echo '--- Load already available container images from local registry into Kind (local development only)'
kind load docker-image redis:5.0.10-alpine --name argocd
kind load docker-image ghcr.io/dexidp/dex:v2.27.0 --name argocd
kind load docker-image banzaicloud/vault-operator:1.3.3 --name argocd
kind load docker-image argoproj/argocd:${ARGOCD_VERSION:-v1.8.3} --name argocd
if [[ -z "${ARGOCD_CI}" ]]; then
echo "\n--- Load already available container images from local registry into Kind (local development only)\n"
kind load docker-image redis:6.2.4-alpine --name argocd
kind load docker-image ghcr.io/dexidp/dex:v2.27.0 --name argocd
kind load docker-image alpine:3 --name argocd
kind load docker-image quay.io/argoproj/argocd:${ARGOCD_VERSION:-v1.8.7} --name argocd
fi

echo '--- Install ArgoCD ${ARGOCD_VERSION:-v1.8.3}\n\n'
echo "\n--- Install ArgoCD ${ARGOCD_VERSION:-v1.8.7}\n"
curl https://raw.githubusercontent.com/argoproj/argo-cd/${ARGOCD_VERSION:-v1.8.7}/manifests/install.yaml > manifests/install/argocd.yml &&
kustomize build manifests/install | kubectl apply -f - &&
kubectl apply -f manifests/testdata/ &&

echo '--- Wait for ArgoCD components to be ready...'
echo "\n--- Wait for ArgoCD components to be ready...\n"
kubectl wait --for=condition=available --timeout=600s deployment/argocd-server -n argocd
kubectl wait --for=condition=available --timeout=30s deployment/argocd-repo-server -n argocd
kubectl wait --for=condition=available --timeout=30s deployment/argocd-dex-server -n argocd
Expand Down

0 comments on commit 59bb5dc

Please sign in to comment.