зеркало из https://github.com/mozilla/mig.git
[medium] add console loader management operations
This commit is contained in:
Родитель
f1ff92681c
Коммит
461163a032
106
client/client.go
106
client/client.go
|
@ -541,6 +541,112 @@ func (cli Client) PostManifestSignature(mr mig.ManifestRecord, sig string) (err
|
|||
return
|
||||
}
|
||||
|
||||
// GetLoaderEntry retrieves a MIG loader entry from the API using the record ID
|
||||
func (cli Client) GetLoaderEntry(lid float64) (le mig.LoaderEntry, err error) {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
err = fmt.Errorf("GetLoaderEntry() -> %v", e)
|
||||
}
|
||||
}()
|
||||
target := fmt.Sprintf("loader?loaderid=%.0f", lid)
|
||||
resource, err := cli.GetAPIResource(target)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if resource.Collection.Items[0].Data[0].Name != "loader" {
|
||||
panic("API returned something that is not a loader... something's wrong.")
|
||||
}
|
||||
le, err = ValueToLoaderEntry(resource.Collection.Items[0].Data[0].Value)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Change the status of an existing loader entry
|
||||
func (cli Client) LoaderEntryStatus(le mig.LoaderEntry, status bool) (err error) {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
err = fmt.Errorf("LoaderEntryStatus() -> %v", e)
|
||||
}
|
||||
}()
|
||||
statusval := "disabled"
|
||||
if status {
|
||||
statusval = "enabled"
|
||||
}
|
||||
data := url.Values{"loaderid": {fmt.Sprintf("%.0f", le.ID)}, "status": {statusval}}
|
||||
r, err := http.NewRequest("POST", cli.Conf.API.URL+"loader/status/",
|
||||
strings.NewReader(data.Encode()))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
r.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
resp, err := cli.Do(r)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
var resource *cljs.Resource
|
||||
if len(body) > 1 {
|
||||
err = json.Unmarshal(body, &resource)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
err = fmt.Errorf("error: HTTP %d. Status update failed with error '%v' (code %s).",
|
||||
resp.StatusCode, resource.Collection.Error.Message, resource.Collection.Error.Code)
|
||||
panic(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Post a new loader entry for storage through the API
|
||||
func (cli Client) PostNewLoader(le mig.LoaderEntry) (err error) {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
err = fmt.Errorf("PostNewLoader() -> %v", e)
|
||||
}
|
||||
}()
|
||||
lebuf, err := json.Marshal(le)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
data := url.Values{"loader": {string(lebuf)}}
|
||||
r, err := http.NewRequest("POST", cli.Conf.API.URL+"loader/new/",
|
||||
strings.NewReader(data.Encode()))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
r.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
resp, err := cli.Do(r)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
var resource *cljs.Resource
|
||||
if len(body) > 1 {
|
||||
err = json.Unmarshal(body, &resource)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
if resp.StatusCode != http.StatusCreated {
|
||||
err = fmt.Errorf("error: HTTP %d. Loader create failed with error '%v' (code %s).",
|
||||
resp.StatusCode, resource.Collection.Error.Message, resource.Collection.Error.Code)
|
||||
panic(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// PostAction submits a MIG Action to the API and returns the reflected action with API ID
|
||||
func (cli Client) PostAction(a mig.Action) (a2 mig.Action, err error) {
|
||||
defer func() {
|
||||
|
|
|
@ -131,6 +131,8 @@ func main() {
|
|||
err = actionLauncher(a, cli)
|
||||
case "investigator":
|
||||
err = investigatorCreator(cli)
|
||||
case "loader":
|
||||
err = loaderCreator(cli)
|
||||
case "manifest":
|
||||
err = manifestCreator(cli)
|
||||
default:
|
||||
|
@ -156,6 +158,7 @@ action <id> enter interactive action reader mode for action <id>
|
|||
agent <id> enter interactive agent reader mode for agent <id>
|
||||
create action create a new action
|
||||
create investigator create a new investigator, will prompt for name and public key
|
||||
create loader create a new loader entry
|
||||
create manifest create a new manifest
|
||||
command <id> enter command reader mode for command <id>
|
||||
exit leave
|
||||
|
@ -185,6 +188,11 @@ status display platform status: connected agents, latest actions, ...
|
|||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
case "loader":
|
||||
err = loaderReader(input, cli)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
case "manifest":
|
||||
err = manifestReader(input, cli)
|
||||
if err != nil {
|
||||
|
|
|
@ -0,0 +1,173 @@
|
|||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
//
|
||||
// Contributor: Aaron Meihm ameihm@mozilla.com [:alm]
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/bobappleyard/readline"
|
||||
"mig.ninja/mig"
|
||||
"mig.ninja/mig/client"
|
||||
)
|
||||
|
||||
// loaderReader is used to manipulate loader entries
|
||||
func loaderReader(input string, cli client.Client) (err error) {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
err = fmt.Errorf("loaderReader() -> %v", e)
|
||||
}
|
||||
}()
|
||||
inputArr := strings.Split(input, " ")
|
||||
if len(inputArr) != 2 {
|
||||
panic("wrong order format. must be 'loader <loaderid>'")
|
||||
}
|
||||
lid, err := strconv.ParseFloat(inputArr[1], 64)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
le, err := cli.GetLoaderEntry(lid)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
fmt.Println("Entering loader reader mode. Type \x1b[32;1mexit\x1b[0m or press \x1b[32;1mctrl+d\x1b[0m to leave. \x1b[32;1mhelp\x1b[0m may help.")
|
||||
fmt.Printf("Loader: '%v'.\nStatus '%v'.\n", le.Name, le.Enabled)
|
||||
|
||||
prompt := fmt.Sprintf("\x1b[31;1mloader %v>\x1b[0m ", uint64(lid)%1000)
|
||||
for {
|
||||
reloadfunc := func() {
|
||||
le, err = cli.GetLoaderEntry(lid)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Println("reloaded")
|
||||
}
|
||||
var symbols = []string{"disable", "enable", "exit", "help", "json", "r"}
|
||||
readline.Completer = func(query, ctx string) []string {
|
||||
var res []string
|
||||
for _, sym := range symbols {
|
||||
if strings.HasPrefix(sym, query) {
|
||||
res = append(res, sym)
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
input, err := readline.String(prompt)
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
fmt.Println("error: ", err)
|
||||
break
|
||||
}
|
||||
orders := strings.Split(strings.TrimSpace(input), " ")
|
||||
switch orders[0] {
|
||||
case "disable":
|
||||
err = cli.LoaderEntryStatus(le, false)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Println("Loader has been disabled")
|
||||
reloadfunc()
|
||||
case "enable":
|
||||
err = cli.LoaderEntryStatus(le, true)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Println("Loader has been enabled")
|
||||
reloadfunc()
|
||||
case "help":
|
||||
fmt.Printf(`The following orders are avialable:
|
||||
disable disable loader entry
|
||||
|
||||
enable enable loader entry
|
||||
|
||||
help show this help
|
||||
|
||||
exit exit this mode (also works with ctrl+d)
|
||||
|
||||
json show json of loader entry stored in database
|
||||
|
||||
r refresh the loader entry (get latest version from database)
|
||||
`)
|
||||
case "exit":
|
||||
fmt.Printf("exit\n")
|
||||
goto exit
|
||||
case "json":
|
||||
jsonle, err := json.MarshalIndent(le, "", " ")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Printf("%v\n", string(jsonle))
|
||||
case "r":
|
||||
reloadfunc()
|
||||
case "":
|
||||
break
|
||||
default:
|
||||
fmt.Printf("Unknown order '%s'. You are in loader reader mode. Try `help`.\n", orders[0])
|
||||
}
|
||||
readline.AddHistory(input)
|
||||
}
|
||||
|
||||
exit:
|
||||
fmt.Printf("\n")
|
||||
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
|
||||
}
|
|
@ -7,6 +7,7 @@
|
|||
package database /* import "mig.ninja/mig/database" */
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
_ "github.com/lib/pq"
|
||||
|
@ -18,7 +19,8 @@ func (db *DB) GetLoaderEntryID(key string) (ret float64, err error) {
|
|||
if key == "" {
|
||||
return ret, fmt.Errorf("key cannot be empty")
|
||||
}
|
||||
err = db.c.QueryRow("SELECT id FROM loaders WHERE loaderkey=$1", key).Scan(&ret)
|
||||
err = db.c.QueryRow(`SELECT id FROM loaders WHERE
|
||||
loaderkey=$1 AND enabled=TRUE`, key).Scan(&ret)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("No matching loader entry found for key")
|
||||
return
|
||||
|
@ -28,7 +30,8 @@ func (db *DB) GetLoaderEntryID(key string) (ret float64, err error) {
|
|||
|
||||
// Return a loader name given an ID
|
||||
func (db *DB) GetLoaderName(id float64) (ret string, err error) {
|
||||
err = db.c.QueryRow("SELECT loadername FROM loaders WHERE id=$1", id).Scan(&ret)
|
||||
err = db.c.QueryRow(`SELECT loadername FROM loaders
|
||||
WHERE id=$1 AND enabled=TRUE`, id).Scan(&ret)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("Unable to locate name for loader ID")
|
||||
return
|
||||
|
@ -105,7 +108,8 @@ func (db *DB) AllLoadersFromManifestID(mid float64) (ret []mig.LoaderEntry, err
|
|||
if err != nil {
|
||||
return
|
||||
}
|
||||
qs := fmt.Sprintf("SELECT id, loadername, name, lastused FROM loaders WHERE %v", mtarg)
|
||||
qs := fmt.Sprintf(`SELECT id, loadername, name, lastused, enabled
|
||||
FROM loaders WHERE enabled=TRUE AND %v`, mtarg)
|
||||
rows, err := db.c.Query(qs)
|
||||
if err != nil {
|
||||
return
|
||||
|
@ -114,12 +118,53 @@ func (db *DB) AllLoadersFromManifestID(mid float64) (ret []mig.LoaderEntry, err
|
|||
defer rows.Close()
|
||||
}
|
||||
for rows.Next() {
|
||||
var agtname sql.NullString
|
||||
nle := mig.LoaderEntry{}
|
||||
err = rows.Scan(&nle.ID, &nle.Name, &nle.AgentName, &nle.LastUsed)
|
||||
err = rows.Scan(&nle.ID, &nle.Name, &agtname, &nle.LastUsed, &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
|
||||
}
|
||||
|
||||
// Return a loader entry given an ID
|
||||
func (db *DB) GetLoaderFromID(lid float64) (ret mig.LoaderEntry, err error) {
|
||||
var name sql.NullString
|
||||
err = db.c.QueryRow(`SELECT id, loadername, name, lastused, enabled
|
||||
FROM loaders WHERE id=$1`, lid).Scan(&ret.ID, &ret.Name, &name,
|
||||
&ret.LastUsed, &ret.Enabled)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("Error while retrieving loader: '%v'", err)
|
||||
return
|
||||
}
|
||||
if name.Valid {
|
||||
ret.AgentName = name.String
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Enable or disable a loader entry in the database
|
||||
func (db *DB) LoaderUpdateStatus(lid float64, status bool) (err error) {
|
||||
_, err = db.c.Exec(`UPDATE loaders SET enabled=$1 WHERE
|
||||
id=$2`, status, lid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Add a new loader entry to the database
|
||||
func (db *DB) LoaderAdd(le mig.LoaderEntry) (err error) {
|
||||
_, err = db.c.Exec(`INSERT INTO loaders VALUES
|
||||
(DEFAULT, $1, $2, NULL, NULL, NULL, now(), FALSE)`, le.Name,
|
||||
le.Key)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -137,7 +137,8 @@ CREATE TABLE loaders (
|
|||
name character varying(2048),
|
||||
env json,
|
||||
tags json,
|
||||
lastused timestamp with time zone NOT NULL
|
||||
lastused timestamp with time zone NOT NULL,
|
||||
enabled boolean NOT NULL DEFAULT false
|
||||
);
|
||||
ALTER TABLE ONLY loaders
|
||||
ADD CONSTRAINT loaders_pkey PRIMARY KEY (id);
|
||||
|
@ -199,11 +200,11 @@ GRANT USAGE ON SEQUENCE investigators_id_seq TO migscheduler;
|
|||
-- API has limited permissions, and cannot list scheduler private keys in the investigators table, but can update their statuses
|
||||
GRANT SELECT ON actions, agents, agents_stats, agtmodreq, commands, invagtmodperm, loaders, manifests, manifestsig, modules, signatures TO migapi;
|
||||
GRANT SELECT (id, name, pgpfingerprint, publickey, status, createdat, lastmodified, isadmin) ON investigators TO migapi;
|
||||
GRANT INSERT ON actions, signatures, manifests, manifestsig TO migapi;
|
||||
GRANT INSERT ON actions, signatures, manifests, manifestsig, loaders TO migapi;
|
||||
GRANT DELETE ON manifestsig TO migapi;
|
||||
GRANT INSERT (name, pgpfingerprint, publickey, status, createdat, lastmodified) ON investigators TO migapi;
|
||||
GRANT UPDATE (status, lastmodified) ON investigators TO migapi;
|
||||
GRANT UPDATE (name, env, tags, lastused) ON loaders TO migapi;
|
||||
GRANT UPDATE (name, env, tags, lastused, enabled) ON loaders TO migapi;
|
||||
GRANT UPDATE (status) ON manifests TO migapi;
|
||||
GRANT USAGE ON SEQUENCE investigators_id_seq TO migapi;
|
||||
GRANT USAGE ON SEQUENCE loaders_id_seq TO migapi;
|
||||
|
|
|
@ -14,6 +14,12 @@ import (
|
|||
type LoaderEntry struct {
|
||||
ID float64 // Loader ID
|
||||
Name string // Loader name
|
||||
Key string // Loader key (only populated during creation)
|
||||
AgentName string // Loader environment, agent name
|
||||
LastUsed time.Time // Last time loader was used
|
||||
Enabled bool // Loader entry is active
|
||||
}
|
||||
|
||||
func (le *LoaderEntry) Validate() error {
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -77,6 +77,9 @@ func main() {
|
|||
s.HandleFunc("/manifest/fetch/", authenticateLoader(getManifestFile)).Methods("POST")
|
||||
// all other resources require authentication
|
||||
s.HandleFunc("/", authenticate(getHome, false)).Methods("GET")
|
||||
s.HandleFunc("/loader", authenticate(getLoader, true)).Methods("GET")
|
||||
s.HandleFunc("/loader/status/", authenticate(statusLoader, true)).Methods("POST")
|
||||
s.HandleFunc("/loader/new/", authenticate(newLoader, true)).Methods("POST")
|
||||
s.HandleFunc("/manifest", authenticate(getManifest, true)).Methods("GET")
|
||||
s.HandleFunc("/manifest/sign/", authenticate(signManifest, true)).Methods("POST")
|
||||
s.HandleFunc("/manifest/status/", authenticate(statusManifest, true)).Methods("POST")
|
||||
|
|
|
@ -274,7 +274,7 @@ func manifestLoaders(respWriter http.ResponseWriter, request *http.Request) {
|
|||
return
|
||||
}
|
||||
for _, ldr := range ldrs {
|
||||
item, err := loaderEntryToItem(ldr, mid, ctx)
|
||||
item, err := loaderEntryToItem(ldr, ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
@ -420,6 +420,135 @@ func getAgentManifest(respWriter http.ResponseWriter, request *http.Request) {
|
|||
respond(200, resource, respWriter, request)
|
||||
}
|
||||
|
||||
// Return information describing an existing loader entry
|
||||
func getLoader(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(500, resource, respWriter, request)
|
||||
}
|
||||
ctx.Channels.Log <- mig.Log{OpID: opid, Desc: "leaving getLoader()"}.Debug()
|
||||
}()
|
||||
lid, err := strconv.ParseFloat(request.URL.Query()["loaderid"][0], 64)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("Wrong parameters 'loaderid': '%v'", err)
|
||||
panic(err)
|
||||
}
|
||||
|
||||
var le mig.LoaderEntry
|
||||
if lid > 0 {
|
||||
le, err = ctx.DB.GetLoaderFromID(lid)
|
||||
if err != nil {
|
||||
if fmt.Sprintf("%v", err) == "Error while retrieving loader: 'sql: no rows in result set'" {
|
||||
resource.SetError(cljs.Error{
|
||||
Code: fmt.Sprintf("%.0f", opid),
|
||||
Message: fmt.Sprintf("Loader ID '%.0f' not found", lid)})
|
||||
respond(404, resource, respWriter, request)
|
||||
return
|
||||
} else {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// bad request, return 400
|
||||
resource.SetError(cljs.Error{
|
||||
Code: fmt.Sprintf("%.0f", opid),
|
||||
Message: fmt.Sprintf("Invalid Loader ID '%.0f'", lid)})
|
||||
respond(400, resource, respWriter, request)
|
||||
return
|
||||
}
|
||||
li, err := loaderEntryToItem(le, ctx)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
resource.AddItem(li)
|
||||
respond(200, resource, respWriter, request)
|
||||
}
|
||||
|
||||
// Enable or disable a loader entry
|
||||
func statusLoader(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(500, resource, respWriter, request)
|
||||
}
|
||||
ctx.Channels.Log <- mig.Log{OpID: opid, Desc: "leaving statusLoader()"}.Debug()
|
||||
}()
|
||||
|
||||
err := request.ParseForm()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
ctx.Channels.Log <- mig.Log{OpID: opid, Desc: fmt.Sprintf("Received loader status change request")}.Debug()
|
||||
|
||||
loaderid, err := strconv.ParseFloat(request.FormValue("loaderid"), 64)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
sts := request.FormValue("status")
|
||||
var setval bool
|
||||
if sts == "enabled" {
|
||||
setval = true
|
||||
}
|
||||
err = ctx.DB.LoaderUpdateStatus(loaderid, setval)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
respond(200, resource, respWriter, request)
|
||||
}
|
||||
|
||||
// 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(500, 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)
|
||||
}
|
||||
err = ctx.DB.LoaderAdd(le)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
respond(http.StatusCreated, resource, respWriter, request)
|
||||
}
|
||||
|
||||
func manifestRecordToItem(mr mig.ManifestRecord, ctx Context) (item cljs.Item, err error) {
|
||||
item.Href = fmt.Sprintf("%s/manifest?manifestid=%.0f", ctx.Server.BaseURL, mr.ID)
|
||||
item.Data = []cljs.Data{
|
||||
|
@ -428,9 +557,8 @@ func manifestRecordToItem(mr mig.ManifestRecord, ctx Context) (item cljs.Item, e
|
|||
return
|
||||
}
|
||||
|
||||
func loaderEntryToItem(ldr mig.LoaderEntry, mid float64, ctx Context) (item cljs.Item, err error) {
|
||||
// XXX This Href doesn't properly represent the item and needs to be fixed
|
||||
item.Href = fmt.Sprintf("%s/manifest/loaders?manifestid=%.0f", ctx.Server.BaseURL, mid)
|
||||
func loaderEntryToItem(ldr mig.LoaderEntry, ctx Context) (item cljs.Item, err error) {
|
||||
item.Href = fmt.Sprintf("%s/loader?loaderid=%.0f", ctx.Server.BaseURL, ldr.ID)
|
||||
item.Data = []cljs.Data{
|
||||
{Name: "loader", Value: ldr},
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче