Recursively build and diff Kustomizations
Signed-off-by: Boris Kreitchman <bkreitch@gmail.com>
This commit is contained in:
@@ -26,6 +26,7 @@ import (
|
||||
"github.com/fluxcd/pkg/apis/meta"
|
||||
"github.com/google/go-cmp/cmp"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
"sigs.k8s.io/kustomize/api/resource"
|
||||
"sigs.k8s.io/kustomize/kyaml/yaml"
|
||||
)
|
||||
@@ -361,3 +362,242 @@ func Test_ResolveKustomization(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_isKustomization(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
expected bool
|
||||
object *unstructured.Unstructured
|
||||
}{
|
||||
{
|
||||
name: "flux kustomization",
|
||||
object: &unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"apiVersion": "kustomize.toolkit.fluxcd.io/v1",
|
||||
"kind": "Kustomization",
|
||||
},
|
||||
},
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "other kustomization",
|
||||
object: &unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"apiVersion": "kustomize.config.k8s.io/v1beta1",
|
||||
"kind": "Kustomization",
|
||||
},
|
||||
},
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "wrong kind",
|
||||
object: &unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"apiVersion": "kustomize.toolkit.fluxcd.io/v1",
|
||||
"kind": "ConfigMap",
|
||||
},
|
||||
},
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "wrong object",
|
||||
object: &unstructured.Unstructured{
|
||||
Object: map[string]interface{}{
|
||||
"apiVersion": "v1",
|
||||
"kind": "ConfigMap",
|
||||
},
|
||||
},
|
||||
expected: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
actual := isKustomization(tt.object)
|
||||
if actual != tt.expected {
|
||||
t.Fatalf("got '%v', want '%v'", actual, tt.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_kustomizationsEqual(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
kustomization1 *kustomizev1.Kustomization
|
||||
kustomization2 *kustomizev1.Kustomization
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
name: "equal",
|
||||
kustomization1: &kustomizev1.Kustomization{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "podinfo",
|
||||
Namespace: "flux-system",
|
||||
},
|
||||
},
|
||||
kustomization2: &kustomizev1.Kustomization{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "podinfo",
|
||||
Namespace: "flux-system",
|
||||
},
|
||||
},
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "wrong name",
|
||||
kustomization1: &kustomizev1.Kustomization{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "podinfo",
|
||||
Namespace: "flux-system",
|
||||
},
|
||||
},
|
||||
kustomization2: &kustomizev1.Kustomization{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "my-app",
|
||||
Namespace: "flux-system",
|
||||
},
|
||||
},
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "wrong namespace",
|
||||
kustomization1: &kustomizev1.Kustomization{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "podinfo",
|
||||
Namespace: "flux-system",
|
||||
},
|
||||
},
|
||||
kustomization2: &kustomizev1.Kustomization{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "podinfo",
|
||||
Namespace: "my-ns",
|
||||
},
|
||||
},
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "wrong name and namespace",
|
||||
kustomization1: &kustomizev1.Kustomization{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "podinfo",
|
||||
Namespace: "flux-system",
|
||||
},
|
||||
},
|
||||
kustomization2: &kustomizev1.Kustomization{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "my-app",
|
||||
Namespace: "my-ns",
|
||||
},
|
||||
},
|
||||
expected: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
actual := kustomizationsEqual(tt.kustomization1, tt.kustomization2)
|
||||
if actual != tt.expected {
|
||||
t.Fatalf("got '%v', want '%v'", actual, tt.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_kustomizationPath(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
kustomization *kustomizev1.Kustomization
|
||||
expected string
|
||||
wantErr bool
|
||||
errString string
|
||||
}{
|
||||
{
|
||||
name: "full repo",
|
||||
kustomization: &kustomizev1.Kustomization{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "my-app",
|
||||
Namespace: "flux-system",
|
||||
},
|
||||
Spec: kustomizev1.KustomizationSpec{
|
||||
Path: "my-path",
|
||||
SourceRef: kustomizev1.CrossNamespaceSourceReference{
|
||||
Kind: "GitRepository",
|
||||
Name: "my-repo",
|
||||
Namespace: "flux-system",
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: "path/to/local/git/my-path",
|
||||
},
|
||||
{
|
||||
name: "repo without namespace",
|
||||
kustomization: &kustomizev1.Kustomization{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "my-app",
|
||||
Namespace: "flux-system",
|
||||
},
|
||||
Spec: kustomizev1.KustomizationSpec{
|
||||
Path: "my-path",
|
||||
SourceRef: kustomizev1.CrossNamespaceSourceReference{
|
||||
Kind: "GitRepository",
|
||||
Name: "my-repo",
|
||||
Namespace: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
expected: "path/to/local/git/my-path",
|
||||
},
|
||||
{
|
||||
name: "repo not found",
|
||||
kustomization: &kustomizev1.Kustomization{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: "my-app",
|
||||
Namespace: "flux-system",
|
||||
},
|
||||
Spec: kustomizev1.KustomizationSpec{
|
||||
Path: "my-path",
|
||||
SourceRef: kustomizev1.CrossNamespaceSourceReference{
|
||||
Kind: "GitRepository",
|
||||
Name: "my-repo",
|
||||
Namespace: "my-ns",
|
||||
},
|
||||
},
|
||||
},
|
||||
wantErr: true,
|
||||
errString: "cannot get local path",
|
||||
},
|
||||
}
|
||||
|
||||
b := &Builder{
|
||||
name: "podinfo",
|
||||
namespace: "flux-system",
|
||||
localSources: map[string]string{
|
||||
"GitRepository/flux-system/my-repo": "./path/to/local/git",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
actual, err := b.kustomizationPath(tt.kustomization)
|
||||
if !tt.wantErr {
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected err '%s'", err)
|
||||
}
|
||||
|
||||
if actual != tt.expected {
|
||||
t.Errorf("got '%v', want '%v'", actual, tt.expected)
|
||||
}
|
||||
} else {
|
||||
if err == nil {
|
||||
t.Fatal("expected error but got nil")
|
||||
}
|
||||
|
||||
if !strings.Contains(err.Error(), tt.errString) {
|
||||
t.Errorf("expected error '%s' to contain string '%s'", err.Error(), tt.errString)
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user