Skip to content

Commit

Permalink
hide some functions, clean up tests
Browse files Browse the repository at this point in the history
  • Loading branch information
djeebus committed Dec 19, 2024
1 parent c4aa614 commit 5f254df
Show file tree
Hide file tree
Showing 3 changed files with 121 additions and 164 deletions.
261 changes: 110 additions & 151 deletions pkg/affected_apps/argocd_matcher_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,15 @@ package affected_apps

import (
"context"
"crypto/md5"
"encoding/hex"
"math/rand"
"os"
"path/filepath"
"strconv"
"testing"

"github.com/argoproj/argo-cd/v2/pkg/apis/application/v1alpha1"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/zapier/kubechecks/pkg"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

"github.com/zapier/kubechecks/pkg/appdir"
"github.com/zapier/kubechecks/pkg/git"
)
Expand Down Expand Up @@ -51,168 +48,140 @@ func TestFindAffectedAppsWithNilAppsDirectory(t *testing.T) {
}

func TestScenarios(t *testing.T) {
t.Run("simple setup", func(t *testing.T) {
ctx := context.Background()
repoURL := "https://github.com/argoproj/argocd-example-apps.git"
repoFiles := map[string]string{
// app of apps of apps
"app-of-apps-of-apps/kustomization.yaml": `
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- clusters.yaml
`,
"app-of-apps-of-apps/clusters.yaml": `
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: cluster-apps
spec:
destination:
namespace: argocd
server: https://kubernetes.default.svc
project: default
source:
path: charts/app-of-apps
repoURL: https://gitlab.com/zapier/argo-cd-configs.git
targetRevision: HEAD
helm:
valueFiles:
- values.yaml
- ../../app-of-apps/cluster.yaml
syncPolicy:
automated:
prune: true
`,
// helm chart that renders app of apps
"charts/app-of-apps/Chart.yaml": `
apiVersion: v1
description: Chart for setting up argocd applications
name: app-of-apps
version: 1.0.0
`,
"charts/app-of-apps/values.yaml": ``,
"charts/app-of-apps/templates/app.yaml": `
{{- range $name, $app := .Values.apps }}
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: {{ $name }}
spec:
destination:
namespace: argocd
source:
path: apps/{{ $name }}
`,

// values files for app of apps
"app-of-apps/cluster.yaml": `
apps:
app1: `,

// one app
"apps/app1/Chart.yaml": ``,
"apps/app1/values.yaml": ``,
}

testRepo := dumpFiles(t, repoURL, "HEAD", repoFiles)

testVCSMap := appdir.NewVcsToArgoMap("vcs-username")
testVCSMap.AddApp(&v1alpha1.Application{
ObjectMeta: metav1.ObjectMeta{
Name: "app-of-apps-of-apps",
repoURL := "https://github.com/argoproj/argocd-example-apps.git"

testCases := map[string]struct {
files map[string]string
changedFiles []string
app v1alpha1.Application
expected bool
}{
"helm - match": {
files: map[string]string{
"app/Chart.yaml": `apiVersion: v1`,
},
Spec: v1alpha1.ApplicationSpec{
Source: &v1alpha1.ApplicationSource{
RepoURL: repoURL,
Path: "app-of-apps-of-apps",
TargetRevision: "HEAD",
changedFiles: []string{"app/Chart.yaml"},
app: v1alpha1.Application{
Spec: v1alpha1.ApplicationSpec{
Source: &v1alpha1.ApplicationSource{
RepoURL: repoURL,
Path: "app/",
},
},
},
})

testVCSMap.AddApp(&v1alpha1.Application{
ObjectMeta: metav1.ObjectMeta{
Name: "app-of-apps",
expected: true,
},
"helm - value file outside of app path": {
files: map[string]string{
"app/Chart.yaml": `apiVersion: v1`,
"values.yaml": "content",
},
Spec: v1alpha1.ApplicationSpec{
Source: &v1alpha1.ApplicationSource{
RepoURL: repoURL,
Path: "charts/app-of-apps",
TargetRevision: "HEAD",
Helm: &v1alpha1.ApplicationSourceHelm{
ValueFiles: []string{
"values.yaml",
"../../app-of-apps/cluster.yaml",
changedFiles: []string{"values.yaml"},
app: v1alpha1.Application{
Spec: v1alpha1.ApplicationSpec{
Source: &v1alpha1.ApplicationSource{
RepoURL: repoURL,
Path: "app/",
Helm: &v1alpha1.ApplicationSourceHelm{
ValueFiles: []string{
"../values.yaml",
},
},
},
},
},
})
testVCSMap.AddApp(&v1alpha1.Application{
ObjectMeta: metav1.ObjectMeta{
Name: "app",
expected: true,
},
"helm - file parameter outside of app path": {
files: map[string]string{
"app/Chart.yaml": `apiVersion: v1`,
"values.yaml": "content",
},
Spec: v1alpha1.ApplicationSpec{
Source: &v1alpha1.ApplicationSource{
RepoURL: repoURL,
Path: "app/app1",
TargetRevision: "HEAD",
Helm: &v1alpha1.ApplicationSourceHelm{
ValueFiles: []string{
"values.yaml",
app: v1alpha1.Application{
Spec: v1alpha1.ApplicationSpec{
Source: &v1alpha1.ApplicationSource{
RepoURL: repoURL,
Path: "app/",
Helm: &v1alpha1.ApplicationSourceHelm{
FileParameters: []v1alpha1.HelmFileParameter{{
Name: "key", Path: "../values.yaml",
}},
},
},
},
},
})

m, err := NewArgocdMatcher(testVCSMap, testRepo)
require.NoError(t, err)

t.Run("modify cluster.yaml", func(t *testing.T) {
result, err := m.AffectedApps(ctx, []string{"app-of-apps/cluster.yaml"}, "main", testRepo)
require.NoError(t, err)
changedFiles: []string{"values.yaml"},
expected: true,
},
"kustomize": {
files: map[string]string{
"app/kustomization.yaml": `
resources:
- file.yaml`,
"app/file.yaml": "content",
},
changedFiles: []string{"app/file.yaml"},
app: v1alpha1.Application{
Spec: v1alpha1.ApplicationSpec{
Source: &v1alpha1.ApplicationSource{
RepoURL: repoURL,
Path: "app/",
},
},
},
expected: true,
},
"kustomize - file is outside of app path": {
files: map[string]string{
"app/kustomization.yaml": `
resources:
- ../file.yaml`,
"file.yaml": "content",
},
changedFiles: []string{"file.yaml"},
app: v1alpha1.Application{
Spec: v1alpha1.ApplicationSpec{
Source: &v1alpha1.ApplicationSource{
RepoURL: repoURL,
Path: "app/",
},
},
},
expected: true,
},
}

require.Len(t, result.Applications, 1)
app := result.Applications[0]
assert.Equal(t, "app-of-apps", app.Name)
})
for name, tc := range testCases {
t.Run(name, func(t *testing.T) {
tc.app.Name = name
tc.app.Spec.Source.RepoURL = repoURL

t.Run("modify clusters.yaml", func(t *testing.T) {
result, err := m.AffectedApps(ctx, []string{"app-of-apps-of-apps/clusters.yaml"}, "main", testRepo)
require.NoError(t, err)
testRepo := dumpFiles(t, repoURL, "HEAD", tc.files)

require.Len(t, result.Applications, 1)
app := result.Applications[0]
assert.Equal(t, "app-of-apps-of-apps", app.Name)
})
testVCSMap := appdir.NewVcsToArgoMap("vcs-username")
testVCSMap.AddApp(&tc.app)

t.Run("unindexed file in kustomize directory", func(t *testing.T) {
result, err := m.AffectedApps(ctx, []string{"app-of-apps-of-apps/invalid.yaml"}, "main", testRepo)
m, err := NewArgocdMatcher(testVCSMap, testRepo)
require.NoError(t, err)

require.Len(t, result.Applications, 1)
app := result.Applications[0]
assert.Equal(t, "app-of-apps-of-apps", app.Name)
})
ctx := context.Background()

t.Run("unindexed file in helm directory", func(t *testing.T) {
result, err := m.AffectedApps(ctx, []string{"charts/app-of-apps/templates/new.yaml"}, "main", testRepo)
result, err := m.AffectedApps(ctx, tc.changedFiles, "main", testRepo)
require.NoError(t, err)

require.Len(t, result.Applications, 1)
app := result.Applications[0]
assert.Equal(t, "app-of-apps", app.Name)
if tc.expected {
require.Len(t, result.Applications, 1)
app := result.Applications[0]
assert.Equal(t, tc.app.Name, app.Name)
} else {
require.Len(t, result.Applications, 0)
}
})
})
}
}

func dumpFiles(t *testing.T, cloneURL, target string, files map[string]string) *git.Repo {
repoHash := hash(t, cloneURL, target)
tempDir := filepath.Join(t.TempDir(), repoHash)
tempDir := filepath.Join(t.TempDir(), strconv.Itoa(rand.Int()))
repo := &git.Repo{
BranchName: target,
CloneURL: cloneURL,
Expand All @@ -234,13 +203,3 @@ func dumpFiles(t *testing.T, cloneURL, target string, files map[string]string) *

return repo
}

func hash(t *testing.T, repoURL, target string) string {
t.Helper()

url, err := pkg.Canonicalize(repoURL)
require.NoError(t, err)

data := md5.Sum([]byte(url.Host + url.Path + target))
return hex.EncodeToString(data[:])
}
14 changes: 6 additions & 8 deletions pkg/appdir/app_directory.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,10 +141,8 @@ func (d *AppDirectory) AddApp(app v1alpha1.Application) {
return
}

appName := app.Name

for _, src := range getSources(app) {
sourcePath := getSourcePath(app)
sourcePath := src.Path
log.Debug().
Str("appName", app.Name).
Str("cluster-name", app.Spec.Destination.Name).
Expand All @@ -153,18 +151,18 @@ func (d *AppDirectory) AddApp(app v1alpha1.Application) {
Msg("add app")

d.appsMap[app.Name] = app
d.AddDir(app.Name, sourcePath)
d.addDir(app.Name, sourcePath)

// handle extra helm paths
if helm := src.Helm; helm != nil {
for _, param := range helm.FileParameters {
path := filepath.Join(sourcePath, param.Path)
d.AddFile(appName, path)
d.addFile(app.Name, path)
}

for _, valueFilePath := range helm.ValueFiles {
path := filepath.Join(sourcePath, valueFilePath)
d.AddFile(appName, path)
d.addFile(app.Name, path)
}
}
}
Expand All @@ -178,11 +176,11 @@ func getSources(app v1alpha1.Application) []v1alpha1.ApplicationSource {
return app.Spec.Sources
}

func (d *AppDirectory) AddDir(appName, path string) {
func (d *AppDirectory) addDir(appName, path string) {
d.appDirs[path] = append(d.appDirs[path], appName)
}

func (d *AppDirectory) AddFile(appName, path string) {
func (d *AppDirectory) addFile(appName, path string) {
d.appFiles[path] = append(d.appFiles[path], appName)
}

Expand Down
10 changes: 5 additions & 5 deletions pkg/appdir/walk_kustomize_files.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,11 @@ func walkKustomizeFiles(result *AppDirectory, fs fs.FS, appName, dirpath string)
}

if !stat.IsDir() {
result.AddFile(appName, relPath)
result.addFile(appName, relPath)
continue
}

result.AddDir(appName, relPath)
result.addDir(appName, relPath)
if err = walkKustomizeFiles(result, fs, appName, relPath); err != nil {
log.Warn().Err(err).Msgf("failed to read kustomize.yaml from resources in %s", relPath)
}
Expand All @@ -104,20 +104,20 @@ func walkKustomizeFiles(result *AppDirectory, fs fs.FS, appName, dirpath string)
}

relPath := filepath.Join(dirpath, basePath)
result.AddDir(appName, relPath)
result.addDir(appName, relPath)
if err = walkKustomizeFiles(result, fs, appName, relPath); err != nil {
log.Warn().Err(err).Msgf("failed to read kustomize.yaml from bases in %s", relPath)
}
}

for _, patchFile := range kustomize.PatchesStrategicMerge {
relPath := filepath.Join(dirpath, patchFile)
result.AddFile(appName, relPath)
result.addFile(appName, relPath)
}

for _, patch := range kustomize.PatchesJson6902 {
relPath := filepath.Join(dirpath, patch.Path)
result.AddFile(appName, relPath)
result.addFile(appName, relPath)
}

return nil
Expand Down

0 comments on commit 5f254df

Please sign in to comment.