From e0225f476a85c4533eab934105c63f44e9d95a50 Mon Sep 17 00:00:00 2001 From: Damian Czaja Date: Thu, 18 Jan 2024 17:36:28 +0100 Subject: [PATCH] fix: ignore templates in Chart dependencies based on ignore paths (#667) --- pkg/command/lint/command.go | 12 ++- pkg/lintcontext/create_contexts.go | 15 +++- pkg/lintcontext/create_contexts_test.go | 30 ++++++- pkg/lintcontext/parse_yaml.go | 35 +++++--- tests/testdata/mychart-0.1.0.tgz | Bin 3584 -> 3913 bytes tests/testdata/mychart/Chart.lock | 6 ++ tests/testdata/mychart/Chart.yaml | 4 + .../mychart/charts/subchart-0.1.0.tgz | Bin 0 -> 1808 bytes tests/testdata/subchart/.helmignore | 23 +++++ tests/testdata/subchart/Chart.yaml | 6 ++ .../subchart/templates/deployment.yaml | 61 ++++++++++++++ tests/testdata/subchart/values.yaml | 79 ++++++++++++++++++ 12 files changed, 255 insertions(+), 16 deletions(-) create mode 100644 tests/testdata/mychart/Chart.lock create mode 100644 tests/testdata/mychart/charts/subchart-0.1.0.tgz create mode 100644 tests/testdata/subchart/.helmignore create mode 100644 tests/testdata/subchart/Chart.yaml create mode 100644 tests/testdata/subchart/templates/deployment.yaml create mode 100644 tests/testdata/subchart/values.yaml diff --git a/pkg/command/lint/command.go b/pkg/command/lint/command.go index 694e930fa..56c79694d 100644 --- a/pkg/command/lint/command.go +++ b/pkg/command/lint/command.go @@ -5,6 +5,7 @@ import ( "os" "golang.stackrox.io/kube-linter/pkg/diagnostic" + "golang.stackrox.io/kube-linter/pkg/pathutil" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "golang.stackrox.io/kube-linter/internal/flagutil" @@ -86,7 +87,16 @@ func Command() *cobra.Command { return err } - lintCtxs, err := lintcontext.CreateContexts(ignorePaths, args...) + absArgs := []string{} + for _, arg := range args { + absArg, err := pathutil.GetAbsolutPath(arg) + if err != nil { + return err + } + absArgs = append(absArgs, absArg) + } + + lintCtxs, err := lintcontext.CreateContexts(ignorePaths, absArgs...) if err != nil { return err } diff --git a/pkg/lintcontext/create_contexts.go b/pkg/lintcontext/create_contexts.go index 901aa9c22..64b9b32d9 100644 --- a/pkg/lintcontext/create_contexts.go +++ b/pkg/lintcontext/create_contexts.go @@ -92,7 +92,10 @@ fileOrDirsLoop: if !info.IsDir() { if strings.HasSuffix(strings.ToLower(currentPath), ".tgz") { ctx := newCtx(options) - ctx.loadObjectsFromTgzHelmChart(currentPath) + if err := ctx.loadObjectsFromTgzHelmChart(currentPath, ignorePaths); err != nil { + return errors.Wrapf(err, "loading helm chart %s", currentPath) + } + contextsByDir[currentPath] = ctx return nil } @@ -118,7 +121,9 @@ fileOrDirsLoop: } ctx := newCtx(options) contextsByDir[currentPath] = ctx - ctx.loadObjectsFromHelmChart(currentPath) + if err := ctx.loadObjectsFromHelmChart(currentPath, ignorePaths); err != nil { + return errors.Wrap(err, "loading helm chart") + } return filepath.SkipDir } return nil @@ -142,9 +147,11 @@ fileOrDirsLoop: // CreateContextsFromHelmArchive creates a context from TGZ reader of Helm Chart. // Note: although this function is not used in CLI, it is exposed from kube-linter library and therefore should stay. // See https://github.com/stackrox/kube-linter/pull/173 -func CreateContextsFromHelmArchive(fileName string, tgzReader io.Reader) ([]LintContext, error) { +func CreateContextsFromHelmArchive(ignorePaths []string, fileName string, tgzReader io.Reader) ([]LintContext, error) { ctx := newCtx(Options{}) - ctx.readObjectsFromTgzHelmChart(fileName, tgzReader) + if err := ctx.readObjectsFromTgzHelmChart(fileName, tgzReader, ignorePaths); err != nil { + return nil, err + } return []LintContext{ctx}, nil } diff --git a/pkg/lintcontext/create_contexts_test.go b/pkg/lintcontext/create_contexts_test.go index 33a917e0c..ded6f8731 100644 --- a/pkg/lintcontext/create_contexts_test.go +++ b/pkg/lintcontext/create_contexts_test.go @@ -46,6 +46,33 @@ func TestCreateContextsWithIgnorePaths(t *testing.T) { checkEmptyLintContext(t, contexts) } +func TestIgnoreSubchartManifests(t *testing.T) { + ignorePaths := []string{ + "../../tests/testdata/mychart/charts/**", + } + dir := "../../tests/testdata/mychart" + + lintCtxs, err := CreateContexts(ignorePaths, dir) + require.NoError(t, err) + lintCtx := lintCtxs[0] + objects := lintCtx.Objects() + + actualPaths := make([]string, 0, len(objects)) + for _, obj := range objects { + actualPaths = append(actualPaths, obj.Metadata.FilePath) + } + + expectedPaths := []string{ + "../../tests/testdata/mychart/templates/serviceaccount.yaml", + "../../tests/testdata/mychart/templates/service.yaml", + "../../tests/testdata/mychart/templates/hpa.yaml", + "../../tests/testdata/mychart/templates/deployment.yaml", + "../../tests/testdata/mychart/templates/tests/test-connection.yaml", + } + + assert.ElementsMatch(t, expectedPaths, actualPaths) +} + func TestCreateContextsObjectPaths(t *testing.T) { bools := []bool{false, true} @@ -117,7 +144,7 @@ func createContextsAndVerifyPaths(t *testing.T, useTarball, useAbsolutePath, ren require.NoError(t, file.Close()) }() - lintCtxs, err = CreateContextsFromHelmArchive(mockPath, file) + lintCtxs, err = CreateContextsFromHelmArchive(testIgnorePaths, mockPath, file) } else { lintCtxs, err = CreateContexts(testIgnorePaths, testPath) } @@ -165,6 +192,7 @@ func checkObjectPaths(t *testing.T, objects []Object, expectedPrefix string) { path.Join(expectedPrefix, "templates/service.yaml"), path.Join(expectedPrefix, "templates/serviceaccount.yaml"), path.Join(expectedPrefix, "templates/tests/test-connection.yaml"), + path.Join(expectedPrefix, "charts/subchart/templates/deployment.yaml"), } assert.ElementsMatchf(t, expectedPaths, actualPaths, "expected and actual template paths don't match") } diff --git a/pkg/lintcontext/parse_yaml.go b/pkg/lintcontext/parse_yaml.go index 2cf8a78df..ff7da7ee6 100644 --- a/pkg/lintcontext/parse_yaml.go +++ b/pkg/lintcontext/parse_yaml.go @@ -10,6 +10,7 @@ import ( "path/filepath" "strings" + "github.com/bmatcuk/doublestar/v4" y "github.com/ghodss/yaml" ocsAppsV1 "github.com/openshift/api/apps/v1" ocpSecV1 "github.com/openshift/api/security/v1" @@ -122,23 +123,24 @@ func (l *lintContextImpl) renderValues(chrt *chart.Chart, values map[string]inte return rendered, nil } -func (l *lintContextImpl) loadObjectsFromHelmChart(dir string) { +func (l *lintContextImpl) loadObjectsFromHelmChart(dir string, ignorePaths []string) error { renderedFiles, err := l.renderHelmChart(dir) if err != nil { l.addInvalidObjects(InvalidObject{Metadata: ObjectMetadata{FilePath: dir}, LoadErr: err}) - return + return nil } + // Paths returned by helm include redundant directory in front, therefore we strip it out. - l.loadHelmRenderedTemplates(dir, normalizeDirectoryPaths(renderedFiles)) + return l.loadHelmRenderedTemplates(dir, normalizeDirectoryPaths(renderedFiles), ignorePaths) } -func (l *lintContextImpl) loadObjectsFromTgzHelmChart(tgzFile string) { +func (l *lintContextImpl) loadObjectsFromTgzHelmChart(tgzFile string, ignorePaths []string) error { renderedFiles, err := l.renderTgzHelmChart(tgzFile) if err != nil { l.addInvalidObjects(InvalidObject{Metadata: ObjectMetadata{FilePath: tgzFile}, LoadErr: err}) - return + return nil } - l.loadHelmRenderedTemplates(tgzFile, renderedFiles) + return l.loadHelmRenderedTemplates(tgzFile, renderedFiles, ignorePaths) } func (l *lintContextImpl) renderTgzHelmChart(tgzFile string) (map[string]string, error) { @@ -251,19 +253,30 @@ func (l *lintContextImpl) renderTgzHelmChartReader(fileName string, tgzReader io return l.renderChart(fileName, chrt) } -func (l *lintContextImpl) readObjectsFromTgzHelmChart(fileName string, tgzReader io.Reader) { +func (l *lintContextImpl) readObjectsFromTgzHelmChart(fileName string, tgzReader io.Reader, ignoredPaths []string) error { renderedFiles, err := l.renderTgzHelmChartReader(fileName, tgzReader) if err != nil { l.addInvalidObjects(InvalidObject{Metadata: ObjectMetadata{FilePath: fileName}, LoadErr: err}) - return + return nil } - l.loadHelmRenderedTemplates(fileName, renderedFiles) + return l.loadHelmRenderedTemplates(fileName, renderedFiles, ignoredPaths) } -func (l *lintContextImpl) loadHelmRenderedTemplates(chartPath string, renderedFiles map[string]string) { +func (l *lintContextImpl) loadHelmRenderedTemplates(chartPath string, renderedFiles map[string]string, ignorePaths []string) error { +nextFile: for path, contents := range renderedFiles { pathToTemplate := filepath.Join(chartPath, path) + for _, path := range ignorePaths { + ignoreMatch, err := doublestar.PathMatch(path, pathToTemplate) + if err != nil { + return errors.Wrapf(err, "could not match pattern %s", path) + } + if ignoreMatch { + continue nextFile + } + } + // Skip NOTES.txt file that may be present among templates but is not a kubernetes resource. if strings.HasSuffix(pathToTemplate, string(filepath.Separator)+chartutil.NotesName) { continue @@ -274,6 +287,8 @@ func (l *lintContextImpl) loadHelmRenderedTemplates(chartPath string, renderedFi l.addInvalidObjects(InvalidObject{Metadata: ObjectMetadata{FilePath: pathToTemplate}, LoadErr: loadErr}) } } + + return nil } // normalizeDirectoryPaths removes the first element of the path that gets added by the Helm library. diff --git a/tests/testdata/mychart-0.1.0.tgz b/tests/testdata/mychart-0.1.0.tgz index 2c7e87cd096a2197096108df13e4baa32d30f31d..5fc298d62fd1bd5b1c9c8d6658c4b6ca5a2b72a7 100644 GIT binary patch delta 3890 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 Ag8%>k delta 3558 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 diff --git a/tests/testdata/mychart/Chart.lock b/tests/testdata/mychart/Chart.lock new file mode 100644 index 000000000..ab9b56c68 --- /dev/null +++ b/tests/testdata/mychart/Chart.lock @@ -0,0 +1,6 @@ +dependencies: +- name: subchart + repository: file://../subchart + version: 0.1.0 +digest: sha256:f8645a52640009a9d8905d929d3362e04720964c71e37af357b8b5e2852c365d +generated: "2023-11-23T15:35:33.69184771+01:00" diff --git a/tests/testdata/mychart/Chart.yaml b/tests/testdata/mychart/Chart.yaml index ac8a018b7..94de2134d 100644 --- a/tests/testdata/mychart/Chart.yaml +++ b/tests/testdata/mychart/Chart.yaml @@ -4,3 +4,7 @@ description: A Helm chart for Kubernetes name: mychart type: application version: 0.1.0 +dependencies: + - name: subchart + version: 0.1.0 + repository: file://../subchart diff --git a/tests/testdata/mychart/charts/subchart-0.1.0.tgz b/tests/testdata/mychart/charts/subchart-0.1.0.tgz new file mode 100644 index 0000000000000000000000000000000000000000..91414d62bf3a8541f524198de4583ce8735a2dbf GIT binary patch literal 1808 zcmV+r2k-bFiwG0|00000|0w_~VMtOiV@ORlOnEsqVl!4SWK%V1T2nbTPgYhoO;>Dc zVQyr3R8em|NM&qo0PI-ZZyUK0_cQ;Bsr_(m5U*B_;{^L=*zGl_lL+S|#o=%$DDFth zm`iRsq->qf{o4zY+7ErWDK1WeJD3mBE;%2+8O{ucOMWUUZr$iC{ANpDtG$OFd7kGd z$H(zM&-2ayeEj0s-uU?W(TkIlqvuECy?p#EAHUdx{K1jz7@i!rd--SU+BEKWGI%3D zpe1Q^0gEHXo2GjmXXBGBXC;!bvTR&t(=vz&cv(;vs)-d>mg3$8rU7byUr$p2@@`HRi`KRU@D^Z#p%131SS z_sT&EfSA;Oezcn=O`4n2n%i{pDHA92BruN zC&Ch>b_SNlTX0x6iaVr?F^jP(oEfiO0b|Bw&F5G!0E>+w>5N?#pyyKGFo4D@H8Dzx zWdW~dZ;YE*B-D-p9KhQJS}V(-w?c?=!0|a;SB4PEm2omHr@GY_xr{*|E?|Fug<;~A zxB5!q#fLe3--TvzBSw7_9S2Rso1RmQ6_ z_)A#i4oe2BrvjYy7zLebZCos&(Yd@V!(XsxLmUI(J#7KEcai^Hg%BWvneE~V!aQLX zX5?uBEF$N$1omAX+F-fxM`K`qxs+ zuqjzcpr!Fp8o1_q&5{9|*U4I!(#9xduBDzw=}PKA!po1I;(8qvXcS1q?eb}~-(qc| z^$5aSwS=kV(Kj=P7QX9U{av;aTFZWqMB`&D*Q@s$>sWBdM=xK?m5KlMNdGSfx@BDc*2nNS8(sg`9nYf@8)cRuIv=PT z{AB<4{CK1PI~gC3AN#+rF^2a)-ZV5?jMx zi|y&Z4;kEr0z6W;8b+H5fNfO*<(@OBbf34JbsI)NG zTcac*jA5Iwno8Wx{K#vyruk*hwq|1(YR#zMU{)u*-I<+cYV0V~rckb6v6n&^V7d2!C!Y&g2c2DRuw! zmki!&wFILhXMh9^+ISt#SayE-uS;hvvI96Xb!{|!IJ<;WT4LE;x>5X1@L4wf#g5`{ zJ5kL?;irA2g&y^Srd(Y4CVtQ)_9Ub0hCRuq{E9uvTpgZ`m2>vwKkNWLa4U@`cy<0) yVp(I&M-+}_vP3>gAarB2Q7?0y|JdQui_-_CJ0RR6$wE`>vAOHY{p>?nT literal 0 HcmV?d00001 diff --git a/tests/testdata/subchart/.helmignore b/tests/testdata/subchart/.helmignore new file mode 100644 index 000000000..0e8a0eb36 --- /dev/null +++ b/tests/testdata/subchart/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/tests/testdata/subchart/Chart.yaml b/tests/testdata/subchart/Chart.yaml new file mode 100644 index 000000000..8086210ae --- /dev/null +++ b/tests/testdata/subchart/Chart.yaml @@ -0,0 +1,6 @@ +apiVersion: v2 +appVersion: 1.16.0 +description: A Helm chart for Kubernetes +name: subchart +type: application +version: 0.1.0 diff --git a/tests/testdata/subchart/templates/deployment.yaml b/tests/testdata/subchart/templates/deployment.yaml new file mode 100644 index 000000000..d7514029e --- /dev/null +++ b/tests/testdata/subchart/templates/deployment.yaml @@ -0,0 +1,61 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "mychart.fullname" . }} + labels: + {{- include "mychart.labels" . | nindent 4 }} +spec: + {{- if not .Values.autoscaling.enabled }} + replicas: {{ .Values.replicaCount }} + {{- end }} + selector: + matchLabels: + {{- include "mychart.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "mychart.selectorLabels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "mychart.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - name: http + containerPort: 80 + protocol: TCP + livenessProbe: + httpGet: + path: / + port: http + readinessProbe: + httpGet: + path: / + port: http + resources: + {{- toYaml .Values.resources | nindent 12 }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/tests/testdata/subchart/values.yaml b/tests/testdata/subchart/values.yaml new file mode 100644 index 000000000..3c5f7ed79 --- /dev/null +++ b/tests/testdata/subchart/values.yaml @@ -0,0 +1,79 @@ +# Default values for mychart. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +replicaCount: 1 + +image: + repository: nginx + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "" + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +serviceAccount: + # Specifies whether a service account should be created + create: true + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + +podAnnotations: {} + +podSecurityContext: {} + # fsGroup: 2000 + +securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +service: + type: ClusterIP + port: 80 + +ingress: + enabled: false + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + hosts: + - host: chart-example.local + paths: [] + tls: [] + # - secretName: chart-example-tls + # hosts: + # - chart-example.local + +resources: {} + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + +autoscaling: + enabled: true + minReplicas: 1 + maxReplicas: 100 + targetCPUUtilizationPercentage: 80 + # targetMemoryUtilizationPercentage: 80 + +nodeSelector: {} + +tolerations: [] + +affinity: {}