blob: c2e78bacf977158168c8b3e614174160b1f1190e [file] [log] [blame]
David K. Bainbridgef0da8732016-06-01 16:15:37 -07001package main
2
3import (
4 "bufio"
5 "encoding/json"
6 "github.com/gorilla/mux"
David K. Bainbridge97ee8052016-06-14 00:52:07 -07007 "log"
David K. Bainbridgef0da8732016-06-01 16:15:37 -07008 "net/http"
9 "strings"
10)
11
12type RequestInfo struct {
David K. Bainbridge97ee8052016-06-14 00:52:07 -070013 Id string `json:"id"`
14 Name string `json:"name"`
15 Ip string `json:"ip"`
16 Mac string `json:"mac"`
17 RoleSelector string `json:"role_selector"`
18 Role string `json:"role"`
19 Script string `json:"script"`
David K. Bainbridgef0da8732016-06-01 16:15:37 -070020}
21
22func (c *Context) GetRole(info *RequestInfo) (string, error) {
David K. Bainbridge97ee8052016-06-14 00:52:07 -070023 if info.Role != "" {
24 return info.Role, nil
25 } else if c.config.RoleSelectorURL == "" && info.RoleSelector == "" {
David K. Bainbridgef0da8732016-06-01 16:15:37 -070026 return c.config.DefaultRole, nil
27 }
David K. Bainbridge97ee8052016-06-14 00:52:07 -070028 selector := c.config.RoleSelectorURL
29 if info.RoleSelector != "" {
30 selector = info.RoleSelector
31 }
32
33 r, err := http.Get(selector)
David K. Bainbridgef0da8732016-06-01 16:15:37 -070034 if err != nil {
35 return "", err
36 }
37
38 s := bufio.NewScanner(r.Body)
39 defer r.Body.Close()
40 role := strings.TrimSpace(s.Text())
41 if role == "" {
42 return c.config.DefaultRole, nil
43 }
44 return role, nil
45}
46
47func (c *Context) validateData(info *RequestInfo) bool {
48 if strings.TrimSpace(info.Id) == "" ||
49 strings.TrimSpace(info.Name) == "" ||
50 strings.TrimSpace(info.Ip) == "" ||
51 strings.TrimSpace(info.Mac) == "" {
52 return false
53 }
54 return true
55}
56
57func (c *Context) ProvisionRequestHandler(w http.ResponseWriter, r *http.Request) {
58 var info RequestInfo
59 decoder := json.NewDecoder(r.Body)
60 defer r.Body.Close()
David K. Bainbridged86d96d2016-06-01 17:28:46 -070061 if err := decoder.Decode(&info); err != nil {
62 http.Error(w, err.Error(), http.StatusBadRequest)
63 return
64 }
David K. Bainbridge97ee8052016-06-14 00:52:07 -070065
David K. Bainbridged86d96d2016-06-01 17:28:46 -070066 if !c.validateData(&info) {
David K. Bainbridgef0da8732016-06-01 16:15:37 -070067 w.WriteHeader(http.StatusBadRequest)
68 return
69 }
70
David K. Bainbridgef0da8732016-06-01 16:15:37 -070071 role, err := c.GetRole(&info)
72 if err != nil {
73 http.Error(w, err.Error(), http.StatusInternalServerError)
74 return
75 }
David K. Bainbridge38501582016-06-01 18:15:45 -070076 err = c.dispatcher.Dispatch(&info, role, c.config.Script)
David K. Bainbridgef0da8732016-06-01 16:15:37 -070077 if err != nil {
78 http.Error(w, err.Error(), http.StatusInternalServerError)
79 return
80 }
81
82 w.WriteHeader(http.StatusAccepted)
83}
84
85func (c *Context) ListRequestsHandler(w http.ResponseWriter, r *http.Request) {
86 list, err := c.storage.List()
87 bytes, err := json.Marshal(list)
88 if err != nil {
89 http.Error(w, err.Error(), http.StatusInternalServerError)
90 return
91 }
92 w.Write(bytes)
93}
94
95func (c *Context) QueryStatusHandler(w http.ResponseWriter, r *http.Request) {
96 vars := mux.Vars(r)
97 id, ok := vars["nodeid"]
98 if !ok || strings.TrimSpace(id) == "" {
99 w.WriteHeader(http.StatusBadRequest)
100 return
101 }
102 s, err := c.storage.Get(id)
103 if err != nil {
David K. Bainbridge97ee8052016-06-14 00:52:07 -0700104 log.Printf("[warn] Error while retrieving status for '%s' from strorage : %s", id, err)
David K. Bainbridgef0da8732016-06-01 16:15:37 -0700105 http.Error(w, err.Error(), http.StatusInternalServerError)
106 return
107 }
108 if s == nil {
109 w.WriteHeader(http.StatusNotFound)
110 return
111 }
112 bytes, err := json.Marshal(s)
113 if err != nil {
David K. Bainbridge97ee8052016-06-14 00:52:07 -0700114 log.Printf("[error] Error while attempting to marshal status for '%s' from storage : %s", id, err)
David K. Bainbridgef0da8732016-06-01 16:15:37 -0700115 http.Error(w, err.Error(), http.StatusInternalServerError)
116 return
117 }
David K. Bainbridge8352c592016-06-02 12:48:37 -0700118
119 switch s.Status {
120 case Pending, Running:
121 w.WriteHeader(http.StatusAccepted)
David K. Bainbridge97ee8052016-06-14 00:52:07 -0700122 case Failed, Complete:
David K. Bainbridge8352c592016-06-02 12:48:37 -0700123 w.WriteHeader(http.StatusOK)
124 default:
125 w.WriteHeader(http.StatusInternalServerError)
126 }
127
David K. Bainbridgef0da8732016-06-01 16:15:37 -0700128 w.Write(bytes)
129}