github.com/zntrio/harp/v2@v2.0.9/pkg/bundle/ruleset/package_test.go (about)

     1  // Licensed to Elasticsearch B.V. under one or more contributor
     2  // license agreements. See the NOTICE file distributed with
     3  // this work for additional information regarding copyright
     4  // ownership. Elasticsearch B.V. licenses this file to you under
     5  // the Apache License, Version 2.0 (the "License"); you may
     6  // not use this file except in compliance with the License.
     7  // You may obtain a copy of the License at
     8  //
     9  //     http://www.apache.org/licenses/LICENSE-2.0
    10  //
    11  // Unless required by applicable law or agreed to in writing,
    12  // software distributed under the License is distributed on an
    13  // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
    14  // KIND, either express or implied.  See the License for the
    15  // specific language governing permissions and limitations
    16  // under the License.
    17  
    18  package ruleset
    19  
    20  import (
    21  	"context"
    22  	"os"
    23  	"path/filepath"
    24  	"testing"
    25  
    26  	fuzz "github.com/google/gofuzz"
    27  	"github.com/stretchr/testify/assert"
    28  	bundlev1 "github.com/zntrio/harp/v2/api/gen/go/harp/bundle/v1"
    29  )
    30  
    31  func mustLoadRuleSet(filePath string) *bundlev1.RuleSet {
    32  	f, err := os.Open(filePath)
    33  	if err != nil {
    34  		panic(err)
    35  	}
    36  
    37  	p, err := YAML(f)
    38  	if err != nil {
    39  		panic(err)
    40  	}
    41  
    42  	return p
    43  }
    44  
    45  func TestEvaluate(t *testing.T) {
    46  	type args struct {
    47  		specFilePath string
    48  		b            *bundlev1.Bundle
    49  	}
    50  	tests := []struct {
    51  		name    string
    52  		args    args
    53  		wantErr bool
    54  	}{
    55  		{
    56  			name:    "nil",
    57  			wantErr: true,
    58  		},
    59  		{
    60  			name: "empty bundle",
    61  			args: args{
    62  				specFilePath: "../../../test/fixtures/ruleset/valid/cso.yaml",
    63  				b:            &bundlev1.Bundle{},
    64  			},
    65  			wantErr: true,
    66  		},
    67  		{
    68  			name: "cso - invalid bundle",
    69  			args: args{
    70  				specFilePath: "../../../test/fixtures/ruleset/valid/cso.yaml",
    71  				b: &bundlev1.Bundle{
    72  					Packages: []*bundlev1.Package{
    73  						{
    74  							Name: "app/qa/security",
    75  						},
    76  					},
    77  				},
    78  			},
    79  			wantErr: true,
    80  		},
    81  		{
    82  			name: "cso - valid bundle",
    83  			args: args{
    84  				specFilePath: "../../../test/fixtures/ruleset/valid/cso.yaml",
    85  				b: &bundlev1.Bundle{
    86  					Packages: []*bundlev1.Package{
    87  						{
    88  							Name: "app/qa/security/harp/v1.0.0/server/database/credentials",
    89  						},
    90  					},
    91  				},
    92  			},
    93  			wantErr: false,
    94  		},
    95  		{
    96  			name: "db - valid bundle",
    97  			args: args{
    98  				specFilePath: "../../../test/fixtures/ruleset/valid/database-secret-validator.yaml",
    99  				b: &bundlev1.Bundle{
   100  					Packages: []*bundlev1.Package{
   101  						{
   102  							Name: "app/qa/security/harp/v1.0.0/server/database/credentials",
   103  							Secrets: &bundlev1.SecretChain{
   104  								Data: []*bundlev1.KV{
   105  									{
   106  										Key: "DB_HOST",
   107  									},
   108  									{
   109  										Key: "DB_NAME",
   110  									},
   111  									{
   112  										Key: "DB_USER",
   113  									},
   114  									{
   115  										Key: "DB_PASSWORD",
   116  									},
   117  								},
   118  							},
   119  						},
   120  					},
   121  				},
   122  			},
   123  			wantErr: false,
   124  		},
   125  		{
   126  			name: "db - invalid bundle",
   127  			args: args{
   128  				specFilePath: "../../../test/fixtures/ruleset/valid/database-secret-validator.yaml",
   129  				b: &bundlev1.Bundle{
   130  					Packages: []*bundlev1.Package{
   131  						{
   132  							Name: `app/qa/security/harp/v1.0.0/server/database/credentials`,
   133  							Secrets: &bundlev1.SecretChain{
   134  								Data: []*bundlev1.KV{
   135  									{
   136  										Key: "DB_HOST",
   137  									},
   138  								},
   139  							},
   140  						},
   141  					},
   142  				},
   143  			},
   144  			wantErr: true,
   145  		},
   146  		{
   147  			name: "rego - valid bundle",
   148  			args: args{
   149  				specFilePath: "../../../test/fixtures/ruleset/valid/rego.yaml",
   150  				b: &bundlev1.Bundle{
   151  					Packages: []*bundlev1.Package{
   152  						{
   153  							Name: "app/qa/security/harp/v1.0.0/server/database/credentials",
   154  							Annotations: map[string]string{
   155  								"infosec.elastic.co/v1/SecretPolicy#severity": "moderate",
   156  							},
   157  							Secrets: &bundlev1.SecretChain{
   158  								Data: []*bundlev1.KV{
   159  									{
   160  										Key: "DB_HOST",
   161  									},
   162  									{
   163  										Key: "DB_NAME",
   164  									},
   165  									{
   166  										Key: "DB_USER",
   167  									},
   168  									{
   169  										Key: "DB_PASSWORD",
   170  									},
   171  								},
   172  							},
   173  						},
   174  					},
   175  				},
   176  			},
   177  			wantErr: false,
   178  		},
   179  		{
   180  			name: "rego - invalid bundle",
   181  			args: args{
   182  				specFilePath: "../../../test/fixtures/ruleset/valid/rego.yaml",
   183  				b: &bundlev1.Bundle{
   184  					Packages: []*bundlev1.Package{
   185  						{
   186  							Name: "app/qa/security/harp/v1.0.0/server/database/credentials",
   187  							Secrets: &bundlev1.SecretChain{
   188  								Data: []*bundlev1.KV{},
   189  							},
   190  						},
   191  					},
   192  				},
   193  			},
   194  			wantErr: true,
   195  		},
   196  		{
   197  			name: "regofile - valid bundle",
   198  			args: args{
   199  				specFilePath: "../../../test/fixtures/ruleset/valid/rego-file.yaml",
   200  				b: &bundlev1.Bundle{
   201  					Packages: []*bundlev1.Package{
   202  						{
   203  							Name: "app/qa/security/harp/v1.0.0/server/database/credentials",
   204  							Annotations: map[string]string{
   205  								"infosec.elastic.co/v1/SecretPolicy#severity": "moderate",
   206  							},
   207  							Secrets: &bundlev1.SecretChain{
   208  								Data: []*bundlev1.KV{
   209  									{
   210  										Key: "DB_HOST",
   211  									},
   212  									{
   213  										Key: "DB_NAME",
   214  									},
   215  									{
   216  										Key: "DB_USER",
   217  									},
   218  									{
   219  										Key: "DB_PASSWORD",
   220  									},
   221  								},
   222  							},
   223  						},
   224  					},
   225  				},
   226  			},
   227  			wantErr: false,
   228  		},
   229  		{
   230  			name: "regofile - invalid bundle",
   231  			args: args{
   232  				specFilePath: "../../../test/fixtures/ruleset/valid/rego-file.yaml",
   233  				b: &bundlev1.Bundle{
   234  					Packages: []*bundlev1.Package{
   235  						{
   236  							Name: "app/qa/security/harp/v1.0.0/server/database/credentials",
   237  							Secrets: &bundlev1.SecretChain{
   238  								Data: []*bundlev1.KV{},
   239  							},
   240  						},
   241  					},
   242  				},
   243  			},
   244  			wantErr: true,
   245  		},
   246  	}
   247  	for _, tt := range tests {
   248  		t.Run(tt.name, func(t *testing.T) {
   249  			var spec *bundlev1.RuleSet
   250  			if tt.args.specFilePath != "" {
   251  				currentDir, err := os.Getwd()
   252  				assert.NoError(t, err)
   253  
   254  				absPath, err := filepath.Abs(tt.args.specFilePath)
   255  				assert.NoError(t, err)
   256  
   257  				dir, file := filepath.Split(absPath)
   258  				err = os.Chdir(dir)
   259  				assert.NoError(t, err)
   260  				spec = mustLoadRuleSet(file)
   261  
   262  				defer os.Chdir(currentDir)
   263  			}
   264  
   265  			err := Evaluate(context.Background(), tt.args.b, spec)
   266  			if (err != nil) != tt.wantErr {
   267  				t.Errorf("Evaluate() error = %v, wantErr %v", err, tt.wantErr)
   268  				return
   269  			}
   270  		})
   271  	}
   272  }
   273  
   274  func TestEvaluate_Fuzz(t *testing.T) {
   275  	// Making sure the descrption never panics
   276  	for i := 0; i < 500; i++ {
   277  		f := fuzz.New()
   278  
   279  		rs := bundlev1.RuleSet{
   280  			ApiVersion: "harp.elastic.co/v1",
   281  			Kind:       "RuleSet",
   282  			Meta:       &bundlev1.RuleSetMeta{},
   283  			Spec: &bundlev1.RuleSetSpec{
   284  				Rules: []*bundlev1.Rule{
   285  					{},
   286  				},
   287  			},
   288  		}
   289  		file := bundlev1.Bundle{
   290  			Packages: []*bundlev1.Package{
   291  				{
   292  					Name: "foo",
   293  					Secrets: &bundlev1.SecretChain{
   294  						Data: []*bundlev1.KV{
   295  							{
   296  								Key:   "k1",
   297  								Value: []byte("v1"),
   298  							},
   299  						},
   300  					},
   301  				},
   302  			},
   303  		}
   304  
   305  		f.Fuzz(&rs)
   306  		f.Fuzz(&file)
   307  
   308  		// Execute
   309  		Evaluate(context.Background(), &file, &rs)
   310  	}
   311  }