From 5cf07bd912d82c7ef40923ba3cbfd20e726fd01c Mon Sep 17 00:00:00 2001 From: manasachi <144361666+manasachi@users.noreply.github.com> Date: Thu, 27 Jun 2024 16:01:31 -0400 Subject: [PATCH] Mchinta/renderhelm (#321) Signed-off-by: manasachi --- go.mod | 23 +- go.sum | 58 +++-- pkg/safeguards/preprocessing_helpers.go | 110 +++++++++ pkg/safeguards/preprocessing_helpers_test.go | 227 ++++++++++++++++++ pkg/safeguards/testdata/resources.yaml | 41 ++++ pkg/safeguards/testdata/service-1.yaml | 11 + pkg/safeguards/testdata/service-2.yaml | 11 + .../different-structure/Chart.yaml | 5 + .../templates/_helpers.tpl | 12 + .../templates/deployment.yaml | 24 ++ .../templates/service.yaml | 13 + .../different-structure/values.yaml | 22 ++ .../expected-helpers-deployment.yaml | 30 +++ .../expected-helpers-service.yaml | 19 ++ .../testmanifests/expected-mainchart.yaml | 19 ++ .../testmanifests/expected-resources.yaml | 45 ++++ .../testmanifests/expected-subchart1.yaml | 19 ++ .../testmanifests/expected-subchart2.yaml | 19 ++ .../testmanifests/expecteddeployment.yaml | 18 ++ .../tests/testmanifests/expectedingress.yaml | 17 ++ .../tests/testmanifests/expectedservice.yaml | 11 + .../tests/testmanifests/expectedservice2.yaml | 11 + .../testmanifests/invalidchart/Chart.yaml | 2 + .../invalidchart/templates/deployment.yaml | 18 ++ .../testmanifests/invalidchart/values.yaml | 12 + .../invaliddeployment-syntax/Chart.yaml | 4 + .../templates/invaliddeploymentsyntax.yaml | 18 ++ .../invaliddeployment-syntax/values.yaml | 12 + .../invaliddeployment-values/Chart.yaml | 4 + .../templates/invaliddeploymentvalues.yaml | 18 ++ .../invaliddeployment-values/values.yaml | 12 + .../testmanifests/invalidvalues/Chart.yaml | 4 + .../invalidvalues/templates/service.yaml | 11 + .../testmanifests/invalidvalues/values.yaml | 9 + .../testmanifests/multiple-charts/Chart.yaml | 4 + .../charts/subchart1/Chart.yaml | 8 + .../subchart1/templates/deployment1.yaml | 19 ++ .../charts/subchart1/values.yaml | 6 + .../charts/subchart2/Chart.yaml | 4 + .../subchart2/templates/deployment2.yaml | 19 ++ .../charts/subchart2/values.yaml | 6 + .../templates/maindeployment.yaml | 19 ++ .../testmanifests/multiple-charts/values.yaml | 6 + .../multiple-templates/Chart.yaml | 4 + .../templates/resources.yaml | 44 ++++ .../templates/services/service-1.yaml | 11 + .../templates/services/service-2.yaml | 11 + .../multiple-templates/values.yaml | 16 ++ .../tests/testmanifests/validchart/Chart.yaml | 4 + .../validchart/templates/deployment.yaml | 18 ++ .../validchart/templates/ingress.yaml | 19 ++ .../validchart/templates/service.yaml | 11 + .../testmanifests/validchart/values.yaml | 12 + 53 files changed, 1093 insertions(+), 37 deletions(-) create mode 100644 pkg/safeguards/preprocessing_helpers.go create mode 100644 pkg/safeguards/preprocessing_helpers_test.go create mode 100644 pkg/safeguards/testdata/resources.yaml create mode 100644 pkg/safeguards/testdata/service-1.yaml create mode 100644 pkg/safeguards/testdata/service-2.yaml create mode 100644 pkg/safeguards/tests/testmanifests/different-structure/Chart.yaml create mode 100644 pkg/safeguards/tests/testmanifests/different-structure/templates/_helpers.tpl create mode 100644 pkg/safeguards/tests/testmanifests/different-structure/templates/deployment.yaml create mode 100644 pkg/safeguards/tests/testmanifests/different-structure/templates/service.yaml create mode 100644 pkg/safeguards/tests/testmanifests/different-structure/values.yaml create mode 100644 pkg/safeguards/tests/testmanifests/expected-helpers-deployment.yaml create mode 100644 pkg/safeguards/tests/testmanifests/expected-helpers-service.yaml create mode 100644 pkg/safeguards/tests/testmanifests/expected-mainchart.yaml create mode 100644 pkg/safeguards/tests/testmanifests/expected-resources.yaml create mode 100644 pkg/safeguards/tests/testmanifests/expected-subchart1.yaml create mode 100644 pkg/safeguards/tests/testmanifests/expected-subchart2.yaml create mode 100644 pkg/safeguards/tests/testmanifests/expecteddeployment.yaml create mode 100644 pkg/safeguards/tests/testmanifests/expectedingress.yaml create mode 100644 pkg/safeguards/tests/testmanifests/expectedservice.yaml create mode 100644 pkg/safeguards/tests/testmanifests/expectedservice2.yaml create mode 100644 pkg/safeguards/tests/testmanifests/invalidchart/Chart.yaml create mode 100644 pkg/safeguards/tests/testmanifests/invalidchart/templates/deployment.yaml create mode 100644 pkg/safeguards/tests/testmanifests/invalidchart/values.yaml create mode 100644 pkg/safeguards/tests/testmanifests/invaliddeployment-syntax/Chart.yaml create mode 100644 pkg/safeguards/tests/testmanifests/invaliddeployment-syntax/templates/invaliddeploymentsyntax.yaml create mode 100644 pkg/safeguards/tests/testmanifests/invaliddeployment-syntax/values.yaml create mode 100644 pkg/safeguards/tests/testmanifests/invaliddeployment-values/Chart.yaml create mode 100644 pkg/safeguards/tests/testmanifests/invaliddeployment-values/templates/invaliddeploymentvalues.yaml create mode 100644 pkg/safeguards/tests/testmanifests/invaliddeployment-values/values.yaml create mode 100644 pkg/safeguards/tests/testmanifests/invalidvalues/Chart.yaml create mode 100644 pkg/safeguards/tests/testmanifests/invalidvalues/templates/service.yaml create mode 100644 pkg/safeguards/tests/testmanifests/invalidvalues/values.yaml create mode 100644 pkg/safeguards/tests/testmanifests/multiple-charts/Chart.yaml create mode 100644 pkg/safeguards/tests/testmanifests/multiple-charts/charts/subchart1/Chart.yaml create mode 100644 pkg/safeguards/tests/testmanifests/multiple-charts/charts/subchart1/templates/deployment1.yaml create mode 100644 pkg/safeguards/tests/testmanifests/multiple-charts/charts/subchart1/values.yaml create mode 100644 pkg/safeguards/tests/testmanifests/multiple-charts/charts/subchart2/Chart.yaml create mode 100644 pkg/safeguards/tests/testmanifests/multiple-charts/charts/subchart2/templates/deployment2.yaml create mode 100644 pkg/safeguards/tests/testmanifests/multiple-charts/charts/subchart2/values.yaml create mode 100644 pkg/safeguards/tests/testmanifests/multiple-charts/templates/maindeployment.yaml create mode 100644 pkg/safeguards/tests/testmanifests/multiple-charts/values.yaml create mode 100644 pkg/safeguards/tests/testmanifests/multiple-templates/Chart.yaml create mode 100644 pkg/safeguards/tests/testmanifests/multiple-templates/templates/resources.yaml create mode 100644 pkg/safeguards/tests/testmanifests/multiple-templates/templates/services/service-1.yaml create mode 100644 pkg/safeguards/tests/testmanifests/multiple-templates/templates/services/service-2.yaml create mode 100644 pkg/safeguards/tests/testmanifests/multiple-templates/values.yaml create mode 100644 pkg/safeguards/tests/testmanifests/validchart/Chart.yaml create mode 100644 pkg/safeguards/tests/testmanifests/validchart/templates/deployment.yaml create mode 100644 pkg/safeguards/tests/testmanifests/validchart/templates/ingress.yaml create mode 100644 pkg/safeguards/tests/testmanifests/validchart/templates/service.yaml create mode 100644 pkg/safeguards/tests/testmanifests/validchart/values.yaml diff --git a/go.mod b/go.mod index 92744a31..dae86ca3 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,6 @@ go 1.22.0 require ( github.com/Azure/azure-sdk-for-go/sdk/azcore v1.11.1 github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.2 - github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization v1.0.0 github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/subscription/armsubscription v1.2.0 github.com/briandowns/spinner v1.23.0 github.com/cenkalti/backoff/v4 v4.3.0 @@ -16,7 +15,6 @@ require ( github.com/ivanpirog/coloredcobra v1.0.1 github.com/jbrukh/bayesian v0.0.0-20231117143245-13ae6f916c7a github.com/manifoldco/promptui v0.9.0 - github.com/microsoftgraph/msgraph-sdk-go v1.38.0 github.com/open-policy-agent/frameworks/constraint v0.0.0-20240516222118-7d1bd0255f52 github.com/open-policy-agent/gatekeeper/v3 v3.16.0 github.com/sirupsen/logrus v1.9.3 @@ -25,6 +23,7 @@ require ( go.uber.org/mock v0.4.0 golang.org/x/exp v0.0.0-20240416160154-fe59bbe5cc7f golang.org/x/mod v0.17.0 + gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v3 v3.0.1 helm.sh/helm/v3 v3.14.4 k8s.io/api v0.29.3 @@ -40,7 +39,10 @@ require ( github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2 // indirect github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 // indirect github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 // indirect + github.com/BurntSushi/toml v1.3.2 // indirect + github.com/Masterminds/goutils v1.1.1 // indirect github.com/Masterminds/semver/v3 v3.2.1 // indirect + github.com/Masterminds/sprig/v3 v3.2.3 // indirect github.com/Microsoft/hcsshim v0.11.4 // indirect github.com/OneOfOne/xxhash v1.2.8 // indirect github.com/agnivade/levenshtein v1.1.1 // indirect @@ -50,9 +52,9 @@ require ( github.com/blang/semver/v4 v4.0.0 // indirect github.com/cespare/xxhash/v2 v2.2.0 // indirect github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e // indirect - github.com/cjlapao/common-go v0.0.39 // indirect github.com/containerd/containerd v1.7.14 // indirect github.com/containerd/log v0.1.0 // indirect + github.com/cyphar/filepath-securejoin v0.2.4 // indirect github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/distribution/reference v0.5.0 // indirect github.com/docker/cli v25.0.1+incompatible // indirect @@ -87,6 +89,7 @@ require ( github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect + github.com/huandu/xstrings v1.4.0 // indirect github.com/imdario/mergo v0.3.13 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/josharian/intern v1.0.0 // indirect @@ -97,14 +100,8 @@ require ( github.com/mailru/easyjson v0.7.7 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect - github.com/microsoft/kiota-abstractions-go v1.6.0 // indirect - github.com/microsoft/kiota-authentication-azure-go v1.0.2 // indirect - github.com/microsoft/kiota-http-go v1.3.1 // indirect - github.com/microsoft/kiota-serialization-form-go v1.0.0 // indirect - github.com/microsoft/kiota-serialization-json-go v1.0.7 // indirect - github.com/microsoft/kiota-serialization-multipart-go v1.0.0 // indirect - github.com/microsoft/kiota-serialization-text-go v1.0.0 // indirect - github.com/microsoftgraph/msgraph-sdk-go-core v1.1.0 // indirect + github.com/mitchellh/copystructure v1.2.0 // indirect + github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/moby/locker v1.0.1 // indirect github.com/moby/term v0.5.0 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect @@ -122,8 +119,9 @@ require ( github.com/prometheus/common v0.48.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475 // indirect + github.com/shopspring/decimal v1.3.1 // indirect + github.com/spf13/cast v1.6.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/std-uritemplate/std-uritemplate/go v0.0.55 // indirect github.com/stoewer/go-strcase v1.2.0 // indirect github.com/tchap/go-patricia/v2 v2.3.1 // indirect github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect @@ -156,7 +154,6 @@ require ( google.golang.org/protobuf v1.33.0 // indirect gopkg.in/evanphx/json-patch.v4 v4.12.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect k8s.io/apiextensions-apiserver v0.29.3 // indirect k8s.io/apiserver v0.29.3 // indirect k8s.io/component-base v0.29.3 // indirect diff --git a/go.sum b/go.sum index 3240a37c..497df422 100644 --- a/go.sum +++ b/go.sum @@ -7,8 +7,6 @@ github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.2 h1:FDif4R1+UUR+00q6wquyX github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.5.2/go.mod h1:aiYBYui4BJ/BJCAIKs92XiPyQfTaBWqvHujDwKb6CBU= github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2 h1:LqbJ/WzJUwBf8UiaSzgX7aMclParm9/5Vgp+TY51uBQ= github.com/Azure/azure-sdk-for-go/sdk/internal v1.5.2/go.mod h1:yInRyqWXAuaPrgI7p70+lDDgh3mlBohis29jGMISnmc= -github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization v1.0.0 h1:qtRcg5Y7jNJ4jEzPq4GpWLfTspHdNe2ZK6LjwGcjgmU= -github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization v1.0.0/go.mod h1:lPneRe3TwsoDRKY4O6YDLXHhEWrD+TIRa8XrV/3/fqw= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/subscription/armsubscription v1.2.0 h1:UrGzkHueDwAWDdjQxC+QaXHd4tVCkISYE9j7fSSXF8k= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/subscription/armsubscription v1.2.0/go.mod h1:qskvSQeW+cxEE2bcKYyKimB1/KiQ9xpJ99bcHY0BX6c= github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1 h1:UQHMgLO+TxOElx5B5HZ4hJQsoJ/PvUvKRhJHDQXO8P8= @@ -16,8 +14,15 @@ github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg6 github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2 h1:XHOnouVk1mxXfQidrMEnLlPk9UMeRtyBTnEFtxkV0kU= github.com/AzureAD/microsoft-authentication-library-for-go v1.2.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8= +github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= +github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= +github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= github.com/Masterminds/semver/v3 v3.2.1 h1:RN9w6+7QoMeJVGyfmbcgs28Br8cvmnucEXnY0rYXWg0= github.com/Masterminds/semver/v3 v3.2.1/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ= +github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA= +github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/Microsoft/hcsshim v0.11.4 h1:68vKo2VN8DE9AdN4tnkWnmdhqdbpUFM8OF3Airm7fz8= @@ -67,8 +72,6 @@ github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5O github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/cjlapao/common-go v0.0.39 h1:bAAUrj2B9v0kMzbAOhzjSmiyDy+rd56r2sy7oEiQLlA= -github.com/cjlapao/common-go v0.0.39/go.mod h1:M3dzazLjTjEtZJbbxoA5ZDiGCiHmpwqW9l4UWaddwOA= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaDFBM= github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= @@ -87,6 +90,8 @@ github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46t github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY= github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4= +github.com/cyphar/filepath-securejoin v0.2.4 h1:Ugdm7cg7i6ZK6x3xDF1oEu1nfkyfH53EtKeQYTC3kyg= +github.com/cyphar/filepath-securejoin v0.2.4/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= @@ -139,6 +144,8 @@ github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8 github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= github.com/foxcpp/go-mockdns v1.1.0 h1:jI0rD8M0wuYAxL7r/ynTrCQQq0BVqfB99Vgk7DlmewI= github.com/foxcpp/go-mockdns v1.1.0/go.mod h1:IhLeSFGed3mJIAXPH2aiRQB+kqz7oqu8ld2qVbOu7Wk= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= @@ -221,6 +228,7 @@ github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJY github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4= @@ -243,6 +251,10 @@ github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09 github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v0.0.0-20180404174102-ef8a98b0bbce/go.mod h1:oZtUIOe8dh44I2q6ScRibXws4Ajl+d+nod3AaR9vL5w= +github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU= +github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= @@ -294,27 +306,15 @@ github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/microsoft/kiota-abstractions-go v1.6.0 h1:qbGBNMU0/o5myKbikCBXJFohVCFrrpx2cO15Rta2WyA= -github.com/microsoft/kiota-abstractions-go v1.6.0/go.mod h1:7YH20ZbRWXGfHSSvdHkdztzgCB9mRdtFx13+hrYIEpo= -github.com/microsoft/kiota-authentication-azure-go v1.0.2 h1:tClGeyFZJ+4Bakf8u0euPM4wqy4ethycdOgx3jyH3pI= -github.com/microsoft/kiota-authentication-azure-go v1.0.2/go.mod h1:aTcti0bUJEcq7kBfQG4Sr4ElvRNuaalXcFEu4iEyQ6M= -github.com/microsoft/kiota-http-go v1.3.1 h1:S+ZDxE7Pc/Z06hbfqpFHkoq5xiC8/7d12iNovcgl+7o= -github.com/microsoft/kiota-http-go v1.3.1/go.mod h1:4QjB+as08swnZXZLx5I+ZHZ8U/tVy7Zu49RNTmWgw48= -github.com/microsoft/kiota-serialization-form-go v1.0.0 h1:UNdrkMnLFqUCccQZerKjblsyVgifS11b3WCx+eFEsAI= -github.com/microsoft/kiota-serialization-form-go v1.0.0/go.mod h1:h4mQOO6KVTNciMF6azi1J9QB19ujSw3ULKcSNyXXOMA= -github.com/microsoft/kiota-serialization-json-go v1.0.7 h1:yMbckSTPrjZdM4EMXgzLZSA3CtDaUBI350u0VoYRz7Y= -github.com/microsoft/kiota-serialization-json-go v1.0.7/go.mod h1:1krrY7DYl3ivPIzl4xTaBpew6akYNa8/Tal8g+kb0cc= -github.com/microsoft/kiota-serialization-multipart-go v1.0.0 h1:3O5sb5Zj+moLBiJympbXNaeV07K0d46IfuEd5v9+pBs= -github.com/microsoft/kiota-serialization-multipart-go v1.0.0/go.mod h1:yauLeBTpANk4L03XD985akNysG24SnRJGaveZf+p4so= -github.com/microsoft/kiota-serialization-text-go v1.0.0 h1:XOaRhAXy+g8ZVpcq7x7a0jlETWnWrEum0RhmbYrTFnA= -github.com/microsoft/kiota-serialization-text-go v1.0.0/go.mod h1:sM1/C6ecnQ7IquQOGUrUldaO5wj+9+v7G2W3sQ3fy6M= -github.com/microsoftgraph/msgraph-sdk-go v1.38.0 h1:pxVMih65Iul2yIUVE5PUqdw5Q4eFuH+eb4ZTxR3oGag= -github.com/microsoftgraph/msgraph-sdk-go v1.38.0/go.mod h1:u/ciVhK5eBqzQvsVnTVdeEl+Jgy9WbUoUHHKgcw54hk= -github.com/microsoftgraph/msgraph-sdk-go-core v1.1.0 h1:NB7c/n4Knj+TLaLfjsahhSqoUqoN/CtyNB0XIe/nJnM= -github.com/microsoftgraph/msgraph-sdk-go-core v1.1.0/go.mod h1:M3w/5IFJ1u/DpwOyjsjNSVEA43y1rLOeX58suyfBhGk= github.com/miekg/dns v1.1.57 h1:Jzi7ApEIzwEPLHWRcafCN9LZSBbqQpxjt/wpgvg7wcM= github.com/miekg/dns v1.1.57/go.mod h1:uqRjCRUuEAA6qsOiJvDd+CFo/vW+y5WR6SNmHE55hZk= +github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= +github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= +github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/mapstructure v0.0.0-20180715050151-f15292f7a699/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= +github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= github.com/moby/locker v1.0.1 h1:fOXqR41zeveg4fFODix+1Ch4mj/gT0NE1XJbp/epuBg= github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc= github.com/moby/sys/mountinfo v0.6.2 h1:BzJjoreD5BMFNmD9Rus6gdd1pLuecOFPt8wC+Vygl78= @@ -385,11 +385,17 @@ github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUz github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8= github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I= +github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= +github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/spf13/afero v1.1.1/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/cast v1.2.0/go.mod h1:r2rcYCSwa1IExKTDiTfzaxqT2FNHs8hODu4LnUfgKEg= +github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0= +github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= github.com/spf13/cobra v0.0.0-20180820174524-ff0d02e85550/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g= github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= @@ -399,8 +405,6 @@ github.com/spf13/pflag v0.0.0-20180821114517-d929dcbb1086/go.mod h1:DYY7MBk1bdzu github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.1.0/go.mod h1:A8kyI5cUJhb8N+3pkfONlcEcZbueH6nhAm0Fq7SrnBM= -github.com/std-uritemplate/std-uritemplate/go v0.0.55 h1:muSH037g97K7U2f94G9LUuE8tZlJsoSSrPsO9V281WY= -github.com/std-uritemplate/std-uritemplate/go v0.0.55/go.mod h1:rG/bqh/ThY4xE5de7Rap3vaDkYUT76B0GPJ0loYeTTc= github.com/stoewer/go-strcase v1.2.0 h1:Z2iHWqGXH00XYgqDmNgQbIBxf3wrNq0F3feEy0ainaU= github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -482,6 +486,7 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -507,6 +512,7 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -541,12 +547,14 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/term v0.20.0 h1:VnkxpohqXaOBYJtBmEppKUG6mXpi+4O6purfc2+sMhw= golang.org/x/term v0.20.0/go.mod h1:8UkIAJTvZgivsXaD6/pH6U9ecQzZ45awqEOzuCvwpFY= golang.org/x/text v0.0.0-20180810153555-6e3c4e7365dd/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -554,6 +562,7 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= @@ -614,6 +623,7 @@ gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/pkg/safeguards/preprocessing_helpers.go b/pkg/safeguards/preprocessing_helpers.go new file mode 100644 index 00000000..67adcdcb --- /dev/null +++ b/pkg/safeguards/preprocessing_helpers.go @@ -0,0 +1,110 @@ +package safeguards + +import ( + "fmt" + "os" + "path/filepath" + + "gopkg.in/yaml.v2" + "helm.sh/helm/v3/pkg/chart" + "helm.sh/helm/v3/pkg/chart/loader" + "helm.sh/helm/v3/pkg/chartutil" + "helm.sh/helm/v3/pkg/engine" +) + +// Given a Helm chart directory or file, renders all templates and writes them to the specified directory +func RenderHelmChart(isFile bool, mainChartPath, tempDir string) ([]ManifestFile, error) { + if isFile { // Get the directory that the Chart.yaml lives in + mainChartPath = filepath.Dir(mainChartPath) + } + + mainChart, err := loader.Load(mainChartPath) + if err != nil { + return nil, fmt.Errorf("failed to load main chart: %s", err) + } + + loadedCharts := make(map[string]*chart.Chart) // map of chart path to chart object + loadedCharts[mainChartPath] = mainChart + + // Load subcharts and dependencies + for _, dep := range mainChart.Metadata.Dependencies { + // Resolve the chart path based on the main chart's directory + chartPath := filepath.Join(mainChartPath, dep.Repository[len("file://"):]) + chartPath = filepath.Clean(chartPath) + + subChart, err := loader.Load(chartPath) + if err != nil { + return nil, fmt.Errorf("failed to load chart: %s", err) + } + loadedCharts[chartPath] = subChart + } + + var manifestFiles []ManifestFile + for chartPath, chart := range loadedCharts { + valuesPath := filepath.Join(chartPath, "values.yaml") // Enforce that values.yaml must be at same level as Chart.yaml + mergedValues, err := getValues(chart, valuesPath) + if err != nil { + return nil, fmt.Errorf("failed to load values: %s", err) + } + e := engine.Engine{Strict: true} + renderedFiles, err := e.Render(chart, mergedValues) + if err != nil { + return nil, fmt.Errorf("failed to render chart: %s", err) + } + + // Write each rendered file to the output directory with the same name as in templates/ + for filePath, content := range renderedFiles { + outputFilePath := filepath.Join(tempDir, filepath.Base(filePath)) + if err := os.WriteFile(outputFilePath, []byte(content), 0644); err != nil { + return nil, fmt.Errorf("failed to write manifest file: %s", err) + } + manifestFiles = append(manifestFiles, ManifestFile{Name: filepath.Base(filePath), Path: outputFilePath}) + } + } + + return manifestFiles, nil +} + +// Returns values from values.yaml and release options specified in values.yaml +func getValues(chart *chart.Chart, valuesPath string) (chartutil.Values, error) { + // Load values file + valuesFile, err := os.ReadFile(valuesPath) + if err != nil { + return nil, fmt.Errorf("failed to read values file: %s", err) + } + + vals := map[string]interface{}{} + if err := yaml.Unmarshal(valuesFile, &vals); err != nil { + return nil, fmt.Errorf("failed to parse values.yaml: %s", err) + } + + mergedValues, err := getReleaseOptions(chart, vals) + return mergedValues, err +} + +func getReleaseOptions(chart *chart.Chart, vals map[string]interface{}) (chartutil.Values, error) { + // Extract release options from values + releaseName, ok := vals["releaseName"].(string) + if !ok || releaseName == "" { + return nil, fmt.Errorf("releaseName not found or empty in values.yaml") + } + + releaseNamespace, ok := vals["releaseNamespace"].(string) + if !ok || releaseNamespace == "" { + return nil, fmt.Errorf("releaseNamespace not found or empty in values.yaml") + } + + options := chartutil.ReleaseOptions{ + Name: releaseName, + Namespace: releaseNamespace, + } + + // Combine chart values with release options + config := chartutil.Values(vals) + mergedValues, err := chartutil.ToRenderValues(chart, config, options, nil) + if err != nil { + return nil, fmt.Errorf("failed to merge values: %s", err) + } + + return mergedValues, nil +} diff --git a/pkg/safeguards/preprocessing_helpers_test.go b/pkg/safeguards/preprocessing_helpers_test.go new file mode 100644 index 00000000..c9ef4209 --- /dev/null +++ b/pkg/safeguards/preprocessing_helpers_test.go @@ -0,0 +1,227 @@ +package safeguards + +import ( + "os" + "path/filepath" + "testing" + + "github.com/stretchr/testify/assert" + "gopkg.in/yaml.v2" +) + +const ( + tempDir = "testdata" // Rendered files are stored here before they are read for comparison + chartPath = "tests/testmanifests/validchart" + invalidChartPath = "tests/testmanifests/invalidchart" + invalidValuesChart = "tests/testmanifests/invalidvalues" + invalidDeploymentsChart = "tests/testmanifests/invaliddeployment" + invalidDeploymentSyntax = "tests/testmanifests/invaliddeployment-syntax" + invalidDeploymentValues = "tests/testmanifests/invaliddeployment-values" + folderwithHelpersTmpl = "tests/testmanifests/different-structure" + multipleTemplateDirs = "tests/testmanifests/multiple-templates" + multipleValuesFile = "tests/testmanifests/multiple-values-files" + + subcharts = "tests/testmanifests/multiple-charts" + subchartDir = "tests/testmanifests/multiple-charts/charts/subchart2" + directPath_ToSubchartYaml = "tests/testmanifests/multiple-charts/charts/subchart1/Chart.yaml" + directPath_ToMainChartYaml = "tests/testmanifests/multiple-charts/Chart.yaml" + + directPath_ToValidChart = "tests/testmanifests/validchart/Chart.yaml" + directPath_ToInvalidChart = "tests/testmanifests/invalidchart/Chart.yaml" +) + +func makeTempDir(t *testing.T) { + if err := os.MkdirAll(tempDir, 0755); err != nil { + t.Fatalf("failed to create temporary output directory: %s", err) + } +} + +// Test rendering a valid Helm chart with no subcharts and three templates +func TestRenderHelmChart_Valid(t *testing.T) { + makeTempDir(t) + t.Cleanup(func() { cleanupDir(t, tempDir) }) + + manifestFiles, err := RenderHelmChart(false, chartPath, tempDir) + assert.Nil(t, err) + + // Check that the output directory exists and contains expected files + expectedFiles := make(map[string]string) + expectedFiles["deployment.yaml"] = getManifestAsString(t, "tests/testmanifests/expecteddeployment.yaml") + expectedFiles["service.yaml"] = getManifestAsString(t, "tests/testmanifests/expectedservice.yaml") + expectedFiles["ingress.yaml"] = getManifestAsString(t, "tests/testmanifests/expectedingress.yaml") + + for _, writtenFile := range manifestFiles { + expectedYaml := expectedFiles[writtenFile.Name] + writtenYaml := parseYAML(t, getManifestAsString(t, writtenFile.Path)) + assert.Equal(t, writtenYaml, parseYAML(t, expectedYaml)) + } + + cleanupDir(t, tempDir) + makeTempDir(t) + + // Test by giving file directly + manifestFiles, err = RenderHelmChart(true, directPath_ToValidChart, tempDir) + assert.Nil(t, err) + + for _, writtenFile := range manifestFiles { + expectedYaml := expectedFiles[writtenFile.Name] + writtenYaml := parseYAML(t, getManifestAsString(t, writtenFile.Path)) + assert.Equal(t, writtenYaml, parseYAML(t, expectedYaml)) + } +} + +// Should successfully render a Helm chart with sub charts and be able to render subchart separately within a helm chart +func TestSubCharts(t *testing.T) { + makeTempDir(t) + t.Cleanup(func() { cleanupDir(t, tempDir) }) + + manifestFiles, err := RenderHelmChart(false, subcharts, tempDir) + assert.Nil(t, err) + + // Assert that 3 files were created in temp dir: 1 from main chart, 2 from subcharts + files, _ := os.ReadDir(tempDir) + assert.Equal(t, len(files), 3) + + expectedFiles := make(map[string]string) + expectedFiles["maindeployment.yaml"] = getManifestAsString(t, "tests/testmanifests/expected-mainchart.yaml") + expectedFiles["deployment1.yaml"] = getManifestAsString(t, "tests/testmanifests/expected-subchart1.yaml") + expectedFiles["deployment2.yaml"] = getManifestAsString(t, "tests/testmanifests/expected-subchart2.yaml") + + for _, writtenFile := range manifestFiles { + expectedYaml := expectedFiles[writtenFile.Name] + writtenYaml := parseYAML(t, getManifestAsString(t, writtenFile.Path)) + assert.Equal(t, writtenYaml, parseYAML(t, expectedYaml)) + } + + cleanupDir(t, tempDir) + makeTempDir(t) + + // Given a sub-chart dir, that specific sub chart only should be evaluated and rendered + _, err = RenderHelmChart(false, subchartDir, tempDir) + assert.Nil(t, err) + + cleanupDir(t, tempDir) + makeTempDir(t) + + // Given a Chart.yaml in the main directory, main chart and subcharts should be evaluated + _, err = RenderHelmChart(true, directPath_ToMainChartYaml, tempDir) + assert.Nil(t, err) + + cleanupDir(t, tempDir) + makeTempDir(t) + + // Given path to a sub- Chart.yaml with a dependency on another subchart, should render both subcharts, but not the main chart + manifestFiles, err = RenderHelmChart(true, directPath_ToSubchartYaml, tempDir) + assert.Nil(t, err) + + expectedFiles = make(map[string]string) + expectedFiles["deployment1.yaml"] = getManifestAsString(t, "tests/testmanifests/expected-subchart1.yaml") + expectedFiles["deployment2.yaml"] = getManifestAsString(t, "tests/testmanifests/expected-subchart2.yaml") + + for _, writtenFile := range manifestFiles { + expectedYaml := expectedFiles[writtenFile.Name] + writtenYaml := parseYAML(t, getManifestAsString(t, writtenFile.Path)) + assert.Equal(t, writtenYaml, parseYAML(t, expectedYaml)) + } + + //expect mainchart.yaml to not exist + outputFilePath := filepath.Join(tempDir, "maindeployment.yaml") + assert.NoFileExists(t, outputFilePath, "Unexpected file was created: %s", outputFilePath) +} + +/** +* Testing user errors + */ + +// Should fail if the Chart.yaml is invalid +func TestInvalidChartAndValues(t *testing.T) { + makeTempDir(t) + t.Cleanup(func() { cleanupDir(t, tempDir) }) + + _, err := RenderHelmChart(false, invalidChartPath, tempDir) + assert.NotNil(t, err) + assert.Contains(t, err.Error(), "failed to load main chart: validation: chart.metadata.name is required") + + _, err = RenderHelmChart(true, directPath_ToValidChart, tempDir) + assert.Nil(t, err) + + // Should fail if values.yaml doesn't contain all values necessary for templating + cleanupDir(t, tempDir) + makeTempDir(t) + + _, err = RenderHelmChart(false, invalidValuesChart, tempDir) + assert.NotNil(t, err) +} + +func TestInvalidDeployments(t *testing.T) { + makeTempDir(t) + t.Cleanup(func() { cleanupDir(t, tempDir) }) + + _, err := RenderHelmChart(false, invalidDeploymentSyntax, tempDir) + assert.NotNil(t, err) + assert.Contains(t, err.Error(), "parse error") + assert.Contains(t, err.Error(), "function \"selector\" not defined") + + _, err = RenderHelmChart(false, invalidDeploymentValues, tempDir) + assert.NotNil(t, err) + assert.Contains(t, err.Error(), "map has no entry for key") +} + +// Test different helm folder structures +func TestDifferentFolderStructures(t *testing.T) { + makeTempDir(t) + t.Cleanup(func() { cleanupDir(t, tempDir) }) + + manifestFiles, err := RenderHelmChart(false, folderwithHelpersTmpl, tempDir) // includes _helpers.tpl + assert.Nil(t, err) + + expectedFiles := make(map[string]string) + expectedFiles["deployment.yaml"] = getManifestAsString(t, "tests/testmanifests/expected-helpers-deployment.yaml") + expectedFiles["service.yaml"] = getManifestAsString(t, "tests/testmanifests/expected-helpers-service.yaml") + for _, writtenFile := range manifestFiles { + expectedYaml := expectedFiles[writtenFile.Name] + writtenYaml := parseYAML(t, getManifestAsString(t, writtenFile.Path)) + assert.Equal(t, writtenYaml, parseYAML(t, expectedYaml)) + } + cleanupDir(t, tempDir) + makeTempDir(t) + + manifestFiles, err = RenderHelmChart(false, multipleTemplateDirs, tempDir) // all manifests defined in one file + assert.Nil(t, err) + + expectedFiles = make(map[string]string) + expectedFiles["resources.yaml"] = getManifestAsString(t, "tests/testmanifests/expected-resources.yaml") + expectedFiles["service-1.yaml"] = getManifestAsString(t, "tests/testmanifests/expectedservice.yaml") + expectedFiles["service-2.yaml"] = getManifestAsString(t, "tests/testmanifests/expectedservice2.yaml") + for _, writtenFile := range manifestFiles { + expectedYaml := expectedFiles[writtenFile.Name] + writtenYaml := parseYAML(t, getManifestAsString(t, writtenFile.Path)) + assert.Equal(t, writtenYaml, parseYAML(t, expectedYaml)) + } +} + +func cleanupDir(t *testing.T, dir string) { + err := os.RemoveAll(dir) + if err != nil { + t.Fatalf("Failed to clean directory: %s", err) + } +} + +func parseYAML(t *testing.T, content string) map[string]interface{} { + var result map[string]interface{} + err := yaml.Unmarshal([]byte(content), &result) + if err != nil { + t.Fatalf("Failed to parse YAML: %s", err) + } + return result +} + +func getManifestAsString(t *testing.T, filePath string) string { + yamlFileContent, err := os.ReadFile(filePath) + if err != nil { + t.Fatalf("Failed to read YAML file: %s", err) + } + + yamlContentString := string(yamlFileContent) + return yamlContentString +} diff --git a/pkg/safeguards/testdata/resources.yaml b/pkg/safeguards/testdata/resources.yaml new file mode 100644 index 00000000..6a2ffe2b --- /dev/null +++ b/pkg/safeguards/testdata/resources.yaml @@ -0,0 +1,41 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: test-release-deployment + namespace: test-namespace +spec: + replicas: 1 + selector: + matchLabels: + app: my-web-app + template: + metadata: + labels: + app: my-web-app + spec: + containers: + - name: nginx + image: nginx:stable +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: test-release-configmap + namespace: test-namespace +data: + config.yaml: | + replicaCount: 1 + image: + repository: nginx + tag: stable + pullPolicy: IfNotPresent + service: + type: ClusterIP + port: 80 + ingress: + enabled: true + hostname: example.com + annotations: + tls: false + tlsSecret: + diff --git a/pkg/safeguards/testdata/service-1.yaml b/pkg/safeguards/testdata/service-1.yaml new file mode 100644 index 00000000..d22f2b4b --- /dev/null +++ b/pkg/safeguards/testdata/service-1.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Service +metadata: + name: test-release-service + namespace: test-namespace +spec: + type: ClusterIP + ports: + - port: 80 + selector: + app: my-web-app \ No newline at end of file diff --git a/pkg/safeguards/testdata/service-2.yaml b/pkg/safeguards/testdata/service-2.yaml new file mode 100644 index 00000000..e5f2a45b --- /dev/null +++ b/pkg/safeguards/testdata/service-2.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Service +metadata: + name: test-release-service2 + namespace: test-namespace +spec: + type: ClusterIP + ports: + - port: 80 + selector: + app: my-web-app \ No newline at end of file diff --git a/pkg/safeguards/tests/testmanifests/different-structure/Chart.yaml b/pkg/safeguards/tests/testmanifests/different-structure/Chart.yaml new file mode 100644 index 00000000..77f27ed0 --- /dev/null +++ b/pkg/safeguards/tests/testmanifests/different-structure/Chart.yaml @@ -0,0 +1,5 @@ +apiVersion: v2 +name: mychart +description: A simple Helm chart for Kubernetes +version: 0.1.0 +appVersion: "1.16.0" diff --git a/pkg/safeguards/tests/testmanifests/different-structure/templates/_helpers.tpl b/pkg/safeguards/tests/testmanifests/different-structure/templates/_helpers.tpl new file mode 100644 index 00000000..1ae55802 --- /dev/null +++ b/pkg/safeguards/tests/testmanifests/different-structure/templates/_helpers.tpl @@ -0,0 +1,12 @@ +{{- define "mychart.fullname" -}} +{{- printf "%s-%s" .Release.Name .Chart.Name | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{- define "mychart.labels" -}} +helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} +{{ include "mychart.fullname" . }}: {{ .Release.Name }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +app.kubernetes.io/instance: {{ .Release.Name }} +app.kubernetes.io/version: {{ .Chart.AppVersion }} +app.kubernetes.io/component: {{ .Chart.Name }} +{{- end -}} diff --git a/pkg/safeguards/tests/testmanifests/different-structure/templates/deployment.yaml b/pkg/safeguards/tests/testmanifests/different-structure/templates/deployment.yaml new file mode 100644 index 00000000..11a21cdf --- /dev/null +++ b/pkg/safeguards/tests/testmanifests/different-structure/templates/deployment.yaml @@ -0,0 +1,24 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "mychart.fullname" . }} + labels: + {{ include "mychart.labels" . | nindent 4 }} +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + app: {{ include "mychart.fullname" . }} + template: + metadata: + labels: + app: {{ include "mychart.fullname" . }} + spec: + containers: + - name: nginx + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - containerPort: 80 + resources: + {{- toYaml .Values.resources | nindent 12 }} diff --git a/pkg/safeguards/tests/testmanifests/different-structure/templates/service.yaml b/pkg/safeguards/tests/testmanifests/different-structure/templates/service.yaml new file mode 100644 index 00000000..2d1038a3 --- /dev/null +++ b/pkg/safeguards/tests/testmanifests/different-structure/templates/service.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "mychart.fullname" . }} + labels: + {{ include "mychart.labels" . | nindent 4 }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + targetPort: 80 + selector: + app: {{ include "mychart.fullname" . }} diff --git a/pkg/safeguards/tests/testmanifests/different-structure/values.yaml b/pkg/safeguards/tests/testmanifests/different-structure/values.yaml new file mode 100644 index 00000000..b17f9836 --- /dev/null +++ b/pkg/safeguards/tests/testmanifests/different-structure/values.yaml @@ -0,0 +1,22 @@ +replicaCount: 1 + +image: + repository: nginx + tag: "1.16.0" + pullPolicy: IfNotPresent + +service: + type: ClusterIP + port: 80 + +releaseName: test-release + +releaseNamespace: test-namespace + +resources: {} + +nodeSelector: {} + +tolerations: [] + +affinity: {} diff --git a/pkg/safeguards/tests/testmanifests/expected-helpers-deployment.yaml b/pkg/safeguards/tests/testmanifests/expected-helpers-deployment.yaml new file mode 100644 index 00000000..20ea5f38 --- /dev/null +++ b/pkg/safeguards/tests/testmanifests/expected-helpers-deployment.yaml @@ -0,0 +1,30 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: test-release-mychart + labels: + + helm.sh/chart: mychart-0.1.0 + test-release-mychart: test-release + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/instance: test-release + app.kubernetes.io/version: 1.16.0 + app.kubernetes.io/component: mychart +spec: + replicas: 1 + selector: + matchLabels: + app: test-release-mychart + template: + metadata: + labels: + app: test-release-mychart + spec: + containers: + - name: nginx + image: "nginx:1.16.0" + imagePullPolicy: IfNotPresent + ports: + - containerPort: 80 + resources: + diff --git a/pkg/safeguards/tests/testmanifests/expected-helpers-service.yaml b/pkg/safeguards/tests/testmanifests/expected-helpers-service.yaml new file mode 100644 index 00000000..2081a9f7 --- /dev/null +++ b/pkg/safeguards/tests/testmanifests/expected-helpers-service.yaml @@ -0,0 +1,19 @@ +apiVersion: v1 +kind: Service +metadata: + name: test-release-mychart + labels: + + helm.sh/chart: mychart-0.1.0 + test-release-mychart: test-release + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/instance: test-release + app.kubernetes.io/version: 1.16.0 + app.kubernetes.io/component: mychart +spec: + type: ClusterIP + ports: + - port: 80 + targetPort: 80 + selector: + app: test-release-mychart diff --git a/pkg/safeguards/tests/testmanifests/expected-mainchart.yaml b/pkg/safeguards/tests/testmanifests/expected-mainchart.yaml new file mode 100644 index 00000000..d8cccdb1 --- /dev/null +++ b/pkg/safeguards/tests/testmanifests/expected-mainchart.yaml @@ -0,0 +1,19 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: test-release-main + labels: + app: mainchart +spec: + replicas: 1 + selector: + matchLabels: + app: mainchart + template: + metadata: + labels: + app: mainchart + spec: + containers: + - name: mainchart + image: nginx:stable \ No newline at end of file diff --git a/pkg/safeguards/tests/testmanifests/expected-resources.yaml b/pkg/safeguards/tests/testmanifests/expected-resources.yaml new file mode 100644 index 00000000..995a77d6 --- /dev/null +++ b/pkg/safeguards/tests/testmanifests/expected-resources.yaml @@ -0,0 +1,45 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: test-release-deployment + namespace: test-namespace +spec: + replicas: 1 + selector: + matchLabels: + app: my-web-app + template: + metadata: + labels: + app: my-web-app + spec: + containers: + - name: nginx + image: nginx:stable +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: test-release-configmap + namespace: test-namespace +data: + config.yaml: | + replicaCount: 1 + image: + repository: nginx + tag: stable + pullPolicy: IfNotPresent + service: + type: ClusterIP + port: 80 + ingress: + enabled: true + hostname: example.com + annotations: {} + tls: false + tlsSecret: "" + + + + + diff --git a/pkg/safeguards/tests/testmanifests/expected-subchart1.yaml b/pkg/safeguards/tests/testmanifests/expected-subchart1.yaml new file mode 100644 index 00000000..5afbe5d9 --- /dev/null +++ b/pkg/safeguards/tests/testmanifests/expected-subchart1.yaml @@ -0,0 +1,19 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: test-release-subchart1 + labels: + app: my-web-app +spec: + replicas: 2 + selector: + matchLabels: + app: my-web-app + template: + metadata: + labels: + app: my-web-app + spec: + containers: + - name: nginx + image: nginx:stable \ No newline at end of file diff --git a/pkg/safeguards/tests/testmanifests/expected-subchart2.yaml b/pkg/safeguards/tests/testmanifests/expected-subchart2.yaml new file mode 100644 index 00000000..9835f004 --- /dev/null +++ b/pkg/safeguards/tests/testmanifests/expected-subchart2.yaml @@ -0,0 +1,19 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: test-release-subchart2 + labels: + app: my-web-app +spec: + replicas: 3 + selector: + matchLabels: + app: my-web-app + template: + metadata: + labels: + app: my-web-app + spec: + containers: + - name: nginx + image: nginx:stable \ No newline at end of file diff --git a/pkg/safeguards/tests/testmanifests/expecteddeployment.yaml b/pkg/safeguards/tests/testmanifests/expecteddeployment.yaml new file mode 100644 index 00000000..2c601eef --- /dev/null +++ b/pkg/safeguards/tests/testmanifests/expecteddeployment.yaml @@ -0,0 +1,18 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: test-release-deployment + namespace: test-namespace +spec: + replicas: 1 + selector: + matchLabels: + app: my-web-app + template: + metadata: + labels: + app: my-web-app + spec: + containers: + - name: nginx + image: nginx:stable \ No newline at end of file diff --git a/pkg/safeguards/tests/testmanifests/expectedingress.yaml b/pkg/safeguards/tests/testmanifests/expectedingress.yaml new file mode 100644 index 00000000..c99df6bf --- /dev/null +++ b/pkg/safeguards/tests/testmanifests/expectedingress.yaml @@ -0,0 +1,17 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: test-release-ingress + namespace: test-namespace +spec: + rules: + - host: example.com + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: test-release-service + port: + number: 80 \ No newline at end of file diff --git a/pkg/safeguards/tests/testmanifests/expectedservice.yaml b/pkg/safeguards/tests/testmanifests/expectedservice.yaml new file mode 100644 index 00000000..d22f2b4b --- /dev/null +++ b/pkg/safeguards/tests/testmanifests/expectedservice.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Service +metadata: + name: test-release-service + namespace: test-namespace +spec: + type: ClusterIP + ports: + - port: 80 + selector: + app: my-web-app \ No newline at end of file diff --git a/pkg/safeguards/tests/testmanifests/expectedservice2.yaml b/pkg/safeguards/tests/testmanifests/expectedservice2.yaml new file mode 100644 index 00000000..e5f2a45b --- /dev/null +++ b/pkg/safeguards/tests/testmanifests/expectedservice2.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Service +metadata: + name: test-release-service2 + namespace: test-namespace +spec: + type: ClusterIP + ports: + - port: 80 + selector: + app: my-web-app \ No newline at end of file diff --git a/pkg/safeguards/tests/testmanifests/invalidchart/Chart.yaml b/pkg/safeguards/tests/testmanifests/invalidchart/Chart.yaml new file mode 100644 index 00000000..9c43125f --- /dev/null +++ b/pkg/safeguards/tests/testmanifests/invalidchart/Chart.yaml @@ -0,0 +1,2 @@ +description: A Helm chart for Kubernetes +version: 0.1.0 \ No newline at end of file diff --git a/pkg/safeguards/tests/testmanifests/invalidchart/templates/deployment.yaml b/pkg/safeguards/tests/testmanifests/invalidchart/templates/deployment.yaml new file mode 100644 index 00000000..e5e42433 --- /dev/null +++ b/pkg/safeguards/tests/testmanifests/invalidchart/templates/deployment.yaml @@ -0,0 +1,18 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Release.Name }}-deployment + namespace: {{ .Release.Namespace }} +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + app: my-web-app + template: + metadata: + labels: + app: my-web-app + spec: + containers: + - name: nginx + image: {{ .Values.image.repository }}:{{ .Values.image.tag }} diff --git a/pkg/safeguards/tests/testmanifests/invalidchart/values.yaml b/pkg/safeguards/tests/testmanifests/invalidchart/values.yaml new file mode 100644 index 00000000..80610550 --- /dev/null +++ b/pkg/safeguards/tests/testmanifests/invalidchart/values.yaml @@ -0,0 +1,12 @@ +replicaCount: 1 +image: + repository: nginx + tag: stable +service: + type: ClusterIP + port: 80 +ingress: + enabled: true + hostname: example.com +releaseName: test-release +releaseNamespace: test-namespace \ No newline at end of file diff --git a/pkg/safeguards/tests/testmanifests/invaliddeployment-syntax/Chart.yaml b/pkg/safeguards/tests/testmanifests/invaliddeployment-syntax/Chart.yaml new file mode 100644 index 00000000..5fcbd38a --- /dev/null +++ b/pkg/safeguards/tests/testmanifests/invaliddeployment-syntax/Chart.yaml @@ -0,0 +1,4 @@ +apiVersion: v2 +name: my-web-app +description: A Helm chart for Kubernetes +version: 0.1.0 \ No newline at end of file diff --git a/pkg/safeguards/tests/testmanifests/invaliddeployment-syntax/templates/invaliddeploymentsyntax.yaml b/pkg/safeguards/tests/testmanifests/invaliddeployment-syntax/templates/invaliddeploymentsyntax.yaml new file mode 100644 index 00000000..ee760c73 --- /dev/null +++ b/pkg/safeguards/tests/testmanifests/invaliddeployment-syntax/templates/invaliddeploymentsyntax.yaml @@ -0,0 +1,18 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Release.Name }}-deployment + namespace: {{ .Release.Namespace }} +spec: + replicas: {{ .Values.replicaCount + selector: + matchLabels: + app: my-web-app + template: + metadata: + labels: + app: my-web-ap + spec: + containers: + - name: nginx + image: {{ .Values.image.repository }}:{{ .Values.image.tag \ No newline at end of file diff --git a/pkg/safeguards/tests/testmanifests/invaliddeployment-syntax/values.yaml b/pkg/safeguards/tests/testmanifests/invaliddeployment-syntax/values.yaml new file mode 100644 index 00000000..80610550 --- /dev/null +++ b/pkg/safeguards/tests/testmanifests/invaliddeployment-syntax/values.yaml @@ -0,0 +1,12 @@ +replicaCount: 1 +image: + repository: nginx + tag: stable +service: + type: ClusterIP + port: 80 +ingress: + enabled: true + hostname: example.com +releaseName: test-release +releaseNamespace: test-namespace \ No newline at end of file diff --git a/pkg/safeguards/tests/testmanifests/invaliddeployment-values/Chart.yaml b/pkg/safeguards/tests/testmanifests/invaliddeployment-values/Chart.yaml new file mode 100644 index 00000000..5fcbd38a --- /dev/null +++ b/pkg/safeguards/tests/testmanifests/invaliddeployment-values/Chart.yaml @@ -0,0 +1,4 @@ +apiVersion: v2 +name: my-web-app +description: A Helm chart for Kubernetes +version: 0.1.0 \ No newline at end of file diff --git a/pkg/safeguards/tests/testmanifests/invaliddeployment-values/templates/invaliddeploymentvalues.yaml b/pkg/safeguards/tests/testmanifests/invaliddeployment-values/templates/invaliddeploymentvalues.yaml new file mode 100644 index 00000000..9e663e79 --- /dev/null +++ b/pkg/safeguards/tests/testmanifests/invaliddeployment-values/templates/invaliddeploymentvalues.yaml @@ -0,0 +1,18 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Release.Name }}-deployment + namespace: {{ .Release.Namespace }} +spec: + replicas: {{ .Values.nonExistentField }} + selector: + matchLabels: + app: my-web-app + template: + metadata: + labels: + app: my-web-app + spec: + containers: + - name: nginx + image: {{ .Values.image.invalidField }}:{{ .Values.image.tag }} \ No newline at end of file diff --git a/pkg/safeguards/tests/testmanifests/invaliddeployment-values/values.yaml b/pkg/safeguards/tests/testmanifests/invaliddeployment-values/values.yaml new file mode 100644 index 00000000..80610550 --- /dev/null +++ b/pkg/safeguards/tests/testmanifests/invaliddeployment-values/values.yaml @@ -0,0 +1,12 @@ +replicaCount: 1 +image: + repository: nginx + tag: stable +service: + type: ClusterIP + port: 80 +ingress: + enabled: true + hostname: example.com +releaseName: test-release +releaseNamespace: test-namespace \ No newline at end of file diff --git a/pkg/safeguards/tests/testmanifests/invalidvalues/Chart.yaml b/pkg/safeguards/tests/testmanifests/invalidvalues/Chart.yaml new file mode 100644 index 00000000..5fcbd38a --- /dev/null +++ b/pkg/safeguards/tests/testmanifests/invalidvalues/Chart.yaml @@ -0,0 +1,4 @@ +apiVersion: v2 +name: my-web-app +description: A Helm chart for Kubernetes +version: 0.1.0 \ No newline at end of file diff --git a/pkg/safeguards/tests/testmanifests/invalidvalues/templates/service.yaml b/pkg/safeguards/tests/testmanifests/invalidvalues/templates/service.yaml new file mode 100644 index 00000000..f1fce029 --- /dev/null +++ b/pkg/safeguards/tests/testmanifests/invalidvalues/templates/service.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ .Release.Name }}-service + namespace: {{ .Release.Namespace }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + selector: + app: my-web-app \ No newline at end of file diff --git a/pkg/safeguards/tests/testmanifests/invalidvalues/values.yaml b/pkg/safeguards/tests/testmanifests/invalidvalues/values.yaml new file mode 100644 index 00000000..e522d580 --- /dev/null +++ b/pkg/safeguards/tests/testmanifests/invalidvalues/values.yaml @@ -0,0 +1,9 @@ +replicaCount: 1 +image: + repository: nginx + tag: stable +ingress: + enabled: true + hostname: example.com +releaseName: test-release +releaseNamespace: test-namespace \ No newline at end of file diff --git a/pkg/safeguards/tests/testmanifests/multiple-charts/Chart.yaml b/pkg/safeguards/tests/testmanifests/multiple-charts/Chart.yaml new file mode 100644 index 00000000..46363b07 --- /dev/null +++ b/pkg/safeguards/tests/testmanifests/multiple-charts/Chart.yaml @@ -0,0 +1,4 @@ +apiVersion: v2 +name: mainchart +description: A Helm chart with subcharts +version: 0.1.0 diff --git a/pkg/safeguards/tests/testmanifests/multiple-charts/charts/subchart1/Chart.yaml b/pkg/safeguards/tests/testmanifests/multiple-charts/charts/subchart1/Chart.yaml new file mode 100644 index 00000000..f7612a82 --- /dev/null +++ b/pkg/safeguards/tests/testmanifests/multiple-charts/charts/subchart1/Chart.yaml @@ -0,0 +1,8 @@ +apiVersion: v2 +name: subchart1 +description: Subchart 1 for mainchart +version: 0.1.0 +dependencies: + - name: subchart2 + version: 0.1.0 + repository: "file://../subchart2" # Relative path to subchart2 directory diff --git a/pkg/safeguards/tests/testmanifests/multiple-charts/charts/subchart1/templates/deployment1.yaml b/pkg/safeguards/tests/testmanifests/multiple-charts/charts/subchart1/templates/deployment1.yaml new file mode 100644 index 00000000..032e99eb --- /dev/null +++ b/pkg/safeguards/tests/testmanifests/multiple-charts/charts/subchart1/templates/deployment1.yaml @@ -0,0 +1,19 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Release.Name }}-subchart1 + labels: + app: my-web-app +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + app: my-web-app + template: + metadata: + labels: + app: my-web-app + spec: + containers: + - name: nginx + image: {{ .Values.image.repository }}:{{ .Values.image.tag }} diff --git a/pkg/safeguards/tests/testmanifests/multiple-charts/charts/subchart1/values.yaml b/pkg/safeguards/tests/testmanifests/multiple-charts/charts/subchart1/values.yaml new file mode 100644 index 00000000..44b85503 --- /dev/null +++ b/pkg/safeguards/tests/testmanifests/multiple-charts/charts/subchart1/values.yaml @@ -0,0 +1,6 @@ +replicaCount: 2 +image: + repository: nginx + tag: stable +releaseName: test-release +releaseNamespace: test-namespace \ No newline at end of file diff --git a/pkg/safeguards/tests/testmanifests/multiple-charts/charts/subchart2/Chart.yaml b/pkg/safeguards/tests/testmanifests/multiple-charts/charts/subchart2/Chart.yaml new file mode 100644 index 00000000..0a06fca2 --- /dev/null +++ b/pkg/safeguards/tests/testmanifests/multiple-charts/charts/subchart2/Chart.yaml @@ -0,0 +1,4 @@ +apiVersion: v2 +name: subchart2 +description: Subchart 2 for mainchart +version: 0.1.0 diff --git a/pkg/safeguards/tests/testmanifests/multiple-charts/charts/subchart2/templates/deployment2.yaml b/pkg/safeguards/tests/testmanifests/multiple-charts/charts/subchart2/templates/deployment2.yaml new file mode 100644 index 00000000..e1310fef --- /dev/null +++ b/pkg/safeguards/tests/testmanifests/multiple-charts/charts/subchart2/templates/deployment2.yaml @@ -0,0 +1,19 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Release.Name }}-subchart2 + labels: + app: my-web-app +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + app: my-web-app + template: + metadata: + labels: + app: my-web-app + spec: + containers: + - name: nginx + image: {{ .Values.image.repository }}:{{ .Values.image.tag }} diff --git a/pkg/safeguards/tests/testmanifests/multiple-charts/charts/subchart2/values.yaml b/pkg/safeguards/tests/testmanifests/multiple-charts/charts/subchart2/values.yaml new file mode 100644 index 00000000..37aa4d2f --- /dev/null +++ b/pkg/safeguards/tests/testmanifests/multiple-charts/charts/subchart2/values.yaml @@ -0,0 +1,6 @@ +replicaCount: 3 +image: + repository: nginx + tag: stable +releaseName: test-release +releaseNamespace: test-namespace \ No newline at end of file diff --git a/pkg/safeguards/tests/testmanifests/multiple-charts/templates/maindeployment.yaml b/pkg/safeguards/tests/testmanifests/multiple-charts/templates/maindeployment.yaml new file mode 100644 index 00000000..e3db4c9c --- /dev/null +++ b/pkg/safeguards/tests/testmanifests/multiple-charts/templates/maindeployment.yaml @@ -0,0 +1,19 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Release.Name }}-main + labels: + app: mainchart +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + app: mainchart + template: + metadata: + labels: + app: mainchart + spec: + containers: + - name: mainchart + image: {{ .Values.image.repository }}:{{ .Values.image.tag }} diff --git a/pkg/safeguards/tests/testmanifests/multiple-charts/values.yaml b/pkg/safeguards/tests/testmanifests/multiple-charts/values.yaml new file mode 100644 index 00000000..dd955edd --- /dev/null +++ b/pkg/safeguards/tests/testmanifests/multiple-charts/values.yaml @@ -0,0 +1,6 @@ +replicaCount: 1 +image: + repository: nginx + tag: stable +releaseName: test-release +releaseNamespace: test-namespace \ No newline at end of file diff --git a/pkg/safeguards/tests/testmanifests/multiple-templates/Chart.yaml b/pkg/safeguards/tests/testmanifests/multiple-templates/Chart.yaml new file mode 100644 index 00000000..5fcbd38a --- /dev/null +++ b/pkg/safeguards/tests/testmanifests/multiple-templates/Chart.yaml @@ -0,0 +1,4 @@ +apiVersion: v2 +name: my-web-app +description: A Helm chart for Kubernetes +version: 0.1.0 \ No newline at end of file diff --git a/pkg/safeguards/tests/testmanifests/multiple-templates/templates/resources.yaml b/pkg/safeguards/tests/testmanifests/multiple-templates/templates/resources.yaml new file mode 100644 index 00000000..ee836c25 --- /dev/null +++ b/pkg/safeguards/tests/testmanifests/multiple-templates/templates/resources.yaml @@ -0,0 +1,44 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Release.Name }}-deployment + namespace: {{ .Release.Namespace }} +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + app: my-web-app + template: + metadata: + labels: + app: my-web-app + spec: + containers: + - name: nginx + image: {{ .Values.image.repository }}:{{ .Values.image.tag }} +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-configmap + namespace: {{ .Release.Namespace }} +data: + config.yaml: | + replicaCount: {{ .Values.replicaCount }} + image: + repository: {{ .Values.image.repository }} + tag: {{ .Values.image.tag }} + pullPolicy: {{ .Values.image.pullPolicy }} + service: + type: {{ .Values.service.type }} + port: {{ .Values.service.port }} + ingress: + enabled: {{ .Values.ingress.enabled }} + hostname: {{ .Values.ingress.hostname }} + annotations: + {{- range $key, $value := .Values.ingress.annotations }} + {{ $key }}: {{ $value | quote }} + {{- end }} + tls: {{ .Values.ingress.tls }} + tlsSecret: {{ .Values.ingress.tlsSecret }} + diff --git a/pkg/safeguards/tests/testmanifests/multiple-templates/templates/services/service-1.yaml b/pkg/safeguards/tests/testmanifests/multiple-templates/templates/services/service-1.yaml new file mode 100644 index 00000000..f1fce029 --- /dev/null +++ b/pkg/safeguards/tests/testmanifests/multiple-templates/templates/services/service-1.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ .Release.Name }}-service + namespace: {{ .Release.Namespace }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + selector: + app: my-web-app \ No newline at end of file diff --git a/pkg/safeguards/tests/testmanifests/multiple-templates/templates/services/service-2.yaml b/pkg/safeguards/tests/testmanifests/multiple-templates/templates/services/service-2.yaml new file mode 100644 index 00000000..11a10f68 --- /dev/null +++ b/pkg/safeguards/tests/testmanifests/multiple-templates/templates/services/service-2.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ .Release.Name }}-service2 + namespace: {{ .Release.Namespace }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + selector: + app: my-web-app \ No newline at end of file diff --git a/pkg/safeguards/tests/testmanifests/multiple-templates/values.yaml b/pkg/safeguards/tests/testmanifests/multiple-templates/values.yaml new file mode 100644 index 00000000..5c89ef68 --- /dev/null +++ b/pkg/safeguards/tests/testmanifests/multiple-templates/values.yaml @@ -0,0 +1,16 @@ +replicaCount: 1 +image: + repository: nginx + tag: stable + pullPolicy: IfNotPresent +service: + type: ClusterIP + port: 80 +ingress: + enabled: true + hostname: example.com + annotations: {} + tls: false + tlsSecret: "" +releaseName: test-release +releaseNamespace: test-namespace diff --git a/pkg/safeguards/tests/testmanifests/validchart/Chart.yaml b/pkg/safeguards/tests/testmanifests/validchart/Chart.yaml new file mode 100644 index 00000000..5fcbd38a --- /dev/null +++ b/pkg/safeguards/tests/testmanifests/validchart/Chart.yaml @@ -0,0 +1,4 @@ +apiVersion: v2 +name: my-web-app +description: A Helm chart for Kubernetes +version: 0.1.0 \ No newline at end of file diff --git a/pkg/safeguards/tests/testmanifests/validchart/templates/deployment.yaml b/pkg/safeguards/tests/testmanifests/validchart/templates/deployment.yaml new file mode 100644 index 00000000..e5e42433 --- /dev/null +++ b/pkg/safeguards/tests/testmanifests/validchart/templates/deployment.yaml @@ -0,0 +1,18 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ .Release.Name }}-deployment + namespace: {{ .Release.Namespace }} +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + app: my-web-app + template: + metadata: + labels: + app: my-web-app + spec: + containers: + - name: nginx + image: {{ .Values.image.repository }}:{{ .Values.image.tag }} diff --git a/pkg/safeguards/tests/testmanifests/validchart/templates/ingress.yaml b/pkg/safeguards/tests/testmanifests/validchart/templates/ingress.yaml new file mode 100644 index 00000000..6b90e569 --- /dev/null +++ b/pkg/safeguards/tests/testmanifests/validchart/templates/ingress.yaml @@ -0,0 +1,19 @@ +{{- if .Values.ingress.enabled }} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ .Release.Name }}-ingress + namespace: {{ .Release.Namespace }} +spec: + rules: + - host: {{ .Values.ingress.hostname }} + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: {{ .Release.Name }}-service + port: + number: {{ .Values.service.port }} +{{- end }} \ No newline at end of file diff --git a/pkg/safeguards/tests/testmanifests/validchart/templates/service.yaml b/pkg/safeguards/tests/testmanifests/validchart/templates/service.yaml new file mode 100644 index 00000000..f1fce029 --- /dev/null +++ b/pkg/safeguards/tests/testmanifests/validchart/templates/service.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ .Release.Name }}-service + namespace: {{ .Release.Namespace }} +spec: + type: {{ .Values.service.type }} + ports: + - port: {{ .Values.service.port }} + selector: + app: my-web-app \ No newline at end of file diff --git a/pkg/safeguards/tests/testmanifests/validchart/values.yaml b/pkg/safeguards/tests/testmanifests/validchart/values.yaml new file mode 100644 index 00000000..80610550 --- /dev/null +++ b/pkg/safeguards/tests/testmanifests/validchart/values.yaml @@ -0,0 +1,12 @@ +replicaCount: 1 +image: + repository: nginx + tag: stable +service: + type: ClusterIP + port: 80 +ingress: + enabled: true + hostname: example.com +releaseName: test-release +releaseNamespace: test-namespace \ No newline at end of file