diff --git a/end_to_end_testing/course_files/27_gitops.yaml b/end_to_end_testing/course_files/27_gitops.yaml new file mode 100644 index 00000000..a9393ba4 --- /dev/null +++ b/end_to_end_testing/course_files/27_gitops.yaml @@ -0,0 +1,66 @@ +--- +schema: v2 +namespace: myns +repository: stable +context: mycontext +repositories: + fairwinds-stable: + url: https://charts.fairwinds.com/stable +minimum_versions: + helm: 3.4.1 + reckoner: 4.3.1 +gitops: + argocd: + kind: Application + apiVersion: argoproj.io/v1alpha1 + metadata: + namespace: argocd + annotations: + one_key: one_value + spec: + destination: + namespace: some_value + server: https://kubernetes.default.svc + project: default + source: + # path: manifests + repoURL: https://github.com/someuser/clustername.git + directory: + recurse: true + # plugin: + # name: argocd-vault-plugin + syncPolicy: + automated: + prune: true + syncOptions: + - CreateNamespace=true + - PruneLast=true +namespace_management: + default: + metadata: + annotations: + insights.fairwinds.com/adminOnly: "true" + labels: + ManagedBy: Fairwinds + settings: + overwrite: true +releases: + - name: rbac-manager + namespace: rbac-manager + namespace_management: + settings: + overwrite: true + chart: rbac-manager + version: 1.11.1 + repository: fairwinds-stable + + gitops: + argocd: + metadata: + annotations: + notifications.argoproj.io/subscribe.on-sync-succeeded.slack: some_channel + spec: + project: different_project + source: + path: some_totally_different_path + repoURL: https://github.com/another_user/another_repo.git diff --git a/end_to_end_testing/tests/27_gitops.yaml b/end_to_end_testing/tests/27_gitops.yaml new file mode 100644 index 00000000..49864e78 --- /dev/null +++ b/end_to_end_testing/tests/27_gitops.yaml @@ -0,0 +1,13 @@ +version: "2" +name: Shell Executor Secret +vars: + course: ../course_files/27_gitops.yaml + namespace: 27-gitops + release: shell-executor-chart +testcases: +- name: 27 - template course + steps: + - script: | + reckoner template -a {{.course}} --output-dir 27_gitops_output + assertions: + - result.code ShouldEqual 0 diff --git a/pkg/reckoner/argocd_test.go b/pkg/reckoner/argocd_test.go new file mode 100644 index 00000000..e2ffda62 --- /dev/null +++ b/pkg/reckoner/argocd_test.go @@ -0,0 +1,95 @@ +package reckoner + +import ( + "testing" + + "github.com/fairwindsops/reckoner/pkg/course" + "github.com/stretchr/testify/assert" +) + +func Test_generateArgoApplication(t *testing.T) { + tests := []struct { + name string + cFile course.FileV2 + want course.ArgoApplication + wantErr bool + }{ + { + name: "ensure_defaults", + cFile: course.FileV2{ + Releases: []*course.Release{ + { + Name: "somename", + Namespace: "somens", + Repository: "somerepo", + GitOps: course.GitOps{ // release-specific *addition* + ArgoCD: course.ArgoApplication{ + Metadata: course.ArgoApplicationMetadata{ + Annotations: map[string]string{ + "notifications.argoproj.io/subscribe.on-sync-succeeded.slack": "fairwindsops-infra-argocd", + }, + }, + Spec: course.ArgoApplicationSpec{ + Source: course.ArgoApplicationSpecSource{ + Directory: course.ArgoApplicationSpecSourceDirectory{ + Recurse: true, // release-specific *override* + }, + }, + }, + }, + }, + }, + }, + GitOps: course.GitOps{ + ArgoCD: course.ArgoApplication{ + Spec: course.ArgoApplicationSpec{ + Source: course.ArgoApplicationSpecSource{ + Directory: course.ArgoApplicationSpecSourceDirectory{ + Recurse: false, // exists here only to be overridden by the release-specific instance + }, + // Path: "somepath", // omitting this tests more functionality + RepoURL: "https://domain.tld/someorg/somerepo.git", + }, + // Destination: course.ArgoApplicationSpecDestination{}, // omitting this tests defaults + }, + }, + }, + }, + want: course.ArgoApplication{ + Kind: "Application", + APIVersion: "argoproj.io/v1alpha1", + Metadata: course.ArgoApplicationMetadata{ + Name: "somename", + Annotations: map[string]string{ + "notifications.argoproj.io/subscribe.on-sync-succeeded.slack": "fairwindsops-infra-argocd", + }, + }, + Spec: course.ArgoApplicationSpec{ + Source: course.ArgoApplicationSpecSource{ + Directory: course.ArgoApplicationSpecSourceDirectory{ + Recurse: true, + }, + Path: "somename", + RepoURL: "https://domain.tld/someorg/somerepo.git", + }, + Destination: course.ArgoApplicationSpecDestination{ + Server: "https://kubernetes.default.svc", + Namespace: "somens", + }, + Project: "default", + }, + }, + wantErr: false, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := generateArgoApplication(*tt.cFile.Releases[0], tt.cFile) + if (err != nil) != tt.wantErr { + t.Errorf("generateArgoApplication() error = %v, wantErr %v", err, tt.wantErr) + return + } + assert.Equal(t, tt.want, got) + }) + } +} diff --git a/pkg/reckoner/split.go b/pkg/reckoner/split.go index aeab658d..3044fee0 100644 --- a/pkg/reckoner/split.go +++ b/pkg/reckoner/split.go @@ -62,7 +62,7 @@ func splitYAML(in []byte) (out [][]byte, err error) { } // we believe we have a valid YAML object - out = append(out, b.Bytes()) // so append it to the list to be returned later + out = append(out, bytes.TrimSpace(b.Bytes())) // so append it to the list to be returned later } return out, nil // list of YAML objects, each a []byte diff --git a/pkg/reckoner/split_test.go b/pkg/reckoner/split_test.go new file mode 100644 index 00000000..2aaac0be --- /dev/null +++ b/pkg/reckoner/split_test.go @@ -0,0 +1,50 @@ +package reckoner + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func Test_splitYAML(t *testing.T) { + tests := []struct { + name string + yamlFile []byte + want [][]byte + wantNumberOfDocs int + wantErr bool + }{ + { + name: "one_document", + yamlFile: []byte("---\nfield: \"value\"\n"), + want: [][]byte{ + []byte("field: value"), + }, + wantErr: false, + }, + { + name: "multi_documents", + yamlFile: []byte("---\nfield:\n nested: value\n---\nanother: second\n"), + want: [][]byte{ + []byte("field:\n nested: value"), + []byte("another: second"), + }, + wantErr: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + docs, err := splitYAML(tt.yamlFile) + if (err != nil) != tt.wantErr { + t.Errorf("splitYAML() error = %v, wantErr %v", err, tt.wantErr) + return + } + if len(tt.want) != len(docs) { + t.Errorf("splitYAML() produced different number of YAML documents than expected; wanted = %v, got %v", tt.wantNumberOfDocs, len(docs)) + } + + assert.Equal(t, tt.want, docs) + }) + } +}