Documentation
¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
View Source
var DV2EMAILCmd = &cobra.Command{ Use: "dv2email", Short: "Email a Dataview following Geneos Action/Effect conventions", Long: strings.ReplaceAll(` Email a Dataview following Geneos Action/Effect conventions. When called without a sub-command and no arguments the program processes environment variables setup as per Geneos Action/Effect conventions and constructs an HTML Email of the dataview the data item is from. Settings for the Gateway REST connection and defaults for the EMail gateway can be located in dv2email.yaml (either in the working directory or in the user's .config/dv2email directory) `, "|", "`"), DisableAutoGenTag: true, DisableSuggestions: true, RunE: func(cmd *cobra.Command, _ []string) (err error) { gwcf := cf.Sub("gateway") gwcf.SetDefault("allow-insecure", true) u := &url.URL{ Scheme: "http", Host: fmt.Sprintf("%s:%d", gwcf.GetString("host", config.Default("localhost")), gwcf.GetInt("port", config.Default(7038))), } gwcf.SetDefault("use-tls", true) if gwcf.GetBool("use-tls") { u.Scheme = "https" } password := &config.Plaintext{} username := gwcf.GetString("username") gateway := gwcf.GetString("name") if username != "" { password = gwcf.GetPassword("password") } if username == "" && gateway != "" { creds := config.FindCreds("gateway:"+gateway, config.SetAppName("geneos")) if creds != nil { username = creds.GetString("username") password = creds.GetPassword("password") } } gw, err := commands.DialGateway(u, commands.SetBasicAuth(username, password), commands.AllowInsecureCertificates(gwcf.GetBool("allow-insecure")), ) if err != nil { log.Fatal().Err(err).Msg("") } htmlTemplate := cf.GetString("html-template", config.Default(htmlDefaultTemplate)) ht, err := htemplate.New("dataview").Parse(htmlTemplate) if err != nil { return } textTemplate := cf.GetString("text-template", config.Default(textDefaultTemplate)) tt, err := ttemplate.New("dataview").Parse(textTemplate) if err != nil { return } tmplData := dv2emailData{ Dataviews: []*commands.Dataview{}, Rows: []string{}, Env: make(map[string]string, len(os.Environ())), } for _, e := range os.Environ() { n := strings.SplitN(e, "=", 2) tmplData.Env[n[0]] = n[1] } dv, err := xpath.Parse(cf.GetString("_variablepath")) dv = dv.ResolveTo(&xpath.Dataview{}) if err != nil { return } dataviews, err := gw.Match(dv, 0) if err != nil { return } if len(dataviews) == 0 { return errors.New("no matching dataviews found") } em := config.New() epassword := &config.Plaintext{} emcf := cf.Sub("email") eusername := emcf.GetString("username") smtpserver := emcf.GetString("smtp", config.Default("localhost")) smtptls := emcf.GetString("use-tls", config.Default("default")) if eusername != "" { epassword = emcf.GetPassword("password") } if eusername == "" { creds := config.FindCreds(smtpserver, config.SetAppName("geneos")) if creds != nil { eusername = creds.GetString("username") epassword = creds.GetPassword("password") } } em.SetDefault("_smtp_username", eusername) em.SetDefault("_smtp_password", epassword.String()) em.SetDefault("_smtp_server", smtpserver) em.SetDefault("_smtp_tls", smtptls) em.SetDefault("_smtp_port", emcf.GetInt("port", config.Default(25))) em.SetDefault("_from", emcf.GetString("from")) em.SetDefault("_to", emcf.GetString("to")) em.SetDefault("_subject", emcf.GetString("subject", config.Default("Geneos Alert"))) for _, e := range os.Environ() { n := strings.SplitN(e, "=", 2) em.Set(n[0], n[1]) } for _, dataview := range dataviews { data, err := gw.Snapshot(dataview, commands.Scope{Value: true, Severity: true}) if err != nil { log.Error().Err(err).Msg("") continue } tmplData.Dataviews = append(tmplData.Dataviews, data) headlines := match(data.Name, "headline-filter", "__headlines", em) if len(headlines) > 0 { nh := map[string]commands.DataItem{} for _, h := range headlines { h = strings.TrimSpace(h) for oh, headline := range data.Headlines { if ok, err := path.Match(h, oh); err == nil && ok { nh[oh] = headline } } } data.Headlines = nh } // the first column is either from `first-column` in config // (matched against the dataview name) or from the // environment variable _FIRSTCOLUMN or `rowname` and is // always the first column. var rowname string defaultRowName := match(data.Name, "first-column", "_firstcolumn", em) if len(defaultRowName) > 0 { rowname = defaultRowName[0] } else { rowname = em.GetString("_FIRSTCOLUMN", config.Default("rowname")) } data.Columns[0] = rowname cols := match(data.Name, "column-filter", "__columns", em) if len(cols) > 0 { nc := []string{rowname} for _, c := range cols { c = strings.TrimSpace(c) for _, oc := range data.Columns { if oc == rowname { continue } if ok, err := path.Match(c, oc); err == nil && ok { nc = append(nc, oc) } } } data.Columns = nc } rows := match(data.Name, "row-filter", "__rows", em) if len(rows) > 0 { nr := map[string]map[string]commands.DataItem{} for _, r := range rows { r = strings.TrimSpace(r) for rowname, row := range data.Table { if ok, err := path.Match(r, rowname); err == nil && ok { nr[rowname] = row } } } data.Table = nr } for k := range data.Table { tmplData.Rows = append(tmplData.Rows, k) } asc := true matches := matchForName(data.Name, "row-order") if len(matches) > 0 { m := matches[0] switch { case strings.HasSuffix(m, "-"): asc = false m = m[:len(m)-1] case strings.HasSuffix(m, "+"): m = m[:len(m)-1] fallthrough default: asc = true } if m == "rowname" || m == data.Columns[0] { sort.Slice(tmplData.Rows, func(i, j int) bool { if asc { return tmplData.Rows[i] < tmplData.Rows[j] } else { return tmplData.Rows[j] < tmplData.Rows[i] } }) } else { sort.Slice(tmplData.Rows, func(i, j int) bool { r := tmplData.Rows a := data.Table[r[i]][m].Value af, _ := strconv.ParseFloat(a, 64) b := data.Table[r[j]][m].Value bf, _ := strconv.ParseFloat(b, 64) if a == b { if asc { return a < b } else { return a > b } } if asc { return af < bf } return bf < af }) } } if err != nil { log.Error().Err(err).Msg("") continue } } d, err := email.Dial(em) if err != nil { log.Fatal().Err(err).Msg("") } m, err := email.Envelope(em) if err != nil { log.Fatal().Err(err).Msg("") } m.SetHeader("Subject", em.GetString("_subject")) m.SetBodyWriter("text/plain", func(w io.Writer) error { return tt.Execute(w, tmplData) }) if inlineCSS { var body strings.Builder err = ht.Execute(&body, tmplData) if err != nil { return } var inlined string inlined, err = inliner.Inline(body.String()) if err != nil { return } m.AddAlternative("text/html", inlined) } else { m.AddAlternativeWriter("text/html", func(w io.Writer) error { return ht.Execute(w, tmplData) }) } for name, path := range cf.GetStringMapString("images") { if _, err := os.Stat(path); err != nil { log.Error().Err(err).Msg("skipping") continue } m.Embed(path, mail.Rename(name)) } err = d.DialAndSend(m) if err != nil { log.Fatal().Err(err).Msg("") } return }, }
DV2EMAILCmd represents the base command when called without any subcommands
Functions ¶
Types ¶
This section is empty.
Click to show internal directories.
Click to hide internal directories.