Skip to content

Commit

Permalink
Merge pull request #43 from salsadigitalauorg/feature/DEVOPS-406-reme…
Browse files Browse the repository at this point in the history
…diate-drush-yaml

[DEVOPS-406] Add remediation support for drush yaml checks
  • Loading branch information
yusufhm authored Feb 13, 2024
2 parents 8acf7da + 1f3ab77 commit f2615df
Show file tree
Hide file tree
Showing 68 changed files with 2,100 additions and 1,247 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,12 @@ jobs:
with:
go-version: 1.21

- name: Vet
run: go vet ./...

- name: Run generators
run: go generate ./...

- name: Vet
run: go vet ./...

- name: Build
run: go build -ldflags="-s -w" -o build/shipshape . && ls -lh build/shipshape

Expand Down
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# Generated files
registry_gen.go
pkg/result/breach_gen.go

build
dist/
docker-compose.override.yml
node_modules
registry_gen.go
venom-output
8 changes: 8 additions & 0 deletions cmd/gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
var (
arg string
checkpackage string
breachTypes []string
)

func main() {
Expand All @@ -25,11 +26,18 @@ func main() {
}
gen.Registry(checkpackage)
break
case "breach-type":
if len(breachTypes) == 0 {
log.Fatal("missing flags; struct is required")
}
gen.BreachType(breachTypes)
break
}
}

func parseFlags() {
pflag.StringVar(&checkpackage, "checkpackage", "", "The package to which the check belongs")
pflag.StringSliceVar(&breachTypes, "type", []string{}, "The breach type")
pflag.Parse()
}

Expand Down
77 changes: 77 additions & 0 deletions cmd/gen/breachtype.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package gen

import (
"bytes"
"log"
"os"
"path/filepath"
"strings"
"text/template"
)

func BreachType(breachTypes []string) {
log.Println("Generating breach type funcs -", strings.Join(breachTypes, ","))

breachTypeFile := "breach_gen.go"
breachTypeFullFilePath := filepath.Join(getScriptPath(), "..", "..", "pkg", "result", breachTypeFile)
if err := os.Remove(breachTypeFullFilePath); err != nil && !os.IsNotExist(err) {
log.Fatalln(err)
}
createFile(breachTypeFullFilePath, "package result\n")

for _, bt := range breachTypes {
appendFileContent(breachTypeFullFilePath, breachTypeFuncs(bt))
}
}

func breachTypeFuncs(bt string) string {
tmplStr := `
/*
* {{.BreachType}}Breach
*/
func (b *{{.BreachType}}Breach) GetCheckName() string {
return b.CheckName
}
func (b *{{.BreachType}}Breach) GetCheckType() string {
return b.CheckType
}
func (b *{{.BreachType}}Breach) GetRemediation() *Remediation {
return &b.Remediation
}
func (b *{{.BreachType}}Breach) GetSeverity() string {
return b.Severity
}
func (b *{{.BreachType}}Breach) GetType() BreachType {
return BreachType{{.BreachType}}
}
func (b *{{.BreachType}}Breach) SetCommonValues(checkType string, checkName string, severity string) {
b.BreachType = b.GetType()
b.CheckType = checkType
b.CheckName = checkName
b.Severity = severity
}
func (b *{{.BreachType}}Breach) SetRemediation(status RemediationStatus, msg string) {
b.Remediation.Status = status
if msg != "" {
b.Remediation.Messages = []string{msg}
}
}
`
tmpl, err := template.New("breachTypeFuncs").Parse(tmplStr)
if err != nil {
log.Fatalln(err)
}

buf := &bytes.Buffer{}
err = tmpl.Execute(buf, struct{ BreachType string }{bt})
if err != nil {
log.Fatalln(err)
}
return buf.String()
}
79 changes: 79 additions & 0 deletions cmd/gen/helpers.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package gen

import (
"log"
"os"
"path/filepath"
"runtime"
"strings"
)

func getScriptPath() string {
_, b, _, _ := runtime.Caller(0)
return filepath.Dir(b)
}

func createFile(fullpath string, firstTimeContent string) {
if f, err := os.Stat(fullpath); err == nil && !f.IsDir() {
return
} else if !os.IsNotExist(err) {
log.Fatalln(err)
}

f, err := os.OpenFile(fullpath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
log.Fatal(err)
}
defer func() {
f.Close()
}()

if firstTimeContent == "" {
return
}

if _, err := f.Write([]byte(firstTimeContent)); err != nil {
log.Fatal(err)
}
}

func getFileLines(fullpath string) []string {
input, err := os.ReadFile(fullpath)
if err != nil {
log.Fatalln(err)
}
return strings.Split(string(input), "\n")
}

func writeFileContent(fullpath string, content string) {
err := os.WriteFile(fullpath, []byte(content), 0644)
if err != nil {
log.Fatalln(err)
}
}

func appendFileContent(fullpath string, content string) {
input, err := os.ReadFile(fullpath)
if err != nil {
log.Fatalln(err)
}
output := string(input) + content
writeFileContent(fullpath, output)
}

func writeFileLines(fullpath string, lines []string) {
output := strings.Join(lines, "\n")
err := os.WriteFile(fullpath, []byte(output), 0644)
if err != nil {
log.Fatalln(err)
}
}

func stringSliceMatch(slice []string, item string) bool {
for _, s := range slice {
if strings.Contains(s, item) {
return true
}
}
return false
}
73 changes: 9 additions & 64 deletions cmd/gen/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,88 +3,33 @@ package gen
import (
"fmt"
"log"
"os"
"path/filepath"
"runtime"
"strings"
)

var registryFile = "registry_gen.go"
var fullRegistryFilePath string

// Registry adds the checks for a package to the registry.
func Registry(chkPkg string) {
fullRegistryFilePath = filepath.Join(getScriptPath(), "../../", registryFile)
createFile()
addImportLine(chkPkg)
}

func getScriptPath() string {
_, b, _, _ := runtime.Caller(0)
return filepath.Dir(b)
}

func createFile() {
if f, err := os.Stat(fullRegistryFilePath); err == nil && !f.IsDir() {
return
} else if !os.IsNotExist(err) {
log.Fatal(err)
}

f, err := os.OpenFile(fullRegistryFilePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
log.Fatal(err)
}
defer func() {
f.Close()
}()

if _, err := f.Write([]byte("package main\n\n")); err != nil {
log.Fatal(err)
}
}

func getFileLines() []string {
input, err := os.ReadFile(fullRegistryFilePath)
if err != nil {
log.Fatalln(err)
}
log.Println("Generating checks registry - adding", chkPkg)

return strings.Split(string(input), "\n")
}
registryFile := "registry_gen.go"
registryFullFilePath := filepath.Join(getScriptPath(), "..", "..", registryFile)
createFile(registryFullFilePath, "package main\n\n")

func writeFileLines(lines []string) {
output := strings.Join(lines, "\n")
err := os.WriteFile(fullRegistryFilePath, []byte(output), 0644)
if err != nil {
log.Fatalln(err)
}
}

func addImportLine(chkPkg string) {
pkgFullName := fmt.Sprintf("github.com/salsadigitalauorg/shipshape/pkg/checks/%s", chkPkg)

fileLines := getFileLines()
fileLines := getFileLines(registryFullFilePath)
if stringSliceMatch(fileLines, pkgFullName) {
return
}

importLine := fmt.Sprintf("import _ \"%s\"", pkgFullName)
newFileLines := []string{}
for i, line := range fileLines {
if i == 2 {
// Add the import line before the last line,
// so that the last line is always a newline.
if i == len(fileLines)-1 {
newFileLines = append(newFileLines, importLine)
}
newFileLines = append(newFileLines, line)
}
writeFileLines(newFileLines)
}

func stringSliceMatch(slice []string, item string) bool {
for _, s := range slice {
if strings.Contains(s, item) {
return true
}
}
return false
writeFileLines(registryFullFilePath, newFileLines)
}
2 changes: 1 addition & 1 deletion pkg/checks/crawler/crawlercheck.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ func (c *CrawlerCheck) RunCheck() {

crawler.OnError(func(r *colly.Response, err error) {
c.Result.Status = result.Fail
c.AddBreach(result.KeyValueBreach{
c.AddBreach(&result.KeyValueBreach{
Key: fmt.Sprintf("%v", r.Request.URL),
ValueLabel: "invalid response",
Value: fmt.Sprintf("%d", r.StatusCode),
Expand Down
2 changes: 1 addition & 1 deletion pkg/checks/crawler/crawlercheck_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func TestCrawlerCheck(t *testing.T) {
c.Init(Crawler)
c.RunCheck()
assert.ElementsMatch(
[]result.Breach{result.KeyValueBreach{
[]result.Breach{&result.KeyValueBreach{
BreachType: result.BreachTypeKeyValue,
CheckType: "crawler",
Severity: "normal",
Expand Down
4 changes: 2 additions & 2 deletions pkg/checks/docker/baseimagecheck.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ func (c *BaseImageCheck) RunCheck() {
}

if len(c.Allowed) > 0 && !utils.PackageCheckString(c.Allowed, match[1], match[2]) {
c.AddBreach(result.KeyValueBreach{
c.AddBreach(&result.KeyValueBreach{
Key: name,
ValueLabel: "invalid base image",
Value: match[1],
Expand All @@ -108,7 +108,7 @@ func (c *BaseImageCheck) RunCheck() {
}

if !utils.PackageCheckString(c.Allowed, match[1], match[2]) {
c.AddBreach(result.KeyValueBreach{
c.AddBreach(&result.KeyValueBreach{
Key: name,
ValueLabel: "invalid base image",
Value: def.Image,
Expand Down
Loading

0 comments on commit f2615df

Please sign in to comment.