diff --git a/e2e/package_examples_test.go b/e2e/package_examples_test.go new file mode 100644 index 0000000000..80eddf8e40 --- /dev/null +++ b/e2e/package_examples_test.go @@ -0,0 +1,170 @@ +//go:build docker + +// Copyright 2026 The kpt Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package e2e_test + +import ( + "os" + "os/exec" + "path/filepath" + "strings" + "testing" + + "github.com/kptdev/kpt/pkg/test/runner" +) + +// TestPackageExamples runs e2e tests against the package-examples directory. +// Test fixtures (expected output) are stored in e2e/testdata/package-examples/ +// while the actual packages live in the top-level package-examples/ directory. +// This keeps documentation examples clean of test-specific files. +// +// To generate or update expected output: +// +// KPT_E2E_UPDATE_EXPECTED=true go test --tags=docker --run=TestPackageExamples ./e2e/ +func TestPackageExamples(t *testing.T) { + testdataDir := filepath.Join(".", "testdata", "package-examples") + pkgExamplesDir := filepath.Join("..", "package-examples") + updateExpected := strings.ToLower(os.Getenv("KPT_E2E_UPDATE_EXPECTED")) == "true" + + checkOrScaffoldTestdata(t, pkgExamplesDir, testdataDir, updateExpected) + + cases, err := runner.ScanTestCases(testdataDir) + if err != nil { + t.Fatalf("failed to scan test cases: %s", err) + } + + for _, c := range *cases { + c := c + name := filepath.Base(c.Path) + t.Run(name, func(t *testing.T) { + if !c.Config.Sequential { + t.Parallel() + } + runPackageExampleCase(t, pkgExamplesDir, name, c, updateExpected) + }) + } +} + +func runPackageExampleCase(t *testing.T, pkgExamplesDir, name string, c runner.TestCase, updateExpected bool) { + t.Helper() + + pkgSrc := filepath.Join(pkgExamplesDir, name) + if _, err := os.Stat(filepath.Join(pkgSrc, "Kptfile")); err != nil { + t.Fatalf("package-example %q does not have a Kptfile: %v", name, err) + } + + mergedPkg := prepareMergedPackage(t, pkgSrc, name, c.Path) + + mergedCase := runner.TestCase{ + Path: mergedPkg, + Config: c.Config, + } + + r, err := runner.NewRunner(t, mergedCase, c.Config.TestType) + if err != nil { + t.Fatalf("failed to create test runner: %v", err) + } + if r.Skip() { + t.Skip() + } + if err := r.Run(); err != nil { + t.Fatalf("failed when running test: %v", err) + } + + if updateExpected { + copyUpdatedExpectedOutput(t, mergedPkg, c.Path) + } +} + +// prepareMergedPackage creates a temporary directory containing the package +// content overlaid with test fixtures, and returns the path to the merged package. +func prepareMergedPackage(t *testing.T, pkgSrc, name, testFixturesDir string) string { + t.Helper() + + tmpDir, err := os.MkdirTemp("", "kpt-pkg-examples-e2e-*") + if err != nil { + t.Fatalf("failed to create temp dir: %v", err) + } + t.Cleanup(func() { os.RemoveAll(tmpDir) }) + + mergedPkg := filepath.Join(tmpDir, name) + + // Copy the actual package content + if out, err := exec.Command("cp", "-r", pkgSrc, mergedPkg).CombinedOutput(); err != nil { + t.Fatalf("failed to copy package: %v\n%s", err, out) + } + + // Copy the test fixtures (.expected, .krmignore) on top + entries, err := os.ReadDir(testFixturesDir) + if err != nil { + t.Fatalf("failed to read test fixtures dir: %v", err) + } + for _, entry := range entries { + src := filepath.Join(testFixturesDir, entry.Name()) + dst := filepath.Join(mergedPkg, entry.Name()) + if out, err := exec.Command("cp", "-r", src, dst).CombinedOutput(); err != nil { + t.Fatalf("failed to copy fixture %s: %v\n%s", entry.Name(), err, out) + } + } + + return mergedPkg +} + +// copyUpdatedExpectedOutput copies generated expected output back to the testdata directory. +func copyUpdatedExpectedOutput(t *testing.T, mergedPkg, testFixturesDir string) { + t.Helper() + + generatedExpected := filepath.Join(mergedPkg, ".expected") + targetExpected := filepath.Join(testFixturesDir, ".expected") + if out, err := exec.Command("cp", "-r", generatedExpected+"/.", targetExpected).CombinedOutput(); err != nil { + t.Fatalf("failed to copy updated expected output: %v\n%s", err, out) + } + t.Logf("updated expected output for %s", filepath.Base(mergedPkg)) +} + +// checkOrScaffoldTestdata verifies that every package-example directory has a +// corresponding entry in testdata. When updateExpected is false, missing entries +// cause the test to fail. When true, the minimum fixture structure is created +// so that ScanTestCases can pick it up and generate expected output. +func checkOrScaffoldTestdata(t *testing.T, pkgExamplesDir, testdataDir string, updateExpected bool) { + t.Helper() + examples, err := os.ReadDir(pkgExamplesDir) + if err != nil { + t.Fatalf("failed to read package-examples directory: %v", err) + } + for _, entry := range examples { + if !entry.IsDir() || strings.HasPrefix(entry.Name(), "_") { + continue + } + fixtureDir := filepath.Join(testdataDir, entry.Name()) + if _, err := os.Stat(fixtureDir); !os.IsNotExist(err) { + continue + } + if !updateExpected { + t.Errorf("package-example %q has no corresponding testdata in %s; "+ + "add a test fixture or run with KPT_E2E_UPDATE_EXPECTED=true to generate one", + entry.Name(), testdataDir) + continue + } + if err := os.MkdirAll(filepath.Join(fixtureDir, ".expected"), 0755); err != nil { + t.Fatalf("failed to scaffold testdata for %q: %v", entry.Name(), err) + } + if err := os.WriteFile(filepath.Join(fixtureDir, ".krmignore"), []byte(".expected\n"), 0644); err != nil { + t.Fatalf("failed to write .krmignore for %q: %v", entry.Name(), err) + } + t.Logf("scaffolded testdata for new example %q", entry.Name()) + } +} diff --git a/e2e/testdata/package-examples/cert-manager-basic/.expected/config.yaml b/e2e/testdata/package-examples/cert-manager-basic/.expected/config.yaml new file mode 100644 index 0000000000..e264d4aea6 --- /dev/null +++ b/e2e/testdata/package-examples/cert-manager-basic/.expected/config.yaml @@ -0,0 +1 @@ +exitCode: 0 diff --git a/e2e/testdata/package-examples/cert-manager-basic/.expected/diff.patch b/e2e/testdata/package-examples/cert-manager-basic/.expected/diff.patch new file mode 100644 index 0000000000..0b5c96a301 --- /dev/null +++ b/e2e/testdata/package-examples/cert-manager-basic/.expected/diff.patch @@ -0,0 +1,545 @@ +diff --git a/Kptfile b/Kptfile +index 6362f4b..ee8f5d1 100644 +--- a/Kptfile ++++ b/Kptfile +@@ -6,3 +6,8 @@ metadata: + config.kubernetes.io/local-config: "true" + info: + description: CertManager Package (https://cert-manager.io) ++status: ++ conditions: ++ - type: Rendered ++ status: "True" ++ reason: RenderSuccess +diff --git a/cainjector/clusterrole-cert-manager-cainjector.yaml b/cainjector/clusterrole-cert-manager-cainjector.yaml +index f50f7b2..bee1ab4 100644 +--- a/cainjector/clusterrole-cert-manager-cainjector.yaml ++++ b/cainjector/clusterrole-cert-manager-cainjector.yaml +@@ -28,4 +28,3 @@ rules: + - apiGroups: ["apiextensions.k8s.io"] + resources: ["customresourcedefinitions"] + verbs: ["get", "list", "watch", "update"] +- +diff --git a/cainjector/clusterrolebinding-cert-manager-cainjector.yaml b/cainjector/clusterrolebinding-cert-manager-cainjector.yaml +index 25f7415..5c3d014 100644 +--- a/cainjector/clusterrolebinding-cert-manager-cainjector.yaml ++++ b/cainjector/clusterrolebinding-cert-manager-cainjector.yaml +@@ -17,4 +17,3 @@ subjects: + - name: cert-manager-cainjector + namespace: "cert-manager" + kind: ServiceAccount +- +diff --git a/cainjector/deployment-cert-manager-cainjector.yaml b/cainjector/deployment-cert-manager-cainjector.yaml +index 2a8b441..2a5f297 100644 +--- a/cainjector/deployment-cert-manager-cainjector.yaml ++++ b/cainjector/deployment-cert-manager-cainjector.yaml +@@ -34,15 +34,14 @@ spec: + image: "quay.io/jetstack/cert-manager-cainjector:v1.8.2" + imagePullPolicy: IfNotPresent + args: +- - --v=2 +- - --leader-election-namespace=kube-system ++ - --v=2 ++ - --leader-election-namespace=kube-system + env: +- - name: POD_NAMESPACE +- valueFrom: +- fieldRef: +- fieldPath: metadata.namespace ++ - name: POD_NAMESPACE ++ valueFrom: ++ fieldRef: ++ fieldPath: metadata.namespace + securityContext: + allowPrivilegeEscalation: false + nodeSelector: + kubernetes.io/os: linux +- +diff --git a/cainjector/role-cert-manager-cainjector-leaderelection.yaml b/cainjector/role-cert-manager-cainjector-leaderelection.yaml +index f552b3e..ea13126 100644 +--- a/cainjector/role-cert-manager-cainjector-leaderelection.yaml ++++ b/cainjector/role-cert-manager-cainjector-leaderelection.yaml +@@ -24,4 +24,3 @@ rules: + - apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["create"] +- +diff --git a/cainjector/rolebinding-cert-manager-cainjector-leaderelection.yaml b/cainjector/rolebinding-cert-manager-cainjector-leaderelection.yaml +index 47cb026..c55888e 100644 +--- a/cainjector/rolebinding-cert-manager-cainjector-leaderelection.yaml ++++ b/cainjector/rolebinding-cert-manager-cainjector-leaderelection.yaml +@@ -20,4 +20,3 @@ subjects: + - kind: ServiceAccount + name: cert-manager-cainjector + namespace: cert-manager +- +diff --git a/cainjector/serviceaccount-cert-manager-cainjector.yaml b/cainjector/serviceaccount-cert-manager-cainjector.yaml +index 64bc6e9..dfc6074 100644 +--- a/cainjector/serviceaccount-cert-manager-cainjector.yaml ++++ b/cainjector/serviceaccount-cert-manager-cainjector.yaml +@@ -11,4 +11,3 @@ metadata: + app.kubernetes.io/instance: cert-manager + app.kubernetes.io/component: "cainjector" + app.kubernetes.io/version: "v1.8.2" +- +diff --git a/cert-manager/clusterrole-cert-manager-controller-approve-cert-manager-io.yaml b/cert-manager/clusterrole-cert-manager-controller-approve-cert-manager-io.yaml +index c217d3e..971b305 100644 +--- a/cert-manager/clusterrole-cert-manager-controller-approve-cert-manager-io.yaml ++++ b/cert-manager/clusterrole-cert-manager-controller-approve-cert-manager-io.yaml +@@ -15,4 +15,3 @@ rules: + resources: ["signers"] + verbs: ["approve"] + resourceNames: ["issuers.cert-manager.io/*", "clusterissuers.cert-manager.io/*"] +- +diff --git a/cert-manager/clusterrole-cert-manager-controller-certificates.yaml b/cert-manager/clusterrole-cert-manager-controller-certificates.yaml +index 35d5e27..06add19 100644 +--- a/cert-manager/clusterrole-cert-manager-controller-certificates.yaml ++++ b/cert-manager/clusterrole-cert-manager-controller-certificates.yaml +@@ -32,4 +32,3 @@ rules: + - apiGroups: [""] + resources: ["events"] + verbs: ["create", "patch"] +- +diff --git a/cert-manager/clusterrole-cert-manager-controller-certificatesigningrequests.yaml b/cert-manager/clusterrole-cert-manager-controller-certificatesigningrequests.yaml +index fecd592..9265271 100644 +--- a/cert-manager/clusterrole-cert-manager-controller-certificatesigningrequests.yaml ++++ b/cert-manager/clusterrole-cert-manager-controller-certificatesigningrequests.yaml +@@ -26,4 +26,3 @@ rules: + - apiGroups: ["authorization.k8s.io"] + resources: ["subjectaccessreviews"] + verbs: ["create"] +- +diff --git a/cert-manager/clusterrole-cert-manager-controller-challenges.yaml b/cert-manager/clusterrole-cert-manager-controller-challenges.yaml +index 354412f..dd4c64f 100644 +--- a/cert-manager/clusterrole-cert-manager-controller-challenges.yaml ++++ b/cert-manager/clusterrole-cert-manager-controller-challenges.yaml +@@ -38,8 +38,8 @@ rules: + - apiGroups: ["networking.k8s.io"] + resources: ["ingresses"] + verbs: ["get", "list", "watch", "create", "delete", "update"] +- - apiGroups: [ "gateway.networking.k8s.io" ] +- resources: [ "httproutes" ] ++ - apiGroups: ["gateway.networking.k8s.io"] ++ resources: ["httproutes"] + verbs: ["get", "list", "watch", "create", "delete", "update"] + # We require the ability to specify a custom hostname when we are creating + # new ingress resources. +@@ -57,4 +57,3 @@ rules: + - apiGroups: [""] + resources: ["secrets"] + verbs: ["get", "list", "watch"] +- +diff --git a/cert-manager/clusterrole-cert-manager-controller-clusterissuers.yaml b/cert-manager/clusterrole-cert-manager-controller-clusterissuers.yaml +index 7a8b52c..b25fadf 100644 +--- a/cert-manager/clusterrole-cert-manager-controller-clusterissuers.yaml ++++ b/cert-manager/clusterrole-cert-manager-controller-clusterissuers.yaml +@@ -23,4 +23,3 @@ rules: + - apiGroups: [""] + resources: ["events"] + verbs: ["create", "patch"] +- +diff --git a/cert-manager/clusterrole-cert-manager-controller-ingress-shim.yaml b/cert-manager/clusterrole-cert-manager-controller-ingress-shim.yaml +index ea1779f..56b4339 100644 +--- a/cert-manager/clusterrole-cert-manager-controller-ingress-shim.yaml ++++ b/cert-manager/clusterrole-cert-manager-controller-ingress-shim.yaml +@@ -35,4 +35,3 @@ rules: + - apiGroups: [""] + resources: ["events"] + verbs: ["create", "patch"] +- +diff --git a/cert-manager/clusterrole-cert-manager-controller-issuers.yaml b/cert-manager/clusterrole-cert-manager-controller-issuers.yaml +index 7330d6d..4bb32ac 100644 +--- a/cert-manager/clusterrole-cert-manager-controller-issuers.yaml ++++ b/cert-manager/clusterrole-cert-manager-controller-issuers.yaml +@@ -23,4 +23,3 @@ rules: + - apiGroups: [""] + resources: ["events"] + verbs: ["create", "patch"] +- +diff --git a/cert-manager/clusterrole-cert-manager-controller-orders.yaml b/cert-manager/clusterrole-cert-manager-controller-orders.yaml +index 2520992..54d6e16 100644 +--- a/cert-manager/clusterrole-cert-manager-controller-orders.yaml ++++ b/cert-manager/clusterrole-cert-manager-controller-orders.yaml +@@ -35,4 +35,3 @@ rules: + - apiGroups: [""] + resources: ["events"] + verbs: ["create", "patch"] +- +diff --git a/cert-manager/clusterrole-cert-manager-edit.yaml b/cert-manager/clusterrole-cert-manager-edit.yaml +index 8c57433..4777488 100644 +--- a/cert-manager/clusterrole-cert-manager-edit.yaml ++++ b/cert-manager/clusterrole-cert-manager-edit.yaml +@@ -21,4 +21,3 @@ rules: + - apiGroups: ["acme.cert-manager.io"] + resources: ["challenges", "orders"] + verbs: ["create", "delete", "deletecollection", "patch", "update"] +- +diff --git a/cert-manager/clusterrole-cert-manager-view.yaml b/cert-manager/clusterrole-cert-manager-view.yaml +index 9e15379..f5d8298 100644 +--- a/cert-manager/clusterrole-cert-manager-view.yaml ++++ b/cert-manager/clusterrole-cert-manager-view.yaml +@@ -19,4 +19,3 @@ rules: + - apiGroups: ["acme.cert-manager.io"] + resources: ["challenges", "orders"] + verbs: ["get", "list", "watch"] +- +diff --git a/cert-manager/clusterrolebinding-cert-manager-controller-approve-cert-manager-io.yaml b/cert-manager/clusterrolebinding-cert-manager-controller-approve-cert-manager-io.yaml +index 7a2f3f2..632c2d7 100644 +--- a/cert-manager/clusterrolebinding-cert-manager-controller-approve-cert-manager-io.yaml ++++ b/cert-manager/clusterrolebinding-cert-manager-controller-approve-cert-manager-io.yaml +@@ -17,4 +17,3 @@ subjects: + - name: cert-manager + namespace: "cert-manager" + kind: ServiceAccount +- +diff --git a/cert-manager/clusterrolebinding-cert-manager-controller-certificates.yaml b/cert-manager/clusterrolebinding-cert-manager-controller-certificates.yaml +index 992c61b..2b3dda3 100644 +--- a/cert-manager/clusterrolebinding-cert-manager-controller-certificates.yaml ++++ b/cert-manager/clusterrolebinding-cert-manager-controller-certificates.yaml +@@ -17,4 +17,3 @@ subjects: + - name: cert-manager + namespace: "cert-manager" + kind: ServiceAccount +- +diff --git a/cert-manager/clusterrolebinding-cert-manager-controller-certificatesigningrequests.yaml b/cert-manager/clusterrolebinding-cert-manager-controller-certificatesigningrequests.yaml +index fd1f843..1d1d02e 100644 +--- a/cert-manager/clusterrolebinding-cert-manager-controller-certificatesigningrequests.yaml ++++ b/cert-manager/clusterrolebinding-cert-manager-controller-certificatesigningrequests.yaml +@@ -17,4 +17,3 @@ subjects: + - name: cert-manager + namespace: "cert-manager" + kind: ServiceAccount +- +diff --git a/cert-manager/clusterrolebinding-cert-manager-controller-challenges.yaml b/cert-manager/clusterrolebinding-cert-manager-controller-challenges.yaml +index 7ff71b7..b11b588 100644 +--- a/cert-manager/clusterrolebinding-cert-manager-controller-challenges.yaml ++++ b/cert-manager/clusterrolebinding-cert-manager-controller-challenges.yaml +@@ -17,4 +17,3 @@ subjects: + - name: cert-manager + namespace: "cert-manager" + kind: ServiceAccount +- +diff --git a/cert-manager/clusterrolebinding-cert-manager-controller-clusterissuers.yaml b/cert-manager/clusterrolebinding-cert-manager-controller-clusterissuers.yaml +index a5d3d55..9799add 100644 +--- a/cert-manager/clusterrolebinding-cert-manager-controller-clusterissuers.yaml ++++ b/cert-manager/clusterrolebinding-cert-manager-controller-clusterissuers.yaml +@@ -17,4 +17,3 @@ subjects: + - name: cert-manager + namespace: "cert-manager" + kind: ServiceAccount +- +diff --git a/cert-manager/clusterrolebinding-cert-manager-controller-ingress-shim.yaml b/cert-manager/clusterrolebinding-cert-manager-controller-ingress-shim.yaml +index a8b2ba3..12059f9 100644 +--- a/cert-manager/clusterrolebinding-cert-manager-controller-ingress-shim.yaml ++++ b/cert-manager/clusterrolebinding-cert-manager-controller-ingress-shim.yaml +@@ -17,4 +17,3 @@ subjects: + - name: cert-manager + namespace: "cert-manager" + kind: ServiceAccount +- +diff --git a/cert-manager/clusterrolebinding-cert-manager-controller-issuers.yaml b/cert-manager/clusterrolebinding-cert-manager-controller-issuers.yaml +index b1ca638..646aed0 100644 +--- a/cert-manager/clusterrolebinding-cert-manager-controller-issuers.yaml ++++ b/cert-manager/clusterrolebinding-cert-manager-controller-issuers.yaml +@@ -17,4 +17,3 @@ subjects: + - name: cert-manager + namespace: "cert-manager" + kind: ServiceAccount +- +diff --git a/cert-manager/clusterrolebinding-cert-manager-controller-orders.yaml b/cert-manager/clusterrolebinding-cert-manager-controller-orders.yaml +index eb88a61..f083d0c 100644 +--- a/cert-manager/clusterrolebinding-cert-manager-controller-orders.yaml ++++ b/cert-manager/clusterrolebinding-cert-manager-controller-orders.yaml +@@ -17,4 +17,3 @@ subjects: + - name: cert-manager + namespace: "cert-manager" + kind: ServiceAccount +- +diff --git a/cert-manager/deployment-cert-manager.yaml b/cert-manager/deployment-cert-manager.yaml +index 0133262..cd4eabd 100644 +--- a/cert-manager/deployment-cert-manager.yaml ++++ b/cert-manager/deployment-cert-manager.yaml +@@ -32,27 +32,25 @@ spec: + spec: + serviceAccountName: cert-manager + securityContext: +- + runAsNonRoot: true + containers: + - name: cert-manager + image: "quay.io/jetstack/cert-manager-controller:v1.8.2" + imagePullPolicy: IfNotPresent + args: +- - --v=2 +- - --cluster-resource-namespace=$(POD_NAMESPACE) +- - --leader-election-namespace=kube-system ++ - --v=2 ++ - --cluster-resource-namespace=$(POD_NAMESPACE) ++ - --leader-election-namespace=kube-system + ports: +- - containerPort: 9402 +- name: http-metrics +- protocol: TCP ++ - containerPort: 9402 ++ name: http-metrics ++ protocol: TCP + securityContext: + allowPrivilegeEscalation: false + env: +- - name: POD_NAMESPACE +- valueFrom: +- fieldRef: +- fieldPath: metadata.namespace ++ - name: POD_NAMESPACE ++ valueFrom: ++ fieldRef: ++ fieldPath: metadata.namespace + nodeSelector: + kubernetes.io/os: linux +- +diff --git a/cert-manager/namespace-cert-manager.yaml b/cert-manager/namespace-cert-manager.yaml +index 4bd8eb7..2788051 100644 +--- a/cert-manager/namespace-cert-manager.yaml ++++ b/cert-manager/namespace-cert-manager.yaml +@@ -22,4 +22,3 @@ metadata: + app.kubernetes.io/instance: 'cert-manager' + # Generated labels + app.kubernetes.io/version: "v1.8.2" +- +diff --git a/cert-manager/role-cert-manager-leaderelection.yaml b/cert-manager/role-cert-manager-leaderelection.yaml +index cd7db33..197f63d 100644 +--- a/cert-manager/role-cert-manager-leaderelection.yaml ++++ b/cert-manager/role-cert-manager-leaderelection.yaml +@@ -18,4 +18,3 @@ rules: + - apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: ["create"] +- +diff --git a/cert-manager/rolebinding-cert-manager-leaderelection.yaml b/cert-manager/rolebinding-cert-manager-leaderelection.yaml +index f95b529..8e203ec 100644 +--- a/cert-manager/rolebinding-cert-manager-leaderelection.yaml ++++ b/cert-manager/rolebinding-cert-manager-leaderelection.yaml +@@ -21,4 +21,3 @@ subjects: + kind: ServiceAccount + name: cert-manager + namespace: cert-manager +- +diff --git a/cert-manager/service-cert-manager.yaml b/cert-manager/service-cert-manager.yaml +index 2f23d6c..f9c88c0 100644 +--- a/cert-manager/service-cert-manager.yaml ++++ b/cert-manager/service-cert-manager.yaml +@@ -21,4 +21,3 @@ spec: + app.kubernetes.io/name: cert-manager + app.kubernetes.io/instance: cert-manager + app.kubernetes.io/component: "controller" +- +diff --git a/cert-manager/serviceaccount-cert-manager.yaml b/cert-manager/serviceaccount-cert-manager.yaml +index 6a8e7ec..df96d78 100644 +--- a/cert-manager/serviceaccount-cert-manager.yaml ++++ b/cert-manager/serviceaccount-cert-manager.yaml +@@ -11,4 +11,3 @@ metadata: + app.kubernetes.io/instance: cert-manager + app.kubernetes.io/component: "controller" + app.kubernetes.io/version: "v1.8.2" +- +diff --git a/crds/customresourcedefinition-certificaterequests-cert-manager-io.yaml b/crds/customresourcedefinition-certificaterequests-cert-manager-io.yaml +index a5edbdc..da567d9 100644 +--- a/crds/customresourcedefinition-certificaterequests-cert-manager-io.yaml ++++ b/crds/customresourcedefinition-certificaterequests-cert-manager-io.yaml +@@ -197,4 +197,3 @@ spec: + format: date-time + served: true + storage: true +- +diff --git a/crds/customresourcedefinition-certificates-cert-manager-io.yaml b/crds/customresourcedefinition-certificates-cert-manager-io.yaml +index 077e165..c78c9f2 100644 +--- a/crds/customresourcedefinition-certificates-cert-manager-io.yaml ++++ b/crds/customresourcedefinition-certificates-cert-manager-io.yaml +@@ -367,4 +367,3 @@ spec: + type: integer + served: true + storage: true +- +diff --git a/crds/customresourcedefinition-challenges-acme-cert-manager-io.yaml b/crds/customresourcedefinition-challenges-acme-cert-manager-io.yaml +index 5f3b69b..4dec994 100644 +--- a/crds/customresourcedefinition-challenges-acme-cert-manager-io.yaml ++++ b/crds/customresourcedefinition-challenges-acme-cert-manager-io.yaml +@@ -1032,4 +1032,3 @@ spec: + storage: true + subresources: + status: {} +- +diff --git a/crds/customresourcedefinition-clusterissuers-cert-manager-io.yaml b/crds/customresourcedefinition-clusterissuers-cert-manager-io.yaml +index e3db794..23e95b5 100644 +--- a/crds/customresourcedefinition-clusterissuers-cert-manager-io.yaml ++++ b/crds/customresourcedefinition-clusterissuers-cert-manager-io.yaml +@@ -1247,4 +1247,3 @@ spec: + x-kubernetes-list-type: map + served: true + storage: true +- +diff --git a/crds/customresourcedefinition-issuers-cert-manager-io.yaml b/crds/customresourcedefinition-issuers-cert-manager-io.yaml +index 1f585ca..4e3e2c6 100644 +--- a/crds/customresourcedefinition-issuers-cert-manager-io.yaml ++++ b/crds/customresourcedefinition-issuers-cert-manager-io.yaml +@@ -1249,4 +1249,3 @@ spec: + x-kubernetes-list-type: map + served: true + storage: true +- +diff --git a/crds/customresourcedefinition-orders-acme-cert-manager-io.yaml b/crds/customresourcedefinition-orders-acme-cert-manager-io.yaml +index 7d4477f..b30190c 100644 +--- a/crds/customresourcedefinition-orders-acme-cert-manager-io.yaml ++++ b/crds/customresourcedefinition-orders-acme-cert-manager-io.yaml +@@ -181,4 +181,3 @@ spec: + type: string + served: true + storage: true +- +diff --git a/webhook/clusterrole-cert-manager-webhook-subjectaccessreviews.yaml b/webhook/clusterrole-cert-manager-webhook-subjectaccessreviews.yaml +index 4a62244..9d17db9 100644 +--- a/webhook/clusterrole-cert-manager-webhook-subjectaccessreviews.yaml ++++ b/webhook/clusterrole-cert-manager-webhook-subjectaccessreviews.yaml +@@ -13,4 +13,3 @@ rules: + - apiGroups: ["authorization.k8s.io"] + resources: ["subjectaccessreviews"] + verbs: ["create"] +- +diff --git a/webhook/clusterrolebinding-cert-manager-webhook-subjectaccessreviews.yaml b/webhook/clusterrolebinding-cert-manager-webhook-subjectaccessreviews.yaml +index 62c6733..40566cf 100644 +--- a/webhook/clusterrolebinding-cert-manager-webhook-subjectaccessreviews.yaml ++++ b/webhook/clusterrolebinding-cert-manager-webhook-subjectaccessreviews.yaml +@@ -18,4 +18,3 @@ subjects: + kind: ServiceAccount + name: cert-manager-webhook + namespace: cert-manager +- +diff --git a/webhook/configmap-cert-manager-webhook.yaml b/webhook/configmap-cert-manager-webhook.yaml +index 38cc4ec..d9dea58 100644 +--- a/webhook/configmap-cert-manager-webhook.yaml ++++ b/webhook/configmap-cert-manager-webhook.yaml +@@ -10,4 +10,3 @@ metadata: + app.kubernetes.io/instance: cert-manager + app.kubernetes.io/component: "webhook" + data: +- +diff --git a/webhook/deployment-cert-manager-webhook.yaml b/webhook/deployment-cert-manager-webhook.yaml +index ae62549..04d473b 100644 +--- a/webhook/deployment-cert-manager-webhook.yaml ++++ b/webhook/deployment-cert-manager-webhook.yaml +@@ -34,15 +34,15 @@ spec: + image: "quay.io/jetstack/cert-manager-webhook:v1.8.2" + imagePullPolicy: IfNotPresent + args: +- - --v=2 +- - --secure-port=10250 +- - --dynamic-serving-ca-secret-namespace=$(POD_NAMESPACE) +- - --dynamic-serving-ca-secret-name=cert-manager-webhook-ca +- - --dynamic-serving-dns-names=cert-manager-webhook,cert-manager-webhook.cert-manager,cert-manager-webhook.cert-manager.svc ++ - --v=2 ++ - --secure-port=10250 ++ - --dynamic-serving-ca-secret-namespace=$(POD_NAMESPACE) ++ - --dynamic-serving-ca-secret-name=cert-manager-webhook-ca ++ - --dynamic-serving-dns-names=cert-manager-webhook,cert-manager-webhook.cert-manager,cert-manager-webhook.cert-manager.svc + ports: +- - name: https +- protocol: TCP +- containerPort: 10250 ++ - name: https ++ protocol: TCP ++ containerPort: 10250 + livenessProbe: + httpGet: + path: /livez +@@ -66,10 +66,9 @@ spec: + securityContext: + allowPrivilegeEscalation: false + env: +- - name: POD_NAMESPACE +- valueFrom: +- fieldRef: +- fieldPath: metadata.namespace ++ - name: POD_NAMESPACE ++ valueFrom: ++ fieldRef: ++ fieldPath: metadata.namespace + nodeSelector: + kubernetes.io/os: linux +- +diff --git a/webhook/mutatingwebhookconfiguration-cert-manager-webhook.yaml b/webhook/mutatingwebhookconfiguration-cert-manager-webhook.yaml +index 419f238..21794ef 100644 +--- a/webhook/mutatingwebhookconfiguration-cert-manager-webhook.yaml ++++ b/webhook/mutatingwebhookconfiguration-cert-manager-webhook.yaml +@@ -38,4 +38,3 @@ webhooks: + name: cert-manager-webhook + namespace: "cert-manager" + path: /mutate +- +diff --git a/webhook/role-cert-manager-webhook-dynamic-serving.yaml b/webhook/role-cert-manager-webhook-dynamic-serving.yaml +index 59809b4..5e79aba 100644 +--- a/webhook/role-cert-manager-webhook-dynamic-serving.yaml ++++ b/webhook/role-cert-manager-webhook-dynamic-serving.yaml +@@ -20,4 +20,3 @@ rules: + - apiGroups: [""] + resources: ["secrets"] + verbs: ["create"] +- +diff --git a/webhook/rolebinding-cert-manager-webhook-dynamic-serving.yaml b/webhook/rolebinding-cert-manager-webhook-dynamic-serving.yaml +index 1a87590..c4596c5 100644 +--- a/webhook/rolebinding-cert-manager-webhook-dynamic-serving.yaml ++++ b/webhook/rolebinding-cert-manager-webhook-dynamic-serving.yaml +@@ -19,4 +19,3 @@ subjects: + kind: ServiceAccount + name: cert-manager-webhook + namespace: cert-manager +- +diff --git a/webhook/service-cert-manager-webhook.yaml b/webhook/service-cert-manager-webhook.yaml +index 9f75c78..5b2dd8c 100644 +--- a/webhook/service-cert-manager-webhook.yaml ++++ b/webhook/service-cert-manager-webhook.yaml +@@ -21,4 +21,3 @@ spec: + app.kubernetes.io/name: webhook + app.kubernetes.io/instance: cert-manager + app.kubernetes.io/component: "webhook" +- +diff --git a/webhook/serviceaccount-cert-manager-webhook.yaml b/webhook/serviceaccount-cert-manager-webhook.yaml +index 3ad5647..a66c791 100644 +--- a/webhook/serviceaccount-cert-manager-webhook.yaml ++++ b/webhook/serviceaccount-cert-manager-webhook.yaml +@@ -11,4 +11,3 @@ metadata: + app.kubernetes.io/instance: cert-manager + app.kubernetes.io/component: "webhook" + app.kubernetes.io/version: "v1.8.2" +- +diff --git a/webhook/validatingwebhookconfiguration-cert-manager-webhook.yaml b/webhook/validatingwebhookconfiguration-cert-manager-webhook.yaml +index 5aa546f..ddb7823 100644 +--- a/webhook/validatingwebhookconfiguration-cert-manager-webhook.yaml ++++ b/webhook/validatingwebhookconfiguration-cert-manager-webhook.yaml +@@ -15,14 +15,14 @@ webhooks: + - name: webhook.cert-manager.io + namespaceSelector: + matchExpressions: +- - key: "cert-manager.io/disable-validation" +- operator: "NotIn" +- values: +- - "true" +- - key: "name" +- operator: "NotIn" +- values: +- - cert-manager ++ - key: "cert-manager.io/disable-validation" ++ operator: "NotIn" ++ values: ++ - "true" ++ - key: "name" ++ operator: "NotIn" ++ values: ++ - cert-manager + rules: + - apiGroups: + - "cert-manager.io" +@@ -47,4 +47,3 @@ webhooks: + name: cert-manager-webhook + namespace: "cert-manager" + path: /validate +- diff --git a/e2e/testdata/package-examples/cert-manager-basic/.krmignore b/e2e/testdata/package-examples/cert-manager-basic/.krmignore new file mode 100644 index 0000000000..9d7a4007d6 --- /dev/null +++ b/e2e/testdata/package-examples/cert-manager-basic/.krmignore @@ -0,0 +1 @@ +.expected diff --git a/e2e/testdata/package-examples/ghost/.expected/config.yaml b/e2e/testdata/package-examples/ghost/.expected/config.yaml new file mode 100644 index 0000000000..e264d4aea6 --- /dev/null +++ b/e2e/testdata/package-examples/ghost/.expected/config.yaml @@ -0,0 +1 @@ +exitCode: 0 diff --git a/e2e/testdata/package-examples/ghost/.expected/diff.patch b/e2e/testdata/package-examples/ghost/.expected/diff.patch new file mode 100644 index 0000000000..8296c90c30 --- /dev/null +++ b/e2e/testdata/package-examples/ghost/.expected/diff.patch @@ -0,0 +1,37 @@ +diff --git a/Kptfile b/Kptfile +index 3701834..4ea9a98 100644 +--- a/Kptfile ++++ b/Kptfile +@@ -10,3 +10,32 @@ pipeline: + mutators: + - image: ghcr.io/kptdev/krm-functions-catalog/set-namespace:latest + configPath: package-context.yaml ++status: ++ conditions: ++ - type: Rendered ++ status: "True" ++ reason: RenderSuccess ++ renderStatus: ++ mutationSteps: ++ - image: ghcr.io/kptdev/krm-functions-catalog/set-labels:latest ++ exitCode: 0 ++ results: ++ - message: set 7 labels in total ++ severity: info ++ - image: ghcr.io/kptdev/krm-functions-catalog/apply-replacements:latest ++ exitCode: 0 ++ - image: ghcr.io/kptdev/krm-functions-catalog/set-labels:latest ++ exitCode: 0 ++ results: ++ - message: set 9 labels in total ++ severity: info ++ - image: ghcr.io/kptdev/krm-functions-catalog/set-namespace:latest ++ exitCode: 0 ++ results: ++ - message: all matching namespaces are already "example". no value changed ++ severity: info ++ - message: all `depends-on` annotations are up-to-date. no `namespace` changed ++ severity: info ++ validationSteps: ++ - image: ghcr.io/kptdev/krm-functions-catalog/starlark:latest ++ exitCode: 0 diff --git a/e2e/testdata/package-examples/ghost/.krmignore b/e2e/testdata/package-examples/ghost/.krmignore new file mode 100644 index 0000000000..9d7a4007d6 --- /dev/null +++ b/e2e/testdata/package-examples/ghost/.krmignore @@ -0,0 +1 @@ +.expected diff --git a/e2e/testdata/package-examples/guestbook/.expected/config.yaml b/e2e/testdata/package-examples/guestbook/.expected/config.yaml new file mode 100644 index 0000000000..e264d4aea6 --- /dev/null +++ b/e2e/testdata/package-examples/guestbook/.expected/config.yaml @@ -0,0 +1 @@ +exitCode: 0 diff --git a/e2e/testdata/package-examples/guestbook/.expected/diff.patch b/e2e/testdata/package-examples/guestbook/.expected/diff.patch new file mode 100644 index 0000000000..0bf9f5addf --- /dev/null +++ b/e2e/testdata/package-examples/guestbook/.expected/diff.patch @@ -0,0 +1,141 @@ +diff --git a/Kptfile b/Kptfile +index 88bbc4a..3ae69ec 100644 +--- a/Kptfile ++++ b/Kptfile +@@ -9,17 +9,50 @@ info: + pipeline: + mutators: + - image: ghcr.io/kptdev/krm-functions-catalog/create-setters:v0.1 +- selectors: +- - kind: Namespace + configMap: + namespace: default +- - image: ghcr.io/kptdev/krm-functions-catalog/apply-setters:v0.2 + selectors: + - kind: Namespace ++ - image: ghcr.io/kptdev/krm-functions-catalog/apply-setters:v0.2 + configMap: + namespace: default ++ selectors: ++ - kind: Namespace + - image: ghcr.io/kptdev/krm-functions-catalog/set-namespace:v0.4 + configMap: + namespace: default + validators: + - image: ghcr.io/kptdev/krm-functions-catalog/kubeconform:v0.1 ++status: ++ conditions: ++ - type: Rendered ++ status: "True" ++ reason: RenderSuccess ++ renderStatus: ++ mutationSteps: ++ - image: ghcr.io/kptdev/krm-functions-catalog/create-setters:v0.1 ++ exitCode: 0 ++ results: ++ - message: 'Added line comment "kpt-set: ${namespace}" for field with value "default"' ++ field: ++ path: metadata.name ++ file: ++ path: namespace.yaml ++ - image: ghcr.io/kptdev/krm-functions-catalog/apply-setters:v0.2 ++ exitCode: 0 ++ results: ++ - message: set field value to "default" ++ field: ++ path: metadata.name ++ file: ++ path: namespace.yaml ++ - image: ghcr.io/kptdev/krm-functions-catalog/set-namespace:v0.4 ++ exitCode: 0 ++ results: ++ - message: all matching namespaces are already "default". no value changed ++ severity: info ++ - message: all `depends-on` annotations are up-to-date. no `namespace` changed ++ severity: info ++ validationSteps: ++ - image: ghcr.io/kptdev/krm-functions-catalog/kubeconform:v0.1 ++ exitCode: 0 +diff --git a/frontend/frontend-deployment.yaml b/frontend/frontend-deployment.yaml +index 3e0fa39..083176c 100644 +--- a/frontend/frontend-deployment.yaml ++++ b/frontend/frontend-deployment.yaml +@@ -2,6 +2,7 @@ apiVersion: apps/v1 + kind: Deployment + metadata: + name: frontend ++ namespace: default + spec: + replicas: 3 + selector: +diff --git a/frontend/frontend-service.yaml b/frontend/frontend-service.yaml +index ba3471c..02f05a3 100644 +--- a/frontend/frontend-service.yaml ++++ b/frontend/frontend-service.yaml +@@ -5,6 +5,7 @@ metadata: + labels: + app: guestbook + tier: frontend ++ namespace: default + spec: + type: LoadBalancer + ports: +diff --git a/namespace.yaml b/namespace.yaml +index cf6d1f2..99bfad8 100644 +--- a/namespace.yaml ++++ b/namespace.yaml +@@ -1,4 +1,4 @@ + apiVersion: v1 + kind: Namespace + metadata: +- name: default +\ No newline at end of file ++ name: default # kpt-set: ${namespace} +diff --git a/redis/redis-follower-deployment.yaml b/redis/redis-follower-deployment.yaml +index abfb29c..c376757 100644 +--- a/redis/redis-follower-deployment.yaml ++++ b/redis/redis-follower-deployment.yaml +@@ -6,6 +6,7 @@ metadata: + app: redis + role: follower + tier: backend ++ namespace: default + spec: + replicas: 2 + selector: +diff --git a/redis/redis-follower-service.yaml b/redis/redis-follower-service.yaml +index 14a2c1d..93c3683 100644 +--- a/redis/redis-follower-service.yaml ++++ b/redis/redis-follower-service.yaml +@@ -6,6 +6,7 @@ metadata: + app: redis + role: follower + tier: backend ++ namespace: default + spec: + ports: + # the port that this service should serve on +diff --git a/redis/redis-leader-deployment.yaml b/redis/redis-leader-deployment.yaml +index f6a88f4..a08f585 100644 +--- a/redis/redis-leader-deployment.yaml ++++ b/redis/redis-leader-deployment.yaml +@@ -6,6 +6,7 @@ metadata: + app: redis + role: leader + tier: backend ++ namespace: default + spec: + replicas: 1 + selector: +diff --git a/redis/redis-leader-service.yaml b/redis/redis-leader-service.yaml +index 4c124f0..72af1f3 100644 +--- a/redis/redis-leader-service.yaml ++++ b/redis/redis-leader-service.yaml +@@ -6,6 +6,7 @@ metadata: + app: redis + role: leader + tier: backend ++ namespace: default + spec: + ports: + - port: 6379 diff --git a/e2e/testdata/package-examples/guestbook/.krmignore b/e2e/testdata/package-examples/guestbook/.krmignore new file mode 100644 index 0000000000..9d7a4007d6 --- /dev/null +++ b/e2e/testdata/package-examples/guestbook/.krmignore @@ -0,0 +1 @@ +.expected diff --git a/e2e/testdata/package-examples/ingress-nginx/.expected/config.yaml b/e2e/testdata/package-examples/ingress-nginx/.expected/config.yaml new file mode 100644 index 0000000000..e264d4aea6 --- /dev/null +++ b/e2e/testdata/package-examples/ingress-nginx/.expected/config.yaml @@ -0,0 +1 @@ +exitCode: 0 diff --git a/e2e/testdata/package-examples/ingress-nginx/.expected/diff.patch b/e2e/testdata/package-examples/ingress-nginx/.expected/diff.patch new file mode 100644 index 0000000000..11a5436c0b --- /dev/null +++ b/e2e/testdata/package-examples/ingress-nginx/.expected/diff.patch @@ -0,0 +1,184 @@ +diff --git a/Kptfile b/Kptfile +index efb547b..24a6944 100644 +--- a/Kptfile ++++ b/Kptfile +@@ -6,3 +6,8 @@ metadata: + config.kubernetes.io/local-config: "true" + info: + description: sample description ++status: ++ conditions: ++ - type: Rendered ++ status: "True" ++ reason: RenderSuccess +diff --git a/admission-webhook/clusterrole-ingress-nginx-admission.yaml b/admission-webhook/clusterrole-ingress-nginx-admission.yaml +index 6fd0e8e..930aad2 100644 +--- a/admission-webhook/clusterrole-ingress-nginx-admission.yaml ++++ b/admission-webhook/clusterrole-ingress-nginx-admission.yaml +@@ -16,4 +16,3 @@ rules: + verbs: + - get + - update +- +diff --git a/admission-webhook/clusterrolebinding-ingress-nginx-admission.yaml b/admission-webhook/clusterrolebinding-ingress-nginx-admission.yaml +index 05849b9..8c8b0de 100644 +--- a/admission-webhook/clusterrolebinding-ingress-nginx-admission.yaml ++++ b/admission-webhook/clusterrolebinding-ingress-nginx-admission.yaml +@@ -16,4 +16,3 @@ subjects: + - kind: ServiceAccount + name: ingress-nginx-admission + namespace: ingress-nginx +- +diff --git a/admission-webhook/job-ingress-nginx-admission-create.yaml b/admission-webhook/job-ingress-nginx-admission-create.yaml +index 3d13a42..42108d9 100644 +--- a/admission-webhook/job-ingress-nginx-admission-create.yaml ++++ b/admission-webhook/job-ingress-nginx-admission-create.yaml +@@ -44,4 +44,3 @@ spec: + runAsNonRoot: true + runAsUser: 2000 + serviceAccountName: ingress-nginx-admission +- +diff --git a/admission-webhook/job-ingress-nginx-admission-patch.yaml b/admission-webhook/job-ingress-nginx-admission-patch.yaml +index 36ba4f0..55897a9 100644 +--- a/admission-webhook/job-ingress-nginx-admission-patch.yaml ++++ b/admission-webhook/job-ingress-nginx-admission-patch.yaml +@@ -46,4 +46,3 @@ spec: + runAsNonRoot: true + runAsUser: 2000 + serviceAccountName: ingress-nginx-admission +- +diff --git a/admission-webhook/role-ingress-nginx-admission.yaml b/admission-webhook/role-ingress-nginx-admission.yaml +index 7d45572..8f77f52 100644 +--- a/admission-webhook/role-ingress-nginx-admission.yaml ++++ b/admission-webhook/role-ingress-nginx-admission.yaml +@@ -17,4 +17,3 @@ rules: + verbs: + - get + - create +- +diff --git a/admission-webhook/rolebinding-ingress-nginx-admission.yaml b/admission-webhook/rolebinding-ingress-nginx-admission.yaml +index 347d092..b804674 100644 +--- a/admission-webhook/rolebinding-ingress-nginx-admission.yaml ++++ b/admission-webhook/rolebinding-ingress-nginx-admission.yaml +@@ -17,4 +17,3 @@ subjects: + - kind: ServiceAccount + name: ingress-nginx-admission + namespace: ingress-nginx +- +diff --git a/admission-webhook/serviceaccount-ingress-nginx-admission.yaml b/admission-webhook/serviceaccount-ingress-nginx-admission.yaml +index 8730444..b1c650e 100644 +--- a/admission-webhook/serviceaccount-ingress-nginx-admission.yaml ++++ b/admission-webhook/serviceaccount-ingress-nginx-admission.yaml +@@ -9,4 +9,3 @@ metadata: + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx-admission + namespace: ingress-nginx +- +diff --git a/admission-webhook/validatingwebhookconfiguration-ingress-nginx-admission.yaml b/admission-webhook/validatingwebhookconfiguration-ingress-nginx-admission.yaml +index e77ab00..bc6b9f1 100644 +--- a/admission-webhook/validatingwebhookconfiguration-ingress-nginx-admission.yaml ++++ b/admission-webhook/validatingwebhookconfiguration-ingress-nginx-admission.yaml +@@ -30,4 +30,3 @@ webhooks: + resources: + - ingresses + sideEffects: None +- +diff --git a/controller/clusterrole-ingress-nginx.yaml b/controller/clusterrole-ingress-nginx.yaml +index 998a94e..5ae596a 100644 +--- a/controller/clusterrole-ingress-nginx.yaml ++++ b/controller/clusterrole-ingress-nginx.yaml +@@ -71,4 +71,3 @@ rules: + - get + - list + - watch +- +diff --git a/controller/clusterrolebinding-ingress-nginx.yaml b/controller/clusterrolebinding-ingress-nginx.yaml +index 868bd7a..658f8dc 100644 +--- a/controller/clusterrolebinding-ingress-nginx.yaml ++++ b/controller/clusterrolebinding-ingress-nginx.yaml +@@ -16,4 +16,3 @@ subjects: + - kind: ServiceAccount + name: ingress-nginx + namespace: ingress-nginx +- +diff --git a/controller/configmap-ingress-nginx-controller.yaml b/controller/configmap-ingress-nginx-controller.yaml +index b0192ab..666a899 100644 +--- a/controller/configmap-ingress-nginx-controller.yaml ++++ b/controller/configmap-ingress-nginx-controller.yaml +@@ -11,4 +11,3 @@ metadata: + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx-controller + namespace: ingress-nginx +- +diff --git a/controller/deployment-ingress-nginx-controller.yaml b/controller/deployment-ingress-nginx-controller.yaml +index a81fe40..6502d30 100644 +--- a/controller/deployment-ingress-nginx-controller.yaml ++++ b/controller/deployment-ingress-nginx-controller.yaml +@@ -109,4 +109,3 @@ spec: + - name: webhook-cert + secret: + secretName: ingress-nginx-admission +- +diff --git a/controller/ingressclass-nginx.yaml b/controller/ingressclass-nginx.yaml +index fa3ca43..99b4ec4 100644 +--- a/controller/ingressclass-nginx.yaml ++++ b/controller/ingressclass-nginx.yaml +@@ -10,4 +10,3 @@ metadata: + name: nginx + spec: + controller: k8s.io/ingress-nginx +- +diff --git a/controller/namespace-ingress-nginx.yaml b/controller/namespace-ingress-nginx.yaml +index b2e697c..6869a24 100644 +--- a/controller/namespace-ingress-nginx.yaml ++++ b/controller/namespace-ingress-nginx.yaml +@@ -6,4 +6,3 @@ metadata: + app.kubernetes.io/name: ingress-nginx + app.kubernetes.io/component: controller + name: ingress-nginx +- +diff --git a/controller/role-ingress-nginx.yaml b/controller/role-ingress-nginx.yaml +index bcf8929..ca27a85 100644 +--- a/controller/role-ingress-nginx.yaml ++++ b/controller/role-ingress-nginx.yaml +@@ -94,4 +94,3 @@ rules: + verbs: + - create + - patch +- +diff --git a/controller/rolebinding-ingress-nginx.yaml b/controller/rolebinding-ingress-nginx.yaml +index eeb75f1..dcc3607 100644 +--- a/controller/rolebinding-ingress-nginx.yaml ++++ b/controller/rolebinding-ingress-nginx.yaml +@@ -17,4 +17,3 @@ subjects: + - kind: ServiceAccount + name: ingress-nginx + namespace: ingress-nginx +- +diff --git a/controller/service-ingress-nginx-controller-admission.yaml b/controller/service-ingress-nginx-controller-admission.yaml +index 35fc1d6..2e87600 100644 +--- a/controller/service-ingress-nginx-controller-admission.yaml ++++ b/controller/service-ingress-nginx-controller-admission.yaml +@@ -20,4 +20,3 @@ spec: + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + type: ClusterIP +- +diff --git a/controller/service-ingress-nginx-controller.yaml b/controller/service-ingress-nginx-controller.yaml +index 497c6c9..1b5da16 100644 +--- a/controller/service-ingress-nginx-controller.yaml ++++ b/controller/service-ingress-nginx-controller.yaml +@@ -27,4 +27,3 @@ spec: + app.kubernetes.io/instance: ingress-nginx + app.kubernetes.io/name: ingress-nginx + type: LoadBalancer +- +diff --git a/controller/serviceaccount-ingress-nginx.yaml b/controller/serviceaccount-ingress-nginx.yaml +index 30371bf..a30617f 100644 +--- a/controller/serviceaccount-ingress-nginx.yaml ++++ b/controller/serviceaccount-ingress-nginx.yaml +@@ -10,4 +10,3 @@ metadata: + app.kubernetes.io/version: 1.3.0 + name: ingress-nginx + namespace: ingress-nginx +- diff --git a/e2e/testdata/package-examples/ingress-nginx/.krmignore b/e2e/testdata/package-examples/ingress-nginx/.krmignore new file mode 100644 index 0000000000..9d7a4007d6 --- /dev/null +++ b/e2e/testdata/package-examples/ingress-nginx/.krmignore @@ -0,0 +1 @@ +.expected diff --git a/e2e/testdata/package-examples/kustomize/.expected/config.yaml b/e2e/testdata/package-examples/kustomize/.expected/config.yaml new file mode 100644 index 0000000000..e264d4aea6 --- /dev/null +++ b/e2e/testdata/package-examples/kustomize/.expected/config.yaml @@ -0,0 +1 @@ +exitCode: 0 diff --git a/e2e/testdata/package-examples/kustomize/.expected/diff.patch b/e2e/testdata/package-examples/kustomize/.expected/diff.patch new file mode 100644 index 0000000000..4d6f12247e --- /dev/null +++ b/e2e/testdata/package-examples/kustomize/.expected/diff.patch @@ -0,0 +1,39 @@ +diff --git a/Kptfile b/Kptfile +index 380fe6c..f07be93 100644 +--- a/Kptfile ++++ b/Kptfile +@@ -4,3 +4,12 @@ metadata: + name: kustomize-pkg + info: + description: kustomize kpt package ++status: ++ conditions: ++ - type: Rendered ++ status: "True" ++ reason: RenderSuccess ++ renderStatus: ++ validationSteps: ++ - image: ghcr.io/kptdev/krm-functions-catalog/kubeconform:latest ++ exitCode: 0 +diff --git a/overlays/dev/kustomization.yaml b/overlays/dev/kustomization.yaml +index 05b5c2f..50eddd0 100644 +--- a/overlays/dev/kustomization.yaml ++++ b/overlays/dev/kustomization.yaml +@@ -24,5 +24,5 @@ patches: + target: + kind: Deployment + commonLabels: +- environ: dev ++ environ: dev + namePrefix: dev- +diff --git a/overlays/prod/kustomization.yaml b/overlays/prod/kustomization.yaml +index ca8c54e..3cd2ba3 100644 +--- a/overlays/prod/kustomization.yaml ++++ b/overlays/prod/kustomization.yaml +@@ -24,5 +24,5 @@ patches: + target: + kind: Deployment + commonLabels: +- environ: prod ++ environ: prod + namePrefix: prod- diff --git a/e2e/testdata/package-examples/kustomize/.krmignore b/e2e/testdata/package-examples/kustomize/.krmignore new file mode 100644 index 0000000000..9d7a4007d6 --- /dev/null +++ b/e2e/testdata/package-examples/kustomize/.krmignore @@ -0,0 +1 @@ +.expected diff --git a/e2e/testdata/package-examples/nginx/.expected/config.yaml b/e2e/testdata/package-examples/nginx/.expected/config.yaml new file mode 100644 index 0000000000..e264d4aea6 --- /dev/null +++ b/e2e/testdata/package-examples/nginx/.expected/config.yaml @@ -0,0 +1 @@ +exitCode: 0 diff --git a/e2e/testdata/package-examples/nginx/.expected/diff.patch b/e2e/testdata/package-examples/nginx/.expected/diff.patch new file mode 100644 index 0000000000..15ac939ce9 --- /dev/null +++ b/e2e/testdata/package-examples/nginx/.expected/diff.patch @@ -0,0 +1,17 @@ +diff --git a/Kptfile b/Kptfile +index 2942092..e7b7790 100644 +--- a/Kptfile ++++ b/Kptfile +@@ -11,3 +11,12 @@ pipeline: + - image: ghcr.io/kptdev/krm-functions-catalog/kubeconform:latest + configMap: + strict: "true" ++status: ++ conditions: ++ - type: Rendered ++ status: "True" ++ reason: RenderSuccess ++ renderStatus: ++ validationSteps: ++ - image: ghcr.io/kptdev/krm-functions-catalog/kubeconform:latest ++ exitCode: 0 diff --git a/e2e/testdata/package-examples/nginx/.krmignore b/e2e/testdata/package-examples/nginx/.krmignore new file mode 100644 index 0000000000..9d7a4007d6 --- /dev/null +++ b/e2e/testdata/package-examples/nginx/.krmignore @@ -0,0 +1 @@ +.expected diff --git a/e2e/testdata/package-examples/tenant/.expected/config.yaml b/e2e/testdata/package-examples/tenant/.expected/config.yaml new file mode 100644 index 0000000000..e264d4aea6 --- /dev/null +++ b/e2e/testdata/package-examples/tenant/.expected/config.yaml @@ -0,0 +1 @@ +exitCode: 0 diff --git a/e2e/testdata/package-examples/tenant/.expected/diff.patch b/e2e/testdata/package-examples/tenant/.expected/diff.patch new file mode 100644 index 0000000000..b5c7a4ab1c --- /dev/null +++ b/e2e/testdata/package-examples/tenant/.expected/diff.patch @@ -0,0 +1,99 @@ +diff --git a/Kptfile b/Kptfile +index dedb208..a441383 100644 +--- a/Kptfile ++++ b/Kptfile +@@ -12,3 +12,20 @@ pipeline: + validators: + - image: ghcr.io/kptdev/krm-functions-catalog/starlark:latest + configPath: ns-invariant.yaml ++status: ++ conditions: ++ - type: Rendered ++ status: "True" ++ reason: RenderSuccess ++ renderStatus: ++ mutationSteps: ++ - image: ghcr.io/kptdev/krm-functions-catalog/set-namespace:latest ++ exitCode: 0 ++ results: ++ - message: all matching namespaces are already "tenant-name". no value changed ++ severity: info ++ - message: all `depends-on` annotations are up-to-date. no `namespace` changed ++ severity: info ++ validationSteps: ++ - image: ghcr.io/kptdev/krm-functions-catalog/starlark:latest ++ exitCode: 0 +diff --git a/namespace.yaml b/namespace.yaml +index ac09027..3764d5f 100644 +--- a/namespace.yaml ++++ b/namespace.yaml +@@ -11,7 +11,6 @@ + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. +- + apiVersion: v1 + kind: Namespace + metadata: +diff --git a/ns-invariant.yaml b/ns-invariant.yaml +index f233cc8..3079e9b 100644 +--- a/ns-invariant.yaml ++++ b/ns-invariant.yaml +@@ -11,19 +11,8 @@ + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. +- + apiVersion: fn.kpt.dev/v1alpha1 + kind: StarlarkRun + metadata: + name: ns-invariant +-source: | +- def ensure_one_namespace(resource_list): +- num_ns = 0 +- for resource in resource_list["items"]: +- if resource["apiVersion"] == "v1" and resource["kind"] == "Namespace": +- num_ns += 1 +- # only one namespace is allowed +- if num_ns > 1: +- fail("pkg must contain single namespace") +- +- ensure_one_namespace(ctx.resource_list) +\ No newline at end of file ++source: "def ensure_one_namespace(resource_list):\n num_ns = 0\n for resource in resource_list[\"items\"]:\n if resource[\"apiVersion\"] == \"v1\" and resource[\"kind\"] == \"Namespace\":\n num_ns += 1\n # only one namespace is allowed\n if num_ns > 1:\n fail(\"pkg must contain single namespace\") \n\nensure_one_namespace(ctx.resource_list)" +diff --git a/quota.yaml b/quota.yaml +index c0b7b18..96f2090 100644 +--- a/quota.yaml ++++ b/quota.yaml +@@ -11,7 +11,6 @@ + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. +- + apiVersion: v1 + kind: ResourceQuota + metadata: +diff --git a/role-binding.yaml b/role-binding.yaml +index bb5ccb3..b57e59f 100644 +--- a/role-binding.yaml ++++ b/role-binding.yaml +@@ -11,7 +11,6 @@ + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. +- + apiVersion: rbac.authorization.k8s.io/v1beta1 + kind: RoleBinding + metadata: +diff --git a/service-account.yaml b/service-account.yaml +index 0e37426..5b6be1f 100644 +--- a/service-account.yaml ++++ b/service-account.yaml +@@ -11,7 +11,6 @@ + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. +- + apiVersion: v1 + kind: ServiceAccount + metadata: diff --git a/e2e/testdata/package-examples/tenant/.krmignore b/e2e/testdata/package-examples/tenant/.krmignore new file mode 100644 index 0000000000..9d7a4007d6 --- /dev/null +++ b/e2e/testdata/package-examples/tenant/.krmignore @@ -0,0 +1 @@ +.expected diff --git a/e2e/testdata/package-examples/wordpress-with-dependencies/.expected/config.yaml b/e2e/testdata/package-examples/wordpress-with-dependencies/.expected/config.yaml new file mode 100644 index 0000000000..e264d4aea6 --- /dev/null +++ b/e2e/testdata/package-examples/wordpress-with-dependencies/.expected/config.yaml @@ -0,0 +1 @@ +exitCode: 0 diff --git a/e2e/testdata/package-examples/wordpress-with-dependencies/.expected/diff.patch b/e2e/testdata/package-examples/wordpress-with-dependencies/.expected/diff.patch new file mode 100644 index 0000000000..d1f378fd31 --- /dev/null +++ b/e2e/testdata/package-examples/wordpress-with-dependencies/.expected/diff.patch @@ -0,0 +1,99 @@ +diff --git a/Kptfile b/Kptfile +index acc145e..e93c3c7 100644 +--- a/Kptfile ++++ b/Kptfile +@@ -2,6 +2,8 @@ apiVersion: kpt.dev/v1 + kind: Kptfile + metadata: + name: wordpress-with-dependencies ++ labels: ++ app: wordpress + info: + emails: + - wily.e.coyote@theacmecorporation.com +@@ -13,3 +15,23 @@ pipeline: + app: wordpress + validators: + - image: ghcr.io/kptdev/krm-functions-catalog/kubeconform:latest ++status: ++ conditions: ++ - type: Rendered ++ status: "True" ++ reason: RenderSuccess ++ renderStatus: ++ mutationSteps: ++ - image: ghcr.io/kptdev/krm-functions-catalog/set-labels:latest ++ exitCode: 0 ++ results: ++ - message: set 8 labels in total ++ severity: info ++ - image: ghcr.io/kptdev/krm-functions-catalog/set-labels:latest ++ exitCode: 0 ++ results: ++ - message: set 14 labels in total ++ severity: info ++ validationSteps: ++ - image: ghcr.io/kptdev/krm-functions-catalog/kubeconform:latest ++ exitCode: 0 +diff --git a/mysql/Kptfile b/mysql/Kptfile +index 4ac971a..44c38c8 100644 +--- a/mysql/Kptfile ++++ b/mysql/Kptfile +@@ -2,6 +2,9 @@ apiVersion: kpt.dev/v1 + kind: Kptfile + metadata: + name: mysql ++ labels: ++ tier: mysql ++ app: wordpress + info: + emails: + - wily.e.coyote@theacmecorporation.com +diff --git a/mysql/statefulset.yaml b/mysql/statefulset.yaml +index ea1b6f2..9e517a3 100644 +--- a/mysql/statefulset.yaml ++++ b/mysql/statefulset.yaml +@@ -53,23 +53,26 @@ spec: + - name: mysql + image: mysql:9.5 + ports: +- - name: mysql +- protocol: TCP +- containerPort: 3306 ++ - name: mysql ++ protocol: TCP ++ containerPort: 3306 + env: +- - name: MYSQL_ROOT_PASSWORD +- valueFrom: +- secretKeyRef: +- name: mysql-pass +- key: password ++ - name: MYSQL_ROOT_PASSWORD ++ valueFrom: ++ secretKeyRef: ++ name: mysql-pass ++ key: password + volumeMounts: +- - name: wordpress-persistent-storage +- mountPath: /var/lib/mysql ++ - name: wordpress-persistent-storage ++ mountPath: /var/lib/mysql + volumeClaimTemplates: +- - metadata: +- name: wordpress-persistent-storage +- spec: +- accessModes: [ "ReadWriteOnce" ] +- resources: +- requests: +- storage: 1Gi ++ - metadata: ++ name: wordpress-persistent-storage ++ labels: ++ tier: mysql ++ app: wordpress ++ spec: ++ accessModes: ["ReadWriteOnce"] ++ resources: ++ requests: ++ storage: 1Gi diff --git a/e2e/testdata/package-examples/wordpress-with-dependencies/.krmignore b/e2e/testdata/package-examples/wordpress-with-dependencies/.krmignore new file mode 100644 index 0000000000..9d7a4007d6 --- /dev/null +++ b/e2e/testdata/package-examples/wordpress-with-dependencies/.krmignore @@ -0,0 +1 @@ +.expected diff --git a/e2e/testdata/package-examples/wordpress/.expected/config.yaml b/e2e/testdata/package-examples/wordpress/.expected/config.yaml new file mode 100644 index 0000000000..e264d4aea6 --- /dev/null +++ b/e2e/testdata/package-examples/wordpress/.expected/config.yaml @@ -0,0 +1 @@ +exitCode: 0 diff --git a/e2e/testdata/package-examples/wordpress/.expected/diff.patch b/e2e/testdata/package-examples/wordpress/.expected/diff.patch new file mode 100644 index 0000000000..097b0522ba --- /dev/null +++ b/e2e/testdata/package-examples/wordpress/.expected/diff.patch @@ -0,0 +1,51 @@ +diff --git a/Kptfile b/Kptfile +index b00b516..80569e7 100644 +--- a/Kptfile ++++ b/Kptfile +@@ -2,6 +2,8 @@ apiVersion: kpt.dev/v1 + kind: Kptfile + metadata: + name: wordpress ++ labels: ++ app: wordpress + info: + emails: + - wily.e.coyote@theacmecorporation.com +@@ -13,3 +15,23 @@ pipeline: + app: wordpress + validators: + - image: ghcr.io/kptdev/krm-functions-catalog/kubeconform:latest ++status: ++ conditions: ++ - type: Rendered ++ status: "True" ++ reason: RenderSuccess ++ renderStatus: ++ mutationSteps: ++ - image: ghcr.io/kptdev/krm-functions-catalog/set-labels:latest ++ exitCode: 0 ++ results: ++ - message: set 7 labels in total ++ severity: info ++ - image: ghcr.io/kptdev/krm-functions-catalog/set-labels:latest ++ exitCode: 0 ++ results: ++ - message: set 14 labels in total ++ severity: info ++ validationSteps: ++ - image: ghcr.io/kptdev/krm-functions-catalog/kubeconform:latest ++ exitCode: 0 +diff --git a/mysql/Kptfile b/mysql/Kptfile +index 4ac971a..44c38c8 100644 +--- a/mysql/Kptfile ++++ b/mysql/Kptfile +@@ -2,6 +2,9 @@ apiVersion: kpt.dev/v1 + kind: Kptfile + metadata: + name: mysql ++ labels: ++ tier: mysql ++ app: wordpress + info: + emails: + - wily.e.coyote@theacmecorporation.com diff --git a/e2e/testdata/package-examples/wordpress/.krmignore b/e2e/testdata/package-examples/wordpress/.krmignore new file mode 100644 index 0000000000..9d7a4007d6 --- /dev/null +++ b/e2e/testdata/package-examples/wordpress/.krmignore @@ -0,0 +1 @@ +.expected diff --git a/package-examples/tenant/ns-invariant.yaml b/package-examples/tenant/ns-invariant.yaml index 110c06246d..f233cc88e7 100644 --- a/package-examples/tenant/ns-invariant.yaml +++ b/package-examples/tenant/ns-invariant.yaml @@ -21,7 +21,7 @@ source: | num_ns = 0 for resource in resource_list["items"]: if resource["apiVersion"] == "v1" and resource["kind"] == "Namespace": - num_ns++ + num_ns += 1 # only one namespace is allowed if num_ns > 1: fail("pkg must contain single namespace")