in scripts/generate-docs/custom_doc.go [183:279]
func renderCustomDocumentationEvent(options generateOptions, packageName string, event customDocEvent) error {
templatePath := filepath.Join(options.docTemplatesDir, fmt.Sprintf("%s/docs", packageName), "CustomDocumentation.md")
_, err := os.Stat(templatePath)
if err != nil {
return errors.Wrapf(err, "failed to find or stat template file %s", templatePath)
}
t := template.New("CustomDocumentation.md")
t, err = t.Funcs(template.FuncMap{
"overview_name": func() (string, error) {
return event.doc.Overview.Name, nil
},
"overview_description": func() (string, error) {
return event.doc.Overview.Description, nil
},
"identification_os": func() (string, error) {
var styleOses []string
for _, _os := range event.doc.Identification.Os {
if strings.ToLower(_os) == "linux" {
styleOses = append(styleOses, "Linux")
} else if strings.ToLower(_os) == "windows" {
styleOses = append(styleOses, "Windows")
} else if strings.ToLower(_os) == "macos" {
styleOses = append(styleOses, "macOS")
} else {
styleOses = append(styleOses, _os)
}
}
sort.Strings(styleOses)
return strings.Join(styleOses, ", "), nil
},
"identification_data_stream": func() (string, error) {
return event.doc.Identification.DataStream, nil
},
"identification_kql": func() (string, error) {
var terms []string
var keys []string
for key := range event.doc.Identification.Filter {
keys = append(keys, key)
}
sort.Strings(keys)
for _, key := range keys {
if len(event.doc.Identification.Filter[key]) == 1 {
terms = append(terms, fmt.Sprintf("%s : \"%s\"", key, event.doc.Identification.Filter[key][0]))
} else {
term := fmt.Sprintf("%s : (\"%s\"", key, event.doc.Identification.Filter[key][0])
for i := 1; i < len(event.doc.Identification.Filter[key]); i++ {
term += fmt.Sprintf(" or \"%s\"", event.doc.Identification.Filter[key][i])
}
term += ")"
terms = append(terms, term)
}
}
return strings.Join(terms, " and "), nil
},
"fields": func() (string, error) {
var builder strings.Builder
builder.WriteString("| Field |\n")
builder.WriteString("|---|\n")
for _, f := range event.doc.Fields.Endpoint {
detail, ok := event.doc.Fields.Details[f]
if ok {
f += "<br /><br />" + strings.TrimSpace(strings.ReplaceAll(detail.Description, "\n", " "))
}
builder.WriteString(fmt.Sprintf("| %s |\n", f))
}
return builder.String(), nil
},
}).ParseFiles(templatePath)
if err != nil {
return errors.Wrapf(err, "parsing CustomDocumentation template failed (path: %s)", templatePath)
}
subPath := event.fileSubPath
subPathLower := strings.ToLower(subPath)
if strings.HasSuffix(subPathLower, "yaml") {
subPath = subPath[:len(subPath)-4] + "md"
} else if strings.HasSuffix(subPathLower, "yml") {
subPath = subPath[:len(subPath)-3] + "md"
} else {
subPath = subPath + ".md"
}
outputPath := filepath.Join(options.customDocDir, "doc", packageName, subPath)
f, err := os.OpenFile(outputPath, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0644)
if err != nil {
return errors.Wrapf(err, "opening %s for writing failed, does the directory exist?", outputPath)
}
defer f.Close()
err = t.Execute(f, nil)
if err != nil {
return errors.Wrapf(err, "rendering custom documentation failed (path: %s)", templatePath)
}
return nil
}