mirror of
https://github.com/kubescape/kubescape.git
synced 2026-04-15 06:58:11 +00:00
Merge pull request #1516 from mohaidoss/tests/core-pkg-fixhandler
Bug Fix and Test Addition for sanitizeYaml and revertSanitizeYaml Functions
This commit is contained in:
@@ -8,6 +8,7 @@ import (
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@@ -313,7 +314,7 @@ func reduceYamlExpressions(resource *ResourceFixInfo) string {
|
||||
for expr := range resource.YamlExpressions {
|
||||
expressions = append(expressions, expr)
|
||||
}
|
||||
|
||||
sort.Strings(expressions)
|
||||
return strings.Join(expressions, " | ")
|
||||
}
|
||||
|
||||
@@ -378,6 +379,10 @@ func determineNewlineSeparator(contents string) string {
|
||||
// - Since `yaml/v3` fails to serialize documents starting with a document
|
||||
// separator, we comment it out to be compatible.
|
||||
func sanitizeYaml(fileAsString string) string {
|
||||
if len(fileAsString) < 3 {
|
||||
return fileAsString
|
||||
}
|
||||
|
||||
if fileAsString[:3] == "---" {
|
||||
fileAsString = "# " + fileAsString
|
||||
}
|
||||
@@ -388,6 +393,10 @@ func sanitizeYaml(fileAsString string) string {
|
||||
//
|
||||
// For sanitization details, refer to the sanitizeYaml() function.
|
||||
func revertSanitizeYaml(fixedYamlString string) string {
|
||||
if len(fixedYamlString) < 3 {
|
||||
return fixedYamlString
|
||||
}
|
||||
|
||||
if fixedYamlString[:5] == "# ---" {
|
||||
fixedYamlString = fixedYamlString[2:]
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/armosec/armoapi-go/armotypes"
|
||||
logger "github.com/kubescape/go-logger"
|
||||
metav1 "github.com/kubescape/kubescape/v3/core/meta/datastructures/v1"
|
||||
"github.com/kubescape/kubescape/v3/internal/testutils"
|
||||
@@ -266,3 +267,387 @@ func Test_fixPathToValidYamlExpression(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestJoinStrings(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
args []string
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "nil array",
|
||||
args: nil,
|
||||
want: "",
|
||||
},
|
||||
{
|
||||
name: "empty array",
|
||||
args: []string{},
|
||||
want: "",
|
||||
},
|
||||
{
|
||||
name: "single element",
|
||||
args: []string{"a"},
|
||||
want: "a",
|
||||
},
|
||||
{
|
||||
name: "two elements",
|
||||
args: []string{"a", "b"},
|
||||
want: "ab",
|
||||
},
|
||||
{
|
||||
name: "three elements",
|
||||
args: []string{"a", "b", "c"},
|
||||
want: "abc",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := joinStrings(tt.args...); got != tt.want {
|
||||
t.Errorf("joinStrings() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetFileString(t *testing.T) {
|
||||
type args struct {
|
||||
filePath string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want string
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "file not found",
|
||||
args: args{
|
||||
filePath: "notfound.yaml",
|
||||
},
|
||||
want: "",
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "file found",
|
||||
args: args{
|
||||
filePath: "testdata/inserts/tc-01-00-input-mapping-insert-mapping.yaml",
|
||||
},
|
||||
want: `# Fix to Apply:
|
||||
# "select(di==0).spec.containers[0].securityContext.allowPrivilegeEscalation |= false"
|
||||
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: insert_to_mapping_node_1
|
||||
|
||||
spec:
|
||||
containers:
|
||||
- name: nginx_container
|
||||
image: nginx
|
||||
`,
|
||||
wantErr: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
|
||||
got, err := GetFileString(tt.args.filePath)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("getFileString() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
if got != tt.want && !tt.wantErr {
|
||||
t.Errorf("getFileString() got = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDetermineNewlineSeparator(t *testing.T) {
|
||||
type args struct {
|
||||
fileString string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "empty",
|
||||
args: args{
|
||||
fileString: "",
|
||||
},
|
||||
want: "\n",
|
||||
},
|
||||
{
|
||||
name: "windows newline",
|
||||
args: args{
|
||||
fileString: "a\r\nb\r\nc\r\n",
|
||||
},
|
||||
want: "\r\n",
|
||||
},
|
||||
{
|
||||
name: "linux newline",
|
||||
args: args{
|
||||
fileString: "a\nb\nc\n",
|
||||
},
|
||||
want: "\n",
|
||||
},
|
||||
{
|
||||
name: "oldmac newline",
|
||||
args: args{
|
||||
fileString: "a\rb\rc\r",
|
||||
},
|
||||
want: "\n",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := determineNewlineSeparator(tt.args.fileString); got != tt.want {
|
||||
t.Errorf("determineNewlineSeparator() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSanitizeYaml(t *testing.T) {
|
||||
type args struct {
|
||||
fileString string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "empty yaml",
|
||||
args: args{
|
||||
fileString: "",
|
||||
},
|
||||
want: "",
|
||||
},
|
||||
{
|
||||
name: "empty yaml with two characters",
|
||||
args: args{
|
||||
fileString: "##",
|
||||
},
|
||||
want: "##",
|
||||
},
|
||||
{
|
||||
name: "yaml/v3",
|
||||
args: args{
|
||||
fileString: `apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: insert_to_mapping_node_1
|
||||
`,
|
||||
},
|
||||
want: `apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: insert_to_mapping_node_1
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: "yaml/v2",
|
||||
args: args{
|
||||
fileString: `apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: insert_to_mapping_node_1
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: insert_to_mapping_node_2
|
||||
`,
|
||||
},
|
||||
want: `apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: insert_to_mapping_node_1
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: insert_to_mapping_node_2
|
||||
`,
|
||||
},
|
||||
{
|
||||
name: "yaml/v1",
|
||||
args: args{
|
||||
fileString: `---
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: insert_to_mapping_node_1
|
||||
`,
|
||||
},
|
||||
want: `# ---
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: insert_to_mapping_node_1
|
||||
`,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := sanitizeYaml(tt.args.fileString); got != tt.want {
|
||||
t.Errorf("sanitizeYaml() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestReduceYamlExpressions(t *testing.T) {
|
||||
type args struct {
|
||||
yamlExpressions []string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "empty",
|
||||
args: args{
|
||||
yamlExpressions: []string{},
|
||||
},
|
||||
want: "",
|
||||
},
|
||||
{
|
||||
name: "one expression",
|
||||
args: args{
|
||||
yamlExpressions: []string{
|
||||
"select(di==0).spec.containers[0].securityContext.allowPrivilegeEscalation |= false",
|
||||
},
|
||||
},
|
||||
want: "select(di==0).spec.containers[0].securityContext.allowPrivilegeEscalation |= false",
|
||||
},
|
||||
{
|
||||
name: "two expressions",
|
||||
args: args{
|
||||
yamlExpressions: []string{
|
||||
"select(di==0).spec.containers[0].securityContext.allowPrivilegeEscalation |= false",
|
||||
"select(di==0).spec.containers[0].securityContext.capabilities.drop += [\"NET_RAW\"]",
|
||||
},
|
||||
},
|
||||
want: "select(di==0).spec.containers[0].securityContext.allowPrivilegeEscalation |= false | select(di==0).spec.containers[0].securityContext.capabilities.drop += [\"NET_RAW\"]",
|
||||
},
|
||||
{
|
||||
name: "Duplicate expressions",
|
||||
args: args{
|
||||
yamlExpressions: []string{
|
||||
"select(di==0).spec.containers[0].securityContext.allowPrivilegeEscalation |= false",
|
||||
"select(di==0).spec.containers[0].securityContext.capabilities.drop += [\"NET_RAW\"]",
|
||||
"select(di==0).spec.containers[0].securityContext.allowPrivilegeEscalation |= false",
|
||||
},
|
||||
},
|
||||
want: "select(di==0).spec.containers[0].securityContext.allowPrivilegeEscalation |= false | select(di==0).spec.containers[0].securityContext.capabilities.drop += [\"NET_RAW\"]",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
resource := &ResourceFixInfo{}
|
||||
resource.YamlExpressions = make(map[string]armotypes.FixPath)
|
||||
|
||||
for _, yamlExpression := range tt.args.yamlExpressions {
|
||||
resource.YamlExpressions[yamlExpression] = armotypes.FixPath{}
|
||||
}
|
||||
got := reduceYamlExpressions(resource)
|
||||
assert.Equal(t, tt.want, got)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetLocalPath(t *testing.T) {
|
||||
type args struct {
|
||||
report *reporthandlingv2.PostureReport
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want string
|
||||
}{
|
||||
{
|
||||
name: "empty report",
|
||||
args: args{
|
||||
report: &reporthandlingv2.PostureReport{},
|
||||
},
|
||||
want: "",
|
||||
},
|
||||
{
|
||||
name: "No scan metadata",
|
||||
args: args{
|
||||
report: &reporthandlingv2.PostureReport{
|
||||
Metadata: reporthandlingv2.Metadata{
|
||||
ScanMetadata: reporthandlingv2.ScanMetadata{},
|
||||
},
|
||||
},
|
||||
},
|
||||
want: "",
|
||||
},
|
||||
{
|
||||
name: "Scan target GitLocal",
|
||||
args: args{
|
||||
report: &reporthandlingv2.PostureReport{
|
||||
Metadata: reporthandlingv2.Metadata{
|
||||
ScanMetadata: reporthandlingv2.ScanMetadata{
|
||||
ScanningTarget: reporthandlingv2.ScanningTarget(3),
|
||||
},
|
||||
ContextMetadata: reporthandlingv2.ContextMetadata{
|
||||
RepoContextMetadata: &reporthandlingv2.RepoContextMetadata{
|
||||
LocalRootPath: "/tmp",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
want: "/tmp",
|
||||
},
|
||||
{
|
||||
name: "Scan target Directory",
|
||||
args: args{
|
||||
report: &reporthandlingv2.PostureReport{
|
||||
Metadata: reporthandlingv2.Metadata{
|
||||
ScanMetadata: reporthandlingv2.ScanMetadata{
|
||||
ScanningTarget: reporthandlingv2.ScanningTarget(2),
|
||||
},
|
||||
ContextMetadata: reporthandlingv2.ContextMetadata{
|
||||
DirectoryContextMetadata: &reporthandlingv2.DirectoryContextMetadata{
|
||||
BasePath: "/tmp",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "Scan target File",
|
||||
args: args{
|
||||
report: &reporthandlingv2.PostureReport{
|
||||
Metadata: reporthandlingv2.Metadata{
|
||||
ScanMetadata: reporthandlingv2.ScanMetadata{
|
||||
ScanningTarget: reporthandlingv2.ScanningTarget(1),
|
||||
},
|
||||
ContextMetadata: reporthandlingv2.ContextMetadata{
|
||||
FileContextMetadata: &reporthandlingv2.FileContextMetadata{
|
||||
FilePath: "/tmp/target.yaml",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
want: "/tmp",
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := getLocalPath(tt.args.report); got != tt.want {
|
||||
t.Errorf("getLocalPath() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user