diff options
author | Gibheer <gibheer+git@zero-knowledge.org> | 2022-12-15 11:16:56 +0100 |
---|---|---|
committer | Gibheer <gibheer+git@zero-knowledge.org> | 2022-12-15 11:16:56 +0100 |
commit | e29f38937cdf077a99b45c27e49f553d4dd8d0d7 (patch) | |
tree | 38509003a153a0100cb1a69a5d7a752ad2ff7616 /cmd/monfront/create.go | |
parent | 49dac92034f352698429ee1d78d4bfb070006693 (diff) |
monfront - add basic interface to create some entities
Diffstat (limited to 'cmd/monfront/create.go')
-rw-r--r-- | cmd/monfront/create.go | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/cmd/monfront/create.go b/cmd/monfront/create.go new file mode 100644 index 0000000..43805a1 --- /dev/null +++ b/cmd/monfront/create.go @@ -0,0 +1,148 @@ +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 +} |