149 lines
3.8 KiB
Go
149 lines
3.8 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"database/sql"
|
||
|
"fmt"
|
||
|
"log"
|
||
|
"net/http"
|
||
|
"strings"
|
||
|
)
|
||
|
|
||
|
func showCreate(con *Context) {
|
||
|
if con.r.Method == "POST" {
|
||
|
addCreate(con)
|
||
|
return
|
||
|
}
|
||
|
if con.r.Method != "GET" {
|
||
|
con.w.WriteHeader(http.StatusMethodNotAllowed)
|
||
|
con.w.Write([]byte("method is not supported"))
|
||
|
return
|
||
|
}
|
||
|
if !con.CanEdit {
|
||
|
con.w.WriteHeader(http.StatusForbidden)
|
||
|
con.w.Write([]byte("no permission to change data"))
|
||
|
return
|
||
|
}
|
||
|
con.Content = map[string]any{}
|
||
|
|
||
|
primitives := []struct {
|
||
|
name string
|
||
|
query string
|
||
|
}{
|
||
|
{"commands", "select id, name, updated, command, message from commands order by name"},
|
||
|
{"checkers", "select id, name, description from checkers order by name"},
|
||
|
{"notifier", "select id, name, settings from notifier order by name"},
|
||
|
{"nodes", "select id, name, updated, message from nodes order by name"},
|
||
|
}
|
||
|
for _, prim := range primitives {
|
||
|
rows, err := DB.Query(prim.query)
|
||
|
defer rows.Close()
|
||
|
if err != nil {
|
||
|
log.Printf("could not get commands: %s", err)
|
||
|
con.Error = "could not get commands"
|
||
|
returnError(http.StatusInternalServerError, con, con.w)
|
||
|
return
|
||
|
}
|
||
|
result, err := rowsToResult(rows)
|
||
|
if err != nil {
|
||
|
log.Printf("could not get %s: %s", prim.name, err)
|
||
|
con.Error = "could not get " + prim.name
|
||
|
returnError(http.StatusInternalServerError, con, con.w)
|
||
|
return
|
||
|
}
|
||
|
con.Content[prim.name] = result
|
||
|
}
|
||
|
|
||
|
con.w.Header()["Content-Type"] = []string{"text/html"}
|
||
|
con.Render("create_index")
|
||
|
return
|
||
|
}
|
||
|
|
||
|
type (
|
||
|
sqlResult struct {
|
||
|
Columns []string
|
||
|
Rows [][]sql.NullString
|
||
|
}
|
||
|
)
|
||
|
|
||
|
func rowsToResult(rows *sql.Rows) (*sqlResult, error) {
|
||
|
res := &sqlResult{}
|
||
|
cols, err := rows.Columns()
|
||
|
if err != nil {
|
||
|
return res, fmt.Errorf("could not get columns: %w", err)
|
||
|
}
|
||
|
res.Columns = cols
|
||
|
res.Rows = [][]sql.NullString{}
|
||
|
colNum := len(cols)
|
||
|
|
||
|
for rows.Next() {
|
||
|
line := make([]sql.NullString, colNum)
|
||
|
lineMap := make([]any, colNum)
|
||
|
for i := 0; i < colNum; i++ {
|
||
|
lineMap[i] = &(line[i])
|
||
|
}
|
||
|
if err := rows.Scan(lineMap...); err != nil {
|
||
|
return res, fmt.Errorf("could not scan values: %w", err)
|
||
|
}
|
||
|
res.Rows = append(res.Rows, line)
|
||
|
}
|
||
|
|
||
|
return res, nil
|
||
|
}
|
||
|
|
||
|
func addCreate(con *Context) {
|
||
|
if !con.CanEdit {
|
||
|
con.w.WriteHeader(http.StatusForbidden)
|
||
|
con.w.Write([]byte("no permission to change data"))
|
||
|
return
|
||
|
}
|
||
|
|
||
|
if err := con.r.ParseForm(); err != nil {
|
||
|
con.w.WriteHeader(http.StatusBadRequest)
|
||
|
fmt.Fprintf(con.w, "could not parse parameters: %s", err)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
con.w.Header()["Location"] = []string{"/create"}
|
||
|
|
||
|
addType := con.r.PostForm.Get("type")
|
||
|
types := map[string]struct {
|
||
|
Fields []string
|
||
|
Table string
|
||
|
}{
|
||
|
"command": {[]string{"name", "command", "message"}, "commands"},
|
||
|
"node": {[]string{"name", "message"}, "nodes"},
|
||
|
"checker": {[]string{"name", "description"}, "checkers"},
|
||
|
"notifier": {[]string{"name", "settings"}, "notifier"},
|
||
|
"check": {[]string{"name", "message", "options", "intval", "node_id", "command_id", "checker_id"}, "checks"},
|
||
|
}
|
||
|
t, found := types[addType]
|
||
|
if !found {
|
||
|
con.Error = "undefined type '" + addType + "'"
|
||
|
returnError(http.StatusBadRequest, con, con.w)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
fields := make([]any, len(t.Fields))
|
||
|
vals := make([]string, len(t.Fields))
|
||
|
for i := 0; i < len(fields); i++ {
|
||
|
vals[i] = fmt.Sprintf(`$%d`, i+1)
|
||
|
fields[i] = con.r.PostForm.Get(t.Fields[i])
|
||
|
if fields[i] == "" {
|
||
|
con.Error = "field " + t.Fields[i] + " must not be empty"
|
||
|
returnError(http.StatusBadRequest, con, con.w)
|
||
|
return
|
||
|
}
|
||
|
}
|
||
|
stmt := `insert into ` + t.Table + `(` + strings.Join(t.Fields, ",") + `) values (` + strings.Join(vals, ",") + `)`
|
||
|
_, err := DB.Exec(stmt, fields...)
|
||
|
if err != nil {
|
||
|
log.Printf("could not insert new %s: %s", addType, err)
|
||
|
con.Error = "could not insert new " + addType
|
||
|
returnError(http.StatusInternalServerError, con, con.w)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
con.w.WriteHeader(http.StatusSeeOther)
|
||
|
return
|
||
|
}
|