diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c8e5f71..529c759 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -31,6 +31,11 @@ jobs: uses: actions/checkout@v3 - name: yaml-lint uses: ibiqlik/action-yamllint@v3 + - name: Setup golangci-lint + uses: golangci/golangci-lint-action@v2 + with: + version: latest + args: --verbose unit: name: Unit tests runs-on: ubuntu-18.04 diff --git a/.golangci.yaml b/.golangci.yaml new file mode 100644 index 0000000..f8ba09f --- /dev/null +++ b/.golangci.yaml @@ -0,0 +1,12 @@ +--- +linters: + disable-all: true + enable: + - deadcode + - gocyclo + - gofmt + - goimports + - govet + - misspell + - typecheck + - varcheck diff --git a/check/check.go b/check/check.go index a6ebdb0..06fac05 100644 --- a/check/check.go +++ b/check/check.go @@ -229,7 +229,7 @@ func (c *Check) execute() (finalOutput *testOutput, err error) { // Check for AuditConfigOutput only if AuditConfig is set if !result.flagFound && c.AuditConfig != "" { - //t.isConfigSetting = true + // t.isConfigSetting = true t.auditUsed = AuditConfig result = *(t.execute(c.AuditConfigOutput)) if !result.flagFound && t.Env != "" { diff --git a/check/check_test.go b/check/check_test.go index fd18927..79eb046 100644 --- a/check/check_test.go +++ b/check/check_test.go @@ -115,7 +115,6 @@ func TestCheckAuditEnv(t *testing.T) { } func TestCheckAuditConfig(t *testing.T) { - passingCases := []*Check{ controls.Groups[1].Checks[0], controls.Groups[1].Checks[3], diff --git a/check/controls.go b/check/controls.go index 78261ba..060198c 100644 --- a/check/controls.go +++ b/check/controls.go @@ -285,6 +285,7 @@ func (controls *Controls) ASFF() ([]*securityhub.AwsSecurityFinding, error) { } return fs, nil } + func getConfig(name string) (string, error) { r := viper.GetString(name) if len(r) == 0 { @@ -292,6 +293,7 @@ func getConfig(name string) (string, error) { } return r, nil } + func summarize(controls *Controls, state State) { switch state { case PASS: diff --git a/check/test.go b/check/test.go index 212ea18..bb36623 100644 --- a/check/test.go +++ b/check/test.go @@ -68,9 +68,11 @@ type testItem struct { auditUsed AuditUsed } -type envTestItem testItem -type pathTestItem testItem -type flagTestItem testItem +type ( + envTestItem testItem + pathTestItem testItem + flagTestItem testItem +) type compare struct { Op string @@ -236,7 +238,7 @@ func (t testItem) evaluate(s string) *testOutput { } result.flagFound = match - var isExist = "exists" + isExist := "exists" if !result.flagFound { isExist = "does not exist" } @@ -255,7 +257,6 @@ func (t testItem) evaluate(s string) *testOutput { } func compareOp(tCompareOp string, flagVal string, tCompareValue string, flagName string) (string, bool) { - expectedResultPattern := "" testResult := false diff --git a/check/test_test.go b/check/test_test.go index 8cbad72..29eb269 100644 --- a/check/test_test.go +++ b/check/test_test.go @@ -46,7 +46,6 @@ func init() { } func TestTestExecute(t *testing.T) { - cases := []struct { check *Check str string @@ -305,7 +304,6 @@ func TestTestExecute(t *testing.T) { } func TestTestExecuteExceptions(t *testing.T) { - cases := []struct { *Check str string @@ -366,7 +364,8 @@ func TestTestUnmarshal(t *testing.T) { `, kubeletConfig{}, false, - }, { + }, + { ` kind: KubeletConfiguration address: 0.0.0.0 @@ -490,34 +489,42 @@ func TestAllElementsValid(t *testing.T) { }, { source: []string{}, - target: []string{"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", + target: []string{ + "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305", "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305", "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", - "TLS_RSA_WITH_AES_256_GCM_SHA384", "TLS_RSA_WITH_AES_128_GCM_SHA256"}, + "TLS_RSA_WITH_AES_256_GCM_SHA384", "TLS_RSA_WITH_AES_128_GCM_SHA256", + }, valid: false, }, { source: []string{"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"}, - target: []string{"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", + target: []string{ + "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305", "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305", "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", - "TLS_RSA_WITH_AES_256_GCM_SHA384", "TLS_RSA_WITH_AES_128_GCM_SHA256"}, + "TLS_RSA_WITH_AES_256_GCM_SHA384", "TLS_RSA_WITH_AES_128_GCM_SHA256", + }, valid: true, }, { source: []string{"blah"}, - target: []string{"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", + target: []string{ + "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305", "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305", "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", - "TLS_RSA_WITH_AES_256_GCM_SHA384", "TLS_RSA_WITH_AES_128_GCM_SHA256"}, + "TLS_RSA_WITH_AES_256_GCM_SHA384", "TLS_RSA_WITH_AES_128_GCM_SHA256", + }, valid: false, }, { source: []string{"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "blah"}, - target: []string{"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", + target: []string{ + "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305", "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305", "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", - "TLS_RSA_WITH_AES_256_GCM_SHA384", "TLS_RSA_WITH_AES_128_GCM_SHA256"}, + "TLS_RSA_WITH_AES_256_GCM_SHA384", "TLS_RSA_WITH_AES_128_GCM_SHA256", + }, valid: false, }, } @@ -594,494 +601,628 @@ func TestCompareOp(t *testing.T) { // Test Op "eq" {label: "op=eq, both empty", op: "eq", flagVal: "", compareValue: "", expectedResultPattern: "'' is equal to ''", testResult: true, flagName: ""}, - {label: "op=eq, true==true", op: "eq", flagVal: "true", + { + label: "op=eq, true==true", op: "eq", flagVal: "true", compareValue: "true", expectedResultPattern: "'parameterTrue' is equal to 'true'", testResult: true, - flagName: "parameterTrue"}, + flagName: "parameterTrue", + }, - {label: "op=eq, false==false", op: "eq", flagVal: "false", + { + label: "op=eq, false==false", op: "eq", flagVal: "false", compareValue: "false", expectedResultPattern: "'parameterFalse' is equal to 'false'", testResult: true, - flagName: "parameterFalse"}, + flagName: "parameterFalse", + }, - {label: "op=eq, false==true", op: "eq", flagVal: "false", + { + label: "op=eq, false==true", op: "eq", flagVal: "false", compareValue: "true", expectedResultPattern: "'parameterFalse' is equal to 'true'", testResult: false, - flagName: "parameterFalse"}, + flagName: "parameterFalse", + }, - {label: "op=eq, strings match", op: "eq", flagVal: "KubeletConfiguration", + { + label: "op=eq, strings match", op: "eq", flagVal: "KubeletConfiguration", compareValue: "KubeletConfiguration", expectedResultPattern: "'--FlagNameKubeletConf' is equal to 'KubeletConfiguration'", testResult: true, - flagName: "--FlagNameKubeletConf"}, + flagName: "--FlagNameKubeletConf", + }, - {label: "op=eq, flagVal=empty", op: "eq", flagVal: "", + { + label: "op=eq, flagVal=empty", op: "eq", flagVal: "", compareValue: "KubeletConfiguration", expectedResultPattern: "'--FlagNameKubeletConf' is equal to 'KubeletConfiguration'", testResult: false, - flagName: "--FlagNameKubeletConf"}, + flagName: "--FlagNameKubeletConf", + }, - {label: "op=eq, compareValue=empty", + { + label: "op=eq, compareValue=empty", op: "eq", flagVal: "KubeletConfiguration", compareValue: "", expectedResultPattern: "'--FlagNameKubeletConf' is equal to ''", testResult: false, - flagName: "--FlagNameKubeletConf"}, + flagName: "--FlagNameKubeletConf", + }, // Test Op "noteq" - {label: "op=noteq, both empty", + { + label: "op=noteq, both empty", op: "noteq", flagVal: "", compareValue: "", expectedResultPattern: "'parameter' is not equal to ''", testResult: false, - flagName: "parameter"}, + flagName: "parameter", + }, - {label: "op=noteq, true!=true", + { + label: "op=noteq, true!=true", op: "noteq", flagVal: "true", compareValue: "true", expectedResultPattern: "'parameterTrue' is not equal to 'true'", testResult: false, - flagName: "parameterTrue"}, + flagName: "parameterTrue", + }, - {label: "op=noteq, false!=false", + { + label: "op=noteq, false!=false", op: "noteq", flagVal: "false", compareValue: "false", expectedResultPattern: "'parameterFalse' is not equal to 'false'", testResult: false, - flagName: "parameterFalse"}, + flagName: "parameterFalse", + }, - {label: "op=noteq, false!=true", + { + label: "op=noteq, false!=true", op: "noteq", flagVal: "false", compareValue: "true", expectedResultPattern: "'parameterFalse' is not equal to 'true'", testResult: true, - flagName: "parameterFalse"}, + flagName: "parameterFalse", + }, - {label: "op=noteq, strings match", + { + label: "op=noteq, strings match", op: "noteq", flagVal: "KubeletConfiguration", compareValue: "KubeletConfiguration", expectedResultPattern: "'--FlagNameKubeletConf' is not equal to 'KubeletConfiguration'", testResult: false, - flagName: "--FlagNameKubeletConf"}, + flagName: "--FlagNameKubeletConf", + }, - {label: "op=noteq, flagVal=empty", + { + label: "op=noteq, flagVal=empty", op: "noteq", flagVal: "", compareValue: "KubeletConfiguration", expectedResultPattern: "'--FlagNameKubeletConf' is not equal to 'KubeletConfiguration'", testResult: true, - flagName: "--FlagNameKubeletConf"}, + flagName: "--FlagNameKubeletConf", + }, - {label: "op=noteq, compareValue=empty", + { + label: "op=noteq, compareValue=empty", op: "noteq", flagVal: "KubeletConfiguration", compareValue: "", expectedResultPattern: "'--FlagNameKubeletConf' is not equal to ''", testResult: true, - flagName: "--FlagNameKubeletConf"}, + flagName: "--FlagNameKubeletConf", + }, // Test Op "gt" - {label: "op=gt, both empty", + { + label: "op=gt, both empty", op: "gt", flagVal: "", compareValue: "", expectedResultPattern: "Invalid Number(s) used for comparison: '' ''", testResult: false, - flagName: "flagName"}, - {label: "op=gt, 0 > 0", + flagName: "flagName", + }, + { + label: "op=gt, 0 > 0", op: "gt", flagVal: "0", compareValue: "0", expectedResultPattern: "'flagName' is greater than 0", testResult: false, - flagName: "flagName"}, - {label: "op=gt, 4 > 5", + flagName: "flagName", + }, + { + label: "op=gt, 4 > 5", op: "gt", flagVal: "4", compareValue: "5", expectedResultPattern: "'flagName' is greater than 5", testResult: false, - flagName: "flagName"}, - {label: "op=gt, 5 > 4", + flagName: "flagName", + }, + { + label: "op=gt, 5 > 4", op: "gt", flagVal: "5", compareValue: "4", expectedResultPattern: "'flagName' is greater than 4", testResult: true, - flagName: "flagName"}, - {label: "op=gt, 5 > 5", + flagName: "flagName", + }, + { + label: "op=gt, 5 > 5", op: "gt", flagVal: "5", compareValue: "5", expectedResultPattern: "'flagName' is greater than 5", testResult: false, - flagName: "flagName"}, - {label: "op=gt, Pikachu > 5", + flagName: "flagName", + }, + { + label: "op=gt, Pikachu > 5", op: "gt", flagVal: "Pikachu", compareValue: "5", expectedResultPattern: "Invalid Number(s) used for comparison: 'Pikachu' '5'", testResult: false, - flagName: "flagName"}, - {label: "op=gt, 5 > Bulbasaur", + flagName: "flagName", + }, + { + label: "op=gt, 5 > Bulbasaur", op: "gt", flagVal: "5", compareValue: "Bulbasaur", expectedResultPattern: "Invalid Number(s) used for comparison: '5' 'Bulbasaur'", testResult: false, - flagName: "flagName"}, + flagName: "flagName", + }, // Test Op "lt" - {label: "op=lt, both empty", + { + label: "op=lt, both empty", op: "lt", flagVal: "", compareValue: "", expectedResultPattern: "Invalid Number(s) used for comparison: '' ''", testResult: false, - flagName: "flagName"}, - {label: "op=lt, 0 < 0", + flagName: "flagName", + }, + { + label: "op=lt, 0 < 0", op: "lt", flagVal: "0", compareValue: "0", expectedResultPattern: "'flagName' is lower than 0", testResult: false, - flagName: "flagName"}, - {label: "op=lt, 4 < 5", + flagName: "flagName", + }, + { + label: "op=lt, 4 < 5", op: "lt", flagVal: "4", compareValue: "5", expectedResultPattern: "'flagName' is lower than 5", testResult: true, - flagName: "flagName"}, - {label: "op=lt, 5 < 4", + flagName: "flagName", + }, + { + label: "op=lt, 5 < 4", op: "lt", flagVal: "5", compareValue: "4", expectedResultPattern: "'flagName' is lower than 4", testResult: false, - flagName: "flagName"}, - {label: "op=lt, 5 < 5", + flagName: "flagName", + }, + { + label: "op=lt, 5 < 5", op: "lt", flagVal: "5", compareValue: "5", expectedResultPattern: "'flagName' is lower than 5", testResult: false, - flagName: "flagName"}, - {label: "op=lt, Charmander < 5", + flagName: "flagName", + }, + { + label: "op=lt, Charmander < 5", op: "lt", flagVal: "Charmander", compareValue: "5", expectedResultPattern: "Invalid Number(s) used for comparison: 'Charmander' '5'", testResult: false, - flagName: "flagName"}, - {label: "op=lt, 5 < Charmeleon", + flagName: "flagName", + }, + { + label: "op=lt, 5 < Charmeleon", op: "lt", flagVal: "5", compareValue: "Charmeleon", expectedResultPattern: "Invalid Number(s) used for comparison: '5' 'Charmeleon'", testResult: false, - flagName: "flagName"}, + flagName: "flagName", + }, // Test Op "gte" - {label: "op=gte, both empty", + { + label: "op=gte, both empty", op: "gte", flagVal: "", compareValue: "", expectedResultPattern: "Invalid Number(s) used for comparison: '' ''", testResult: false, - flagName: "flagName"}, - {label: "op=gte, 0 >= 0", + flagName: "flagName", + }, + { + label: "op=gte, 0 >= 0", op: "gte", flagVal: "0", compareValue: "0", expectedResultPattern: "'flagName' is greater or equal to 0", testResult: true, - flagName: "flagName"}, - {label: "op=gte, 4 >= 5", + flagName: "flagName", + }, + { + label: "op=gte, 4 >= 5", op: "gte", flagVal: "4", compareValue: "5", expectedResultPattern: "'flagName' is greater or equal to 5", testResult: false, - flagName: "flagName"}, - {label: "op=gte, 5 >= 4", + flagName: "flagName", + }, + { + label: "op=gte, 5 >= 4", op: "gte", flagVal: "5", compareValue: "4", expectedResultPattern: "'flagName' is greater or equal to 4", testResult: true, - flagName: "flagName"}, - {label: "op=gte, 5 >= 5", + flagName: "flagName", + }, + { + label: "op=gte, 5 >= 5", op: "gte", flagVal: "5", compareValue: "5", expectedResultPattern: "'flagName' is greater or equal to 5", testResult: true, - flagName: "flagName"}, - {label: "op=gte, Ekans >= 5", + flagName: "flagName", + }, + { + label: "op=gte, Ekans >= 5", op: "gte", flagVal: "Ekans", compareValue: "5", expectedResultPattern: "Invalid Number(s) used for comparison: 'Ekans' '5'", testResult: false, - flagName: "flagName"}, - {label: "op=gte, 4 >= Zubat", + flagName: "flagName", + }, + { + label: "op=gte, 4 >= Zubat", op: "gte", flagVal: "4", compareValue: "Zubat", expectedResultPattern: "Invalid Number(s) used for comparison: '4' 'Zubat'", testResult: false, - flagName: "flagName"}, + flagName: "flagName", + }, // Test Op "lte" - {label: "op=lte, both empty", + { + label: "op=lte, both empty", op: "lte", flagVal: "", compareValue: "", expectedResultPattern: "Invalid Number(s) used for comparison: '' ''", testResult: false, - flagName: "flagName"}, - {label: "op=lte, 0 <= 0", + flagName: "flagName", + }, + { + label: "op=lte, 0 <= 0", op: "lte", flagVal: "0", compareValue: "0", expectedResultPattern: "'flagName' is lower or equal to 0", testResult: true, - flagName: "flagName"}, - {label: "op=lte, 4 <= 5", + flagName: "flagName", + }, + { + label: "op=lte, 4 <= 5", op: "lte", flagVal: "4", compareValue: "5", expectedResultPattern: "'flagName' is lower or equal to 5", testResult: true, - flagName: "flagName"}, - {label: "op=lte, 5 <= 4", + flagName: "flagName", + }, + { + label: "op=lte, 5 <= 4", op: "lte", flagVal: "5", compareValue: "4", expectedResultPattern: "'flagName' is lower or equal to 4", testResult: false, - flagName: "flagName"}, - {label: "op=lte, 5 <= 5", + flagName: "flagName", + }, + { + label: "op=lte, 5 <= 5", op: "lte", flagVal: "5", compareValue: "5", expectedResultPattern: "'flagName' is lower or equal to 5", testResult: true, - flagName: "flagName"}, - {label: "op=lte, Venomoth <= 4", + flagName: "flagName", + }, + { + label: "op=lte, Venomoth <= 4", op: "lte", flagVal: "Venomoth", compareValue: "4", expectedResultPattern: "Invalid Number(s) used for comparison: 'Venomoth' '4'", testResult: false, - flagName: "flagName"}, - {label: "op=lte, 5 <= Meowth", + flagName: "flagName", + }, + { + label: "op=lte, 5 <= Meowth", op: "lte", flagVal: "5", compareValue: "Meowth", expectedResultPattern: "Invalid Number(s) used for comparison: '5' 'Meowth'", testResult: false, - flagName: "flagName"}, + flagName: "flagName", + }, // Test Op "has" - {label: "op=has, both empty", + { + label: "op=has, both empty", op: "has", flagVal: "", compareValue: "", expectedResultPattern: "'flagName' has ''", testResult: true, - flagName: "flagName"}, - {label: "op=has, flagVal=empty", + flagName: "flagName", + }, + { + label: "op=has, flagVal=empty", op: "has", flagVal: "", compareValue: "blah", expectedResultPattern: "'flagName' has 'blah'", testResult: false, - flagName: "flagName"}, - {label: "op=has, compareValue=empty", + flagName: "flagName", + }, + { + label: "op=has, compareValue=empty", op: "has", flagVal: "blah", compareValue: "", expectedResultPattern: "'flagName-blah' has ''", testResult: true, - flagName: "flagName-blah"}, - {label: "op=has, 'blah' has 'la'", + flagName: "flagName-blah", + }, + { + label: "op=has, 'blah' has 'la'", op: "has", flagVal: "blah", compareValue: "la", expectedResultPattern: "'flagName-blah' has 'la'", testResult: true, - flagName: "flagName-blah"}, - {label: "op=has, 'blah' has 'LA'", + flagName: "flagName-blah", + }, + { + label: "op=has, 'blah' has 'LA'", op: "has", flagVal: "blah", compareValue: "LA", expectedResultPattern: "'flagName-blah' has 'LA'", testResult: false, - flagName: "flagName-blah"}, - {label: "op=has, 'blah' has 'lo'", + flagName: "flagName-blah", + }, + { + label: "op=has, 'blah' has 'lo'", op: "has", flagVal: "blah", compareValue: "lo", expectedResultPattern: "'flagName-blah' has 'lo'", testResult: false, - flagName: "flagName-blah"}, + flagName: "flagName-blah", + }, // Test Op "nothave" - {label: "op=nothave, both empty", + { + label: "op=nothave, both empty", op: "nothave", flagVal: "", compareValue: "", expectedResultPattern: "'flagName' does not have ''", testResult: false, - flagName: "flagName"}, - {label: "op=nothave, flagVal=empty", + flagName: "flagName", + }, + { + label: "op=nothave, flagVal=empty", op: "nothave", flagVal: "", compareValue: "blah", expectedResultPattern: "'flagName' does not have 'blah'", testResult: true, - flagName: "flagName"}, - {label: "op=nothave, compareValue=empty", + flagName: "flagName", + }, + { + label: "op=nothave, compareValue=empty", op: "nothave", flagVal: "blah", compareValue: "", expectedResultPattern: "'flagName-blah' does not have ''", testResult: false, - flagName: "flagName-blah"}, - {label: "op=nothave, 'blah' not have 'la'", + flagName: "flagName-blah", + }, + { + label: "op=nothave, 'blah' not have 'la'", op: "nothave", flagVal: "blah", compareValue: "la", expectedResultPattern: "'flagName-blah' does not have 'la'", testResult: false, - flagName: "flagName-blah"}, - {label: "op=nothave, 'blah' not have 'LA'", + flagName: "flagName-blah", + }, + { + label: "op=nothave, 'blah' not have 'LA'", op: "nothave", flagVal: "blah", compareValue: "LA", expectedResultPattern: "'flagName-blah' does not have 'LA'", testResult: true, - flagName: "flagName-blah"}, - {label: "op=nothave, 'blah' not have 'lo'", + flagName: "flagName-blah", + }, + { + label: "op=nothave, 'blah' not have 'lo'", op: "nothave", flagVal: "blah", compareValue: "lo", expectedResultPattern: "'flagName-blah' does not have 'lo'", testResult: true, - flagName: "flagName-blah"}, + flagName: "flagName-blah", + }, // Test Op "regex" - {label: "op=regex, both empty", + { + label: "op=regex, both empty", op: "regex", flagVal: "", compareValue: "", expectedResultPattern: "'flagName' matched by regex expression ''", testResult: true, - flagName: "flagName"}, - {label: "op=regex, flagVal=empty", + flagName: "flagName", + }, + { + label: "op=regex, flagVal=empty", op: "regex", flagVal: "", compareValue: "blah", expectedResultPattern: "'flagName' matched by regex expression 'blah'", testResult: false, - flagName: "flagName"}, + flagName: "flagName", + }, // Test Op "valid_elements" - {label: "op=valid_elements, valid_elements both empty", + { + label: "op=valid_elements, valid_elements both empty", op: "valid_elements", flagVal: "", compareValue: "", expectedResultPattern: "'flagWithMultipleElements' contains valid elements from ''", testResult: true, - flagName: "flagWithMultipleElements"}, + flagName: "flagWithMultipleElements", + }, - {label: "op=valid_elements, valid_elements flagVal empty", + { + label: "op=valid_elements, valid_elements flagVal empty", op: "valid_elements", flagVal: "", compareValue: "a,b", expectedResultPattern: "'flagWithMultipleElements' contains valid elements from 'a,b'", testResult: false, - flagName: "flagWithMultipleElements"}, + flagName: "flagWithMultipleElements", + }, - {label: "op=valid_elements, valid_elements compareValue empty", + { + label: "op=valid_elements, valid_elements compareValue empty", op: "valid_elements", flagVal: "a,b", compareValue: "", expectedResultPattern: "'flagWithMultipleElements' contains valid elements from ''", testResult: false, - flagName: "flagWithMultipleElements"}, - {label: "op=valid_elements, valid_elements two list equals", + flagName: "flagWithMultipleElements", + }, + { + label: "op=valid_elements, valid_elements two list equals", op: "valid_elements", flagVal: "a,b,c", compareValue: "a,b,c", expectedResultPattern: "'flagWithMultipleElements' contains valid elements from 'a,b,c'", testResult: true, - flagName: "flagWithMultipleElements"}, - {label: "op=valid_elements, valid_elements partial flagVal valid", + flagName: "flagWithMultipleElements", + }, + { + label: "op=valid_elements, valid_elements partial flagVal valid", op: "valid_elements", flagVal: "a,c", compareValue: "a,b,c", expectedResultPattern: "'flagWithMultipleElements' contains valid elements from 'a,b,c'", testResult: true, - flagName: "flagWithMultipleElements"}, - {label: "op=valid_elements, valid_elements partial compareValue valid", + flagName: "flagWithMultipleElements", + }, + { + label: "op=valid_elements, valid_elements partial compareValue valid", op: "valid_elements", flagVal: "a,b,c", compareValue: "a,c", expectedResultPattern: "'flagWithMultipleElements' contains valid elements from 'a,c'", testResult: false, - flagName: "flagWithMultipleElements"}, + flagName: "flagWithMultipleElements", + }, // Test Op "bitmask" - {label: "op=bitmask, 644 AND 640", + { + label: "op=bitmask, 644 AND 640", op: "bitmask", flagVal: "640", compareValue: "644", expectedResultPattern: "etc/fileExamplePermission640 has permissions 640, expected 644 or more restrictive", testResult: true, - flagName: "etc/fileExamplePermission640"}, - {label: "op=bitmask, 644 AND 777", + flagName: "etc/fileExamplePermission640", + }, + { + label: "op=bitmask, 644 AND 777", op: "bitmask", flagVal: "777", compareValue: "644", expectedResultPattern: "etc/fileExamplePermission777 has permissions 777, expected 644 or more restrictive", testResult: false, - flagName: "etc/fileExamplePermission777"}, - {label: "op=bitmask, 644 AND 444", + flagName: "etc/fileExamplePermission777", + }, + { + label: "op=bitmask, 644 AND 444", op: "bitmask", flagVal: "444", compareValue: "644", expectedResultPattern: "etc/fileExamplePermission444 has permissions 444, expected 644 or more restrictive", testResult: true, - flagName: "etc/fileExamplePermission444"}, - {label: "op=bitmask, 644 AND 211", + flagName: "etc/fileExamplePermission444", + }, + { + label: "op=bitmask, 644 AND 211", op: "bitmask", flagVal: "211", compareValue: "644", expectedResultPattern: "etc/fileExamplePermission211 has permissions 211, expected 644 or more restrictive", testResult: false, - flagName: "etc/fileExamplePermission211"}, - {label: "op=bitmask, Harry AND 211", + flagName: "etc/fileExamplePermission211", + }, + { + label: "op=bitmask, Harry AND 211", op: "bitmask", flagVal: "Harry", compareValue: "644", expectedResultPattern: "Not numeric value - flag: Harry", testResult: false, - flagName: "etc/fileExample"}, - {label: "op=bitmask, 644 AND Potter", + flagName: "etc/fileExample", + }, + { + label: "op=bitmask, 644 AND Potter", op: "bitmask", flagVal: "211", compareValue: "Potter", expectedResultPattern: "Not numeric value - flag: Potter", testResult: false, - flagName: "etc/fileExample"}, + flagName: "etc/fileExample", + }, } for _, c := range cases { @@ -1136,37 +1277,36 @@ func TestToNumeric(t *testing.T) { } func TestExecuteJSONPathOnEncryptionConfig(t *testing.T) { - type Resources struct { - Resources []string `json:"resources"` - Providers []map[string]interface{} `json:"providers"` + Resources []string `json:"resources"` + Providers []map[string]interface{} `json:"providers"` } type EncryptionConfig struct { - Kind string `json:"kind"` - ApiVersion string `json:"apiVersion"` - Resources []Resources `json:"resources"` + Kind string `json:"kind"` + ApiVersion string `json:"apiVersion"` + Resources []Resources `json:"resources"` } type Key struct { - Secret string `json:"secret"` - Name string `json:"name"` + Secret string `json:"secret"` + Name string `json:"name"` } type Aescbc struct { - Keys []Key `json:"keys"` + Keys []Key `json:"keys"` } type SecretBox struct { - Keys []Key `json:"keys"` + Keys []Key `json:"keys"` } - type Aesgcm struct { - Keys []Key `json:"keys"` + type Aesgcm struct { + Keys []Key `json:"keys"` } // identity disable encryption when set as the first parameter - type Identity struct {} + type Identity struct{} cases := []struct { name string @@ -1179,11 +1319,12 @@ func TestExecuteJSONPathOnEncryptionConfig(t *testing.T) { "JSONPath parse works, results match", "{.resources[*].providers[*].aescbc.keys[*].secret}", EncryptionConfig{ - Kind: "EncryptionConfig", + Kind: "EncryptionConfig", ApiVersion: "v1", Resources: []Resources{{Resources: []string{"secrets"}, Providers: []map[string]interface{}{ - {"aescbc": Aescbc{Keys: []Key{Key{Secret: "secret1", Name: "name1"}}}}, - }}}}, + {"aescbc": Aescbc{Keys: []Key{{Secret: "secret1", Name: "name1"}}}}, + }}}, + }, "secret1", false, }, @@ -1191,11 +1332,12 @@ func TestExecuteJSONPathOnEncryptionConfig(t *testing.T) { "JSONPath parse works, results match", "{.resources[*].providers[*].aescbc.keys[*].name}", EncryptionConfig{ - Kind: "EncryptionConfig", + Kind: "EncryptionConfig", ApiVersion: "v1", Resources: []Resources{{Resources: []string{"secrets"}, Providers: []map[string]interface{}{ - {"aescbc": Aescbc{Keys: []Key{Key{Secret: "secret1", Name: "name1"}}}}, - }}}}, + {"aescbc": Aescbc{Keys: []Key{{Secret: "secret1", Name: "name1"}}}}, + }}}, + }, "name1", false, }, @@ -1203,11 +1345,12 @@ func TestExecuteJSONPathOnEncryptionConfig(t *testing.T) { "JSONPath parse works, results don't match", "{.resources[*].providers[*].aescbc.keys[*].secret}", EncryptionConfig{ - Kind: "EncryptionConfig", + Kind: "EncryptionConfig", ApiVersion: "v1", Resources: []Resources{{Resources: []string{"secrets"}, Providers: []map[string]interface{}{ - {"aesgcm": Aesgcm{Keys: []Key{Key{Secret: "secret1", Name: "name1"}}}}, - }}}}, + {"aesgcm": Aesgcm{Keys: []Key{{Secret: "secret1", Name: "name1"}}}}, + }}}, + }, "secret1", true, }, @@ -1215,11 +1358,12 @@ func TestExecuteJSONPathOnEncryptionConfig(t *testing.T) { "JSONPath parse works, results match", "{.resources[*].providers[*].aesgcm.keys[*].secret}", EncryptionConfig{ - Kind: "EncryptionConfig", + Kind: "EncryptionConfig", ApiVersion: "v1", Resources: []Resources{{Resources: []string{"secrets"}, Providers: []map[string]interface{}{ - {"aesgcm": Aesgcm{Keys: []Key{Key{Secret: "secret1", Name: "name1"}}}}, - }}}}, + {"aesgcm": Aesgcm{Keys: []Key{{Secret: "secret1", Name: "name1"}}}}, + }}}, + }, "secret1", false, }, @@ -1227,11 +1371,12 @@ func TestExecuteJSONPathOnEncryptionConfig(t *testing.T) { "JSONPath parse works, results match", "{.resources[*].providers[*].secretbox.keys[*].secret}", EncryptionConfig{ - Kind: "EncryptionConfig", + Kind: "EncryptionConfig", ApiVersion: "v1", Resources: []Resources{{Resources: []string{"secrets"}, Providers: []map[string]interface{}{ - {"secretbox": SecretBox{Keys: []Key{Key{Secret: "secret1", Name: "name1"}}}}, - }}}}, + {"secretbox": SecretBox{Keys: []Key{{Secret: "secret1", Name: "name1"}}}}, + }}}, + }, "secret1", false, }, @@ -1239,11 +1384,12 @@ func TestExecuteJSONPathOnEncryptionConfig(t *testing.T) { "JSONPath parse works, results match", "{.resources[*].providers[*].aescbc.keys[*].secret}", EncryptionConfig{ - Kind: "EncryptionConfig", + Kind: "EncryptionConfig", ApiVersion: "v1", Resources: []Resources{{Resources: []string{"secrets"}, Providers: []map[string]interface{}{ - {"aescbc": Aescbc{Keys: []Key{Key{Secret: "secret1", Name: "name1"}, Key{Secret: "secret2", Name: "name2"}}}}, - }}}}, + {"aescbc": Aescbc{Keys: []Key{{Secret: "secret1", Name: "name1"}, {Secret: "secret2", Name: "name2"}}}}, + }}}, + }, "secret1 secret2", false, }, diff --git a/cmd/common.go b/cmd/common.go index 6fb72ae..20e258a 100644 --- a/cmd/common.go +++ b/cmd/common.go @@ -47,7 +47,7 @@ func NewRunFilter(opts FilterOpts) (check.Predicate, error) { } return func(g *check.Group, c *check.Check) bool { - var test = true + test := true if len(groupIDs) > 0 { _, ok := groupIDs[g.ID] test = test && ok @@ -87,7 +87,6 @@ func runChecks(nodetype check.NodeType, testYamlFile, detectedVersion string) { // Get the set of executables we need for this section of the tests binmap, err := getBinaries(typeConf, nodetype) - // Checks that the executables we need for the section are running. if err != nil { glog.V(1).Info(fmt.Sprintf("failed to get a set of executables needed for tests: %v", err)) @@ -148,7 +147,7 @@ func generateDefaultEnvAudit(controls *check.Controls, binSubs []string) { } func parseSkipIds(skipIds string) map[string]bool { - var skipIdMap = make(map[string]bool, 0) + skipIdMap := make(map[string]bool, 0) if skipIds != "" { for _, id := range strings.Split(skipIds, ",") { skipIdMap[strings.Trim(id, " ")] = true diff --git a/cmd/common_test.go b/cmd/common_test.go index 04c8cb3..c949775 100644 --- a/cmd/common_test.go +++ b/cmd/common_test.go @@ -52,7 +52,6 @@ func TestParseSkipIds(t *testing.T) { } func TestNewRunFilter(t *testing.T) { - type TestCase struct { Name string FilterOpts FilterOpts @@ -139,7 +138,6 @@ func TestNewRunFilter(t *testing.T) { // then assert.EqualError(t, err, "group option and check option can't be used together") }) - } func TestIsMaster(t *testing.T) { @@ -212,7 +210,6 @@ func TestIsMaster(t *testing.T) { } func TestMapToCISVersion(t *testing.T) { - viperWithData, err := loadConfigForTest() if err != nil { t.Fatalf("Unable to load config file %v", err) diff --git a/cmd/kubernetes_version_test.go b/cmd/kubernetes_version_test.go index b06f79f..6ae0453 100644 --- a/cmd/kubernetes_version_test.go +++ b/cmd/kubernetes_version_test.go @@ -72,7 +72,6 @@ FAjB57z2NcIgJuVpQnGRYtr/JcH2Qdsq8bLtXaojUIWOOqoTDRLYozdMOOQ= t.Errorf("Expected error") } } - }) } } @@ -124,8 +123,8 @@ func TestGetWebData(t *testing.T) { } }) } - } + func TestGetWebDataWithRetry(t *testing.T) { okfn := func(w http.ResponseWriter, r *http.Request) { _, _ = fmt.Fprintln(w, `{ @@ -173,8 +172,8 @@ func TestGetWebDataWithRetry(t *testing.T) { } }) } - } + func TestExtractVersion(t *testing.T) { okJSON := []byte(`{ "major": "1", @@ -231,7 +230,6 @@ func TestExtractVersion(t *testing.T) { } func TestGetKubernetesURL(t *testing.T) { - resetEnvs := func() { os.Unsetenv("KUBE_BENCH_K8S_ENV") os.Unsetenv("KUBERNETES_SERVICE_HOST") @@ -277,5 +275,4 @@ func TestGetKubernetesURL(t *testing.T) { } }) } - } diff --git a/cmd/root.go b/cmd/root.go index 7d2e65a..c674aeb 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -200,7 +200,6 @@ func init() { goflag.CommandLine.VisitAll(func(goflag *goflag.Flag) { RootCmd.PersistentFlags().AddGoFlag(goflag) }) - } // initConfig reads in config file and ENV variables if set. diff --git a/cmd/securityHub.go b/cmd/securityHub.go index ae6fd81..56d6811 100644 --- a/cmd/securityHub.go +++ b/cmd/securityHub.go @@ -11,7 +11,7 @@ import ( "github.com/spf13/viper" ) -//REGION ... +// REGION ... const REGION = "AWS_REGION" func writeFinding(in []*securityhub.AwsSecurityFinding) error { @@ -20,7 +20,8 @@ func writeFinding(in []*securityhub.AwsSecurityFinding) error { return fmt.Errorf("%s not set", REGION) } sess, err := session.NewSession(&aws.Config{ - Region: aws.String(r)}, + Region: aws.String(r), + }, ) if err != nil { return err diff --git a/cmd/util.go b/cmd/util.go index 365d5ef..12546f5 100644 --- a/cmd/util.go +++ b/cmd/util.go @@ -16,26 +16,26 @@ import ( "github.com/spf13/viper" ) +// Print colors +var colors = map[check.State]*color.Color{ + check.PASS: color.New(color.FgGreen), + check.FAIL: color.New(color.FgRed), + check.WARN: color.New(color.FgYellow), + check.INFO: color.New(color.FgBlue), +} + var ( - // Print colors - colors = map[check.State]*color.Color{ - check.PASS: color.New(color.FgGreen), - check.FAIL: color.New(color.FgRed), - check.WARN: color.New(color.FgYellow), - check.INFO: color.New(color.FgBlue), + psFunc func(string) string + statFunc func(string) (os.FileInfo, error) + getBinariesFunc func(*viper.Viper, check.NodeType) (map[string]string, error) + TypeMap = map[string][]string{ + "ca": {"cafile", "defaultcafile"}, + "kubeconfig": {"kubeconfig", "defaultkubeconfig"}, + "service": {"svc", "defaultsvc"}, + "config": {"confs", "defaultconf"}, } ) -var psFunc func(string) string -var statFunc func(string) (os.FileInfo, error) -var getBinariesFunc func(*viper.Viper, check.NodeType) (map[string]string, error) -var TypeMap = map[string][]string{ - "ca": {"cafile", "defaultcafile"}, - "kubeconfig": {"kubeconfig", "defaultkubeconfig"}, - "service": {"svc", "defaultsvc"}, - "config": {"confs", "defaultconf"}, -} - func init() { psFunc = ps statFunc = os.Stat @@ -208,7 +208,6 @@ func getFiles(v *viper.Viper, fileType string) map[string]string { // verifyBin checks that the binary specified is running func verifyBin(bin string) bool { - // Strip any quotes bin = strings.Trim(bin, "'\"") @@ -290,7 +289,6 @@ Alternatively, you can specify the version with --version ` func getKubeVersion() (*KubeVersion, error) { - if k8sVer, err := getKubeVersionFromRESTAPI(); err == nil { glog.V(2).Info(fmt.Sprintf("Kubernetes REST API Reported version: %s", k8sVer)) return k8sVer, nil @@ -298,7 +296,6 @@ func getKubeVersion() (*KubeVersion, error) { // These executables might not be on the user's path. _, err := exec.LookPath("kubectl") - if err != nil { glog.V(3).Infof("Error locating kubectl: %s", err) _, err = exec.LookPath("kubelet") @@ -337,7 +334,6 @@ func getKubeVersionFromKubectl() *KubeVersion { func getKubeVersionFromKubelet() *KubeVersion { cmd := exec.Command("kubelet", "--version") out, err := cmd.CombinedOutput() - if err != nil { glog.V(2).Infof("Failed to query kubelet: %s", err) glog.V(2).Info(err) @@ -401,11 +397,9 @@ func makeSubstitutions(s string, ext string, m map[string]string) (string, []str func isEmpty(str string) bool { return strings.TrimSpace(str) == "" - } func buildComponentMissingErrorMessage(nodetype check.NodeType, component string, bins []string) string { - errMessageTemplate := ` Unable to detect running programs for component %q The following %q programs have been searched, but none of them have been found: diff --git a/cmd/util_test.go b/cmd/util_test.go index 4d88abc..79a505a 100644 --- a/cmd/util_test.go +++ b/cmd/util_test.go @@ -29,9 +29,11 @@ import ( "github.com/spf13/viper" ) -var g string -var e []error -var eIndex int +var ( + g string + e []error + eIndex int +) func fakeps(proc string) string { return g @@ -132,7 +134,7 @@ func TestGetBinaries(t *testing.T) { expectErr: false, }, { - // "anotherthing" in list of components but doesn't have a defintion + // "anotherthing" in list of components but doesn't have a definition config: map[string]interface{}{"components": []string{"apiserver", "anotherthing"}, "apiserver": map[string]interface{}{"bins": []string{"apiserver", "kube-apiserver"}}, "thing": map[string]interface{}{"bins": []string{"something else", "thing"}}}, psOut: "kube-apiserver thing", exp: map[string]string{"apiserver": "kube-apiserver"}, @@ -262,7 +264,8 @@ func TestGetConfigFiles(t *testing.T) { config: map[string]interface{}{ "components": []string{"apiserver"}, "apiserver": map[string]interface{}{"confs": []string{"apiserver", "kube-apiserver"}}, - "thing": map[string]interface{}{"confs": []string{"/my/file/thing"}}}, + "thing": map[string]interface{}{"confs": []string{"/my/file/thing"}}, + }, statResults: []error{os.ErrNotExist, nil}, exp: map[string]string{"apiserver": "kube-apiserver"}, }, @@ -271,7 +274,8 @@ func TestGetConfigFiles(t *testing.T) { config: map[string]interface{}{ "components": []string{"apiserver", "thing"}, "apiserver": map[string]interface{}{"confs": []string{"apiserver", "kube-apiserver"}}, - "thing": map[string]interface{}{"confs": []string{"/my/file/thing"}}}, + "thing": map[string]interface{}{"confs": []string{"/my/file/thing"}}, + }, statResults: []error{os.ErrNotExist, nil, nil}, exp: map[string]string{"apiserver": "kube-apiserver", "thing": "/my/file/thing"}, }, @@ -280,7 +284,8 @@ func TestGetConfigFiles(t *testing.T) { config: map[string]interface{}{ "components": []string{"apiserver", "thing"}, "apiserver": map[string]interface{}{"confs": []string{"apiserver", "kube-apiserver"}}, - "thing": map[string]interface{}{"confs": []string{"/my/file/thing"}, "defaultconf": "another/thing"}}, + "thing": map[string]interface{}{"confs": []string{"/my/file/thing"}, "defaultconf": "another/thing"}, + }, statResults: []error{os.ErrNotExist, nil, os.ErrNotExist}, exp: map[string]string{"apiserver": "kube-apiserver", "thing": "another/thing"}, }, @@ -289,7 +294,8 @@ func TestGetConfigFiles(t *testing.T) { config: map[string]interface{}{ "components": []string{"apiserver", "thing"}, "apiserver": map[string]interface{}{"confs": []string{"apiserver", "kube-apiserver"}}, - "thing": map[string]interface{}{"confs": []string{"/my/file/thing"}}}, + "thing": map[string]interface{}{"confs": []string{"/my/file/thing"}}, + }, statResults: []error{os.ErrNotExist, nil, os.ErrNotExist}, exp: map[string]string{"apiserver": "kube-apiserver", "thing": "thing"}, }, @@ -459,7 +465,6 @@ func TestGetConfigFilePath(t *testing.T) { } func TestDecrementVersion(t *testing.T) { - cases := []struct { kubeVersion string succeed bool @@ -646,7 +651,6 @@ func Test_getPlatformBenchmarkVersion(t *testing.T) { } func Test_getOcpValidVersion(t *testing.T) { - cases := []struct { openShiftVersion string succeed bool diff --git a/cmd/version.go b/cmd/version.go index beb0469..e9b2dcd 100644 --- a/cmd/version.go +++ b/cmd/version.go @@ -2,6 +2,7 @@ package cmd import ( "fmt" + "github.com/spf13/cobra" )