package kustomization_test import ( "bytes" "context" "embed" "encoding/json" "fmt" "io/fs" "os" "testing" "gotest.tools/v3/assert" "sigs.k8s.io/kustomize/api/filters/namespace" "sigs.k8s.io/kustomize/api/types" "sigs.k8s.io/kustomize/kyaml/kio" "edge-infra.dev/pkg/k8s/decoder" "edge-infra.dev/pkg/k8s/unstructured" "edge-infra.dev/test/f2" "edge-infra.dev/test/f2/integration" "edge-infra.dev/test/f2/x/ktest" "edge-infra.dev/test/f2/x/ktest/envtest" ) // testdata -- the contents of this direcotory are generated by a genrule // //go:embed testdata var manifests embed.FS var f f2.Framework func TestMain(m *testing.M) { f = f2.New( context.Background(), f2.WithExtensions( ktest.New( ktest.WithEnvtestOptions( envtest.WithoutCRDs(), ), ), ), ). Setup(func(ctx f2.Context) (f2.Context, error) { // Test execution should end here unless -integration-level=2 is passed to test if !integration.IsL2() { return ctx, fmt.Errorf("%w: requires L2 integration test level", f2.ErrSkip) } return ctx, nil }) os.Exit(f.Run(m)) } func TestApplyKustomizationDeployment(t *testing.T) { fin := f2.NewFeature("generated kustomization with image sha"). Test("Deploy kustomization", func(ctx f2.Context, t *testing.T) f2.Context { var k = ktest.FromContextT(ctx, t) out, err := processManifests(ctx, t, manifests, "testdata/kustomization_manifests.yaml") assert.NilError(t, err) for _, object := range out { err := k.Client.Create(ctx, object) assert.NilError(t, err) } val, err := json.Marshal(out) assert.NilError(t, err) fmt.Println(string(val)) return ctx }).Feature() f.Test(t, fin) } func processManifests(ctx f2.Context, t *testing.T, fs fs.FS, path string) ([]*unstructured.Unstructured, error) { buf := bytes.Buffer{} file, err := fs.Open(path) if err != nil { return nil, fmt.Errorf("error opening file: %w", err) } err = kio.Pipeline{ Inputs: []kio.Reader{&kio.ByteReader{Reader: file}}, Outputs: []kio.Writer{kio.ByteWriter{Writer: &buf}}, Filters: []kio.Filter{processNamespace(ctx, t)}, }.Execute() if err != nil { return nil, fmt.Errorf("failed to process manifests: %w", err) } return decoder.DecodeYAML(buf.Bytes()) } // processNamespace returns a kio.Filter for updating all namespace references // in manifests to point to the test specific namespace. Includes updating // service account's namespaces in role bindings. func processNamespace(ctx f2.Context, t *testing.T) kio.Filter { k := ktest.FromContextT(ctx, t) fss := types.FsSlice{ { Path: "metadata/namespace", CreateIfNotPresent: true, }, } return namespace.Filter{ Namespace: k.Namespace, FsSlice: fss, SetRoleBindingSubjects: namespace.AllServiceAccountSubjects, } }