Skip to content

Commit ca61364

Browse files
authored
enhancing crd check to disallow more permutations (#587)
Signed-off-by: Adam D. Cornett <adc@redhat.com>
1 parent 4290d4c commit ca61364

7 files changed

Lines changed: 100 additions & 1 deletion
Binary file not shown.
404 Bytes
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

internal/chartverifier/checks/checks.go

Lines changed: 95 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828

2929
"github.com/opdev/getocprange"
3030
"helm.sh/helm/v3/pkg/action"
31+
"helm.sh/helm/v3/pkg/chart"
3132
"helm.sh/helm/v3/pkg/lint"
3233
"helm.sh/helm/v3/pkg/lint/support"
3334

@@ -234,14 +235,107 @@ func NotContainCRDs(opts *CheckOptions) (Result, error) {
234235

235236
r := NewResult(true, ChartDoesNotContainCRDs)
236237

237-
if len(c.CRDObjects()) > 0 {
238+
// Check standard CRD directory in main chart and dependencies
239+
if hasCRDObjects(c) {
240+
r.Ok = false
241+
r.SetResult(false, ChartContainCRDs)
242+
return r, nil
243+
}
244+
245+
// Check for CRDs in templates (main chart and dependencies)
246+
if hasCRDInTemplates(c) {
247+
r.Ok = false
248+
r.SetResult(false, ChartContainCRDs)
249+
return r, nil
250+
}
251+
252+
// Check for CRDs in files (root directory of main chart and dependencies)
253+
if hasCRDInFiles(c) {
238254
r.Ok = false
239255
r.SetResult(false, ChartContainCRDs)
256+
return r, nil
240257
}
241258

242259
return r, nil
243260
}
244261

262+
func hasCRDObjects(c *chart.Chart) bool {
263+
// Check main chart CRDs directory
264+
if len(c.CRDObjects()) > 0 {
265+
return true
266+
}
267+
268+
// Recursively check dependencies' CRDs directories
269+
for _, dep := range c.Dependencies() {
270+
if hasCRDObjects(dep) {
271+
return true
272+
}
273+
}
274+
275+
return false
276+
}
277+
278+
func hasCRDInTemplates(c *chart.Chart) bool {
279+
// Check main chart templates
280+
for _, f := range c.Templates {
281+
if !strings.HasSuffix(f.Name, ".yaml") && !strings.HasSuffix(f.Name, ".yml") {
282+
continue
283+
}
284+
if isCRDFile(f.Data) {
285+
return true
286+
}
287+
}
288+
289+
// Check dependency/subchart templates
290+
for _, dep := range c.Dependencies() {
291+
if hasCRDInTemplates(dep) {
292+
return true
293+
}
294+
}
295+
296+
return false
297+
}
298+
299+
func isCRDFile(data []byte) bool {
300+
// Split on YAML document separator for multi-doc files
301+
docs := strings.Split(string(data), "\n---")
302+
for _, doc := range docs {
303+
for _, line := range strings.Split(doc, "\n") {
304+
trimmed := strings.TrimSpace(line)
305+
if strings.HasPrefix(trimmed, "kind:") {
306+
kind := strings.TrimSpace(strings.TrimPrefix(trimmed, "kind:"))
307+
// Remove surrounding quotes if present (both single and double)
308+
kind = strings.Trim(kind, "\"'")
309+
if kind == "CustomResourceDefinition" {
310+
return true
311+
}
312+
}
313+
}
314+
}
315+
return false
316+
}
317+
318+
func hasCRDInFiles(c *chart.Chart) bool {
319+
// Check this chart's files (root directory)
320+
for _, f := range c.Files {
321+
if !strings.HasSuffix(f.Name, ".yaml") && !strings.HasSuffix(f.Name, ".yml") {
322+
continue
323+
}
324+
if isCRDFile(f.Data) {
325+
return true
326+
}
327+
}
328+
329+
// Recursively check dependencies
330+
for _, dep := range c.Dependencies() {
331+
if hasCRDInFiles(dep) {
332+
return true
333+
}
334+
}
335+
336+
return false
337+
}
338+
245339
func HelmLint(opts *CheckOptions) (Result, error) {
246340
_, p, err := LoadChartFromURI(opts)
247341
if err != nil {

internal/chartverifier/checks/checks_test.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,11 @@ func TestNotContainCRDs(t *testing.T) {
313313

314314
negativeTestCases := []testCase{
315315
{description: "Contain CRDs", uri: "chart-0.1.0-v3.with-crd.tgz"},
316+
{description: "Contain CRDs in /templates", uri: "chart-0.1.0-v3.with-crd-in-templates.tgz"},
317+
{description: "Contain CRDs in root", uri: "chart-0.1.0-v3.with-crd-in-root.tgz"},
318+
{description: "Contain CRDs in /charts", uri: "chart-0.1.0-v3.with-crd-in-charts.tgz"},
319+
{description: "Contain CRDs in subchart /crds", uri: "chart-0.1.0-v3.with-crd-in-subchart-crds.tgz"},
320+
{description: "Contain CRDs with quoted kind values", uri: "chart-0.1.0-v3.with-crd-quoted-kind.tgz"},
316321
}
317322

318323
for _, tc := range negativeTestCases {

0 commit comments

Comments
 (0)