github.com/aquasecurity/trivy-iac@v0.8.1-0.20240127024015-3d8e412cf0ab/test/kubernetes_test.go (about)

     1  package test
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"os"
     7  	"strings"
     8  	"testing"
     9  
    10  	"github.com/aquasecurity/defsec/pkg/scan"
    11  	"github.com/aquasecurity/defsec/pkg/scanners/options"
    12  	"github.com/stretchr/testify/assert"
    13  	"github.com/stretchr/testify/require"
    14  
    15  	"github.com/aquasecurity/trivy-iac/pkg/scanners/kubernetes"
    16  )
    17  
    18  func Test_Kubernetes_RegoPoliciesFromDisk(t *testing.T) {
    19  	t.Parallel()
    20  
    21  	entries, err := os.ReadDir("./testdata/kubernetes")
    22  	require.NoError(t, err)
    23  
    24  	scanner := kubernetes.NewScanner(
    25  		options.ScannerWithPerResultTracing(true),
    26  		options.ScannerWithEmbeddedPolicies(true),
    27  		options.ScannerWithEmbeddedLibraries(true),
    28  	)
    29  
    30  	srcFS := os.DirFS("../")
    31  
    32  	results, err := scanner.ScanFS(context.TODO(), srcFS, "test/testdata/kubernetes")
    33  	require.NoError(t, err)
    34  
    35  	for _, entry := range entries {
    36  		if !entry.IsDir() {
    37  			continue
    38  		}
    39  		if entry.Name() == "optional" {
    40  			continue
    41  		}
    42  		t.Run(entry.Name(), func(t *testing.T) {
    43  			var matched bool
    44  			for _, result := range results {
    45  				if result.Rule().HasID(entry.Name()) {
    46  
    47  					failCase := fmt.Sprintf("test/testdata/kubernetes/%s/denied.yaml", entry.Name())
    48  					passCase := fmt.Sprintf("test/testdata/kubernetes/%s/allowed.yaml", entry.Name())
    49  
    50  					switch result.Range().GetFilename() {
    51  					case failCase:
    52  						assert.Equal(t, scan.StatusFailed, result.Status(), "Rule should have failed, but didn't.")
    53  						assert.Greater(t, result.Range().GetStartLine(), 0, "We should have line numbers for a failure")
    54  						assert.Greater(t, result.Range().GetEndLine(), 0, "We should have line numbers for a failure")
    55  						matched = true
    56  					case passCase:
    57  						assert.Equal(t, scan.StatusPassed, result.Status(), "Rule should have passed, but didn't.")
    58  						matched = true
    59  					default:
    60  						if strings.Contains(result.Range().GetFilename(), entry.Name()) {
    61  							t.Fatal(result.Range().GetFilename())
    62  						}
    63  						continue
    64  					}
    65  
    66  					if t.Failed() {
    67  						fmt.Println("Test failed - rego trace follows:")
    68  						for _, trace := range result.Traces() {
    69  							fmt.Println(trace)
    70  						}
    71  					}
    72  				}
    73  			}
    74  			assert.True(t, matched, "Neither a pass or fail result was found for %s - did you add example code for it?", entry.Name())
    75  		})
    76  	}
    77  }
    78  
    79  func Test_Kubernetes_RegoPoliciesEmbedded(t *testing.T) {
    80  	t.Parallel()
    81  
    82  	entries, err := os.ReadDir("./testdata/kubernetes")
    83  	require.NoError(t, err)
    84  
    85  	scanner := kubernetes.NewScanner(options.ScannerWithEmbeddedPolicies(true), options.ScannerWithEmbeddedLibraries(true), options.ScannerWithEmbeddedLibraries(true))
    86  
    87  	srcFS := os.DirFS("../")
    88  
    89  	results, err := scanner.ScanFS(context.TODO(), srcFS, "test/testdata/kubernetes")
    90  	require.NoError(t, err)
    91  
    92  	for _, entry := range entries {
    93  		if !entry.IsDir() {
    94  			continue
    95  		}
    96  		if entry.Name() == "optional" {
    97  			continue
    98  		}
    99  		t.Run(entry.Name(), func(t *testing.T) {
   100  			var matched bool
   101  			for _, result := range results {
   102  				if result.Rule().HasID(entry.Name()) {
   103  
   104  					failCase := fmt.Sprintf("test/testdata/kubernetes/%s/denied.yaml", entry.Name())
   105  					passCase := fmt.Sprintf("test/testdata/kubernetes/%s/allowed.yaml", entry.Name())
   106  
   107  					switch result.Range().GetFilename() {
   108  					case failCase:
   109  						assert.Equal(t, scan.StatusFailed, result.Status(), "Rule should have failed, but didn't.")
   110  						assert.Greater(t, result.Range().GetStartLine(), 0, "We should have line numbers for a failure")
   111  						assert.Greater(t, result.Range().GetEndLine(), 0, "We should have line numbers for a failure")
   112  						matched = true
   113  					case passCase:
   114  						assert.Equal(t, scan.StatusPassed, result.Status(), "Rule should have passed, but didn't.")
   115  						matched = true
   116  					default:
   117  						continue
   118  					}
   119  
   120  					if t.Failed() {
   121  						fmt.Println("Test failed - rego trace follows:")
   122  						for _, trace := range result.Traces() {
   123  							fmt.Println(trace)
   124  						}
   125  					}
   126  				}
   127  			}
   128  			assert.True(t, matched, "Neither a pass or fail result was found for %s - did you add example code for it?", entry.Name())
   129  		})
   130  	}
   131  }