// Return all the loader entries that match the targeting string for manifest mid func (db *DB) AllLoadersFromManifestID(mid float64) (ret []mig.LoaderEntry, err error) { var mtarg string err = db.c.QueryRow(`SELECT target FROM manifests WHERE (status='active' OR status='staged') AND id=$1`, mid).Scan(&mtarg) if err != nil { return } qs := fmt.Sprintf(`SELECT id, loadername, name, lastseen, enabled FROM loaders WHERE enabled=TRUE AND %v`, mtarg) rows, err := db.c.Query(qs) if err != nil { return } if rows != nil { defer rows.Close() } for rows.Next() { var agtname sql.NullString nle := mig.LoaderEntry{} err = rows.Scan(&nle.ID, &nle.Name, &agtname, &nle.LastSeen, &nle.Enabled) if err != nil { return ret, err } // This should always be valid, if it is not that means we have a loader // entry updated with a valid env, but a NULL agent name. In that case we // just don't set the agent name in the loader entry. if agtname.Valid { nle.AgentName = agtname.String } ret = append(ret, nle) } return }
// Prompts for input and creates a new loader entry through the API func loaderCreator(cli client.Client) (err error) { defer func() { if e := recover(); e != nil { err = fmt.Errorf("loaderCreator() -> %v", e) } }() var newle mig.LoaderEntry fmt.Println("Entering loader creation mode.\nPlease provide the name" + " of the new entry") newle.Name, err = readline.String("name> ") if err != nil { panic(err) } if len(newle.Name) < 3 { panic("input name too short") } fmt.Printf("Name: '%s'\n", newle.Name) fmt.Println("Please provide loader key for entry.") newle.Key, err = readline.String("key> ") if err != nil { panic(err) } fmt.Printf("Key: '%s'\n", newle.Key) // Validate the new loader entry before sending it to the API err = newle.Validate() if err != nil { panic(err) } jsonle, err := json.MarshalIndent(newle, "", " ") if err != nil { panic(err) } fmt.Printf("%s\n", jsonle) input, err := readline.String("create loader entry? (y/n)> ") if err != nil { panic(err) } if input != "y" { fmt.Println("abort") return } err = cli.PostNewLoader(newle) if err != nil { panic(err) } fmt.Println("New entry successfully created but is disabled") return }
// Add a new loader entry func newLoader(respWriter http.ResponseWriter, request *http.Request) { loc := fmt.Sprintf("%s%s", ctx.Server.Host, request.URL.String()) opid := getOpID(request) resource := cljs.New(loc) defer func() { if e := recover(); e != nil { ctx.Channels.Log <- mig.Log{OpID: opid, Desc: fmt.Sprintf("%v", e)}.Err() resource.SetError(cljs.Error{Code: fmt.Sprintf("%.0f", opid), Message: fmt.Sprintf("%v", e)}) respond(http.StatusInternalServerError, resource, respWriter, request) } ctx.Channels.Log <- mig.Log{OpID: opid, Desc: "leaving newLoader()"}.Debug() }() err := request.ParseForm() if err != nil { panic(err) } ctx.Channels.Log <- mig.Log{OpID: opid, Desc: fmt.Sprintf("Received new loader request")}.Debug() lestr := request.FormValue("loader") if lestr == "" { panic("no loader entry specified in form") } var le mig.LoaderEntry err = json.Unmarshal([]byte(lestr), &le) if err != nil { panic(err) } err = le.Validate() if err != nil { panic(err) } // Hash the loader key to provide it to LoaderAdd hkey, salt, err := hashLoaderKey(le.Key, nil) if err != nil { panic(err) } err = ctx.DB.LoaderAdd(le, hkey, salt) if err != nil { panic(err) } respond(http.StatusCreated, resource, respWriter, request) }
func (db *DB) SearchLoaders(p search.Parameters) (lrecords []mig.LoaderEntry, err error) { var rows *sql.Rows ids, err := makeIDsFromParams(p) columns := `loaders.id, loaders.loadername, loaders.name, loaders.lastseen, loaders.enabled` where := "" vals := []interface{}{} valctr := 0 if p.Before.Before(time.Now().Add(search.DefaultWindow - time.Hour)) { where += fmt.Sprintf(`loaders.lastseen <= $%d `, valctr+1) vals = append(vals, p.Before) valctr += 1 } if p.After.After(time.Now().Add(-(search.DefaultWindow - time.Hour))) { if valctr > 0 { where += " AND " } where += fmt.Sprintf(`loaders.lastseen >= $%d `, valctr+1) vals = append(vals, p.After) valctr += 1 } if p.LoaderName != "%" { if valctr > 0 { where += " AND " } where += fmt.Sprintf(`loaders.loadername ILIKE $%d`, valctr+1) vals = append(vals, p.LoaderName) valctr += 1 } if p.AgentName != "%" { if valctr > 0 { where += " AND " } where += fmt.Sprintf(`loaders.name ILIKE $%d`, valctr+1) vals = append(vals, p.AgentName) valctr += 1 } if p.LoaderID != "∞" { if valctr > 0 { where += " AND " } where += fmt.Sprintf(`loaders.id >= $%d AND loaders.id <= $%d`, valctr+1, valctr+2) vals = append(vals, ids.minLdrID, ids.maxLdrID) valctr += 2 } query := fmt.Sprintf(`SELECT %s FROM loaders WHERE %s ORDER BY loadername;`, columns, where) stmt, err := db.c.Prepare(query) if err != nil { err = fmt.Errorf("Error while preparing search statement: '%v' in '%s'", err, query) return } if stmt != nil { defer stmt.Close() } rows, err = stmt.Query(vals...) if err != nil { err = fmt.Errorf("Error while finding loaders: '%v'", err) } if rows != nil { defer rows.Close() } for rows.Next() { var le mig.LoaderEntry var agtnameNull sql.NullString err = rows.Scan(&le.ID, &le.Name, &agtnameNull, &le.LastSeen, &le.Enabled) if err != nil { err = fmt.Errorf("Failed to retrieve loader data: '%v'", err) return } le.AgentName = "unset" if agtnameNull.Valid { le.AgentName = agtnameNull.String } lrecords = append(lrecords, le) } if err := rows.Err(); err != nil { err = fmt.Errorf("Failed to complete database query: '%v'", err) } return }