github.com/billybanfield/evergreen@v0.0.0-20170525200750-eeee692790f7/service/distros.go (about) 1 package service 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "io/ioutil" 7 "net/http" 8 "sort" 9 10 "github.com/evergreen-ci/evergreen/model/distro" 11 "github.com/evergreen-ci/evergreen/model/event" 12 "github.com/evergreen-ci/evergreen/model/host" 13 "github.com/evergreen-ci/evergreen/model/user" 14 "github.com/evergreen-ci/evergreen/util" 15 "github.com/evergreen-ci/evergreen/validator" 16 "github.com/gorilla/mux" 17 ) 18 19 func (uis *UIServer) distrosPage(w http.ResponseWriter, r *http.Request) { 20 projCtx := MustHaveProjectContext(r) 21 distros, err := distro.Find(distro.All) 22 23 if err != nil { 24 message := fmt.Sprintf("error fetching distros: %v", err) 25 PushFlash(uis.CookieStore, r, w, NewErrorFlash(message)) 26 http.Error(w, message, http.StatusInternalServerError) 27 return 28 } 29 30 sort.Sort(&sortableDistro{distros}) 31 32 uis.WriteHTML(w, http.StatusOK, struct { 33 Distros []distro.Distro 34 Keys map[string]string 35 User *user.DBUser 36 ProjectData projectContext 37 Flashes []interface{} 38 }{distros, uis.Settings.Keys, GetUser(r), projCtx, PopFlashes(uis.CookieStore, r, w)}, 39 "base", "distros.html", "base_angular.html", "menu.html") 40 } 41 42 func (uis *UIServer) modifyDistro(w http.ResponseWriter, r *http.Request) { 43 id := mux.Vars(r)["distro_id"] 44 shouldDeco := r.FormValue("deco") == "true" 45 46 u := MustHaveUser(r) 47 48 body := util.NewRequestReader(r) 49 defer body.Close() 50 51 b, err := ioutil.ReadAll(body) 52 if err != nil { 53 message := fmt.Sprintf("error reading request: %v", err) 54 PushFlash(uis.CookieStore, r, w, NewErrorFlash(message)) 55 http.Error(w, message, http.StatusBadRequest) 56 return 57 } 58 59 oldDistro, err := distro.FindOne(distro.ById(id)) 60 if err != nil { 61 message := fmt.Sprintf("error finding distro: %v", err) 62 PushFlash(uis.CookieStore, r, w, NewErrorFlash(message)) 63 http.Error(w, message, http.StatusInternalServerError) 64 return 65 } 66 67 newDistro := *oldDistro 68 69 // attempt to unmarshal data into distros field for type validation 70 if err = json.Unmarshal(b, &newDistro); err != nil { 71 message := fmt.Sprintf("error unmarshaling request: %v", err) 72 PushFlash(uis.CookieStore, r, w, NewErrorFlash(message)) 73 http.Error(w, message, http.StatusBadRequest) 74 return 75 } 76 77 // check that the resulting distro is valid 78 vErrs, err := validator.CheckDistro(&newDistro, &uis.Settings, false) 79 if err != nil { 80 message := fmt.Sprintf("error retrieving distroIds: %v", err) 81 PushFlash(uis.CookieStore, r, w, NewErrorFlash(message)) 82 http.Error(w, message, http.StatusInternalServerError) 83 return 84 } 85 86 if len(vErrs) != 0 { 87 for _, e := range vErrs { 88 PushFlash(uis.CookieStore, r, w, NewErrorFlash(e.Error())) 89 } 90 uis.WriteJSON(w, http.StatusBadRequest, vErrs) 91 return 92 } 93 94 if err = newDistro.Update(); err != nil { 95 message := fmt.Sprintf("error updating distro: %v", err) 96 PushFlash(uis.CookieStore, r, w, NewErrorFlash(message)) 97 http.Error(w, message, http.StatusBadRequest) 98 return 99 } 100 101 if shouldDeco { 102 err = host.DecommissionHostsWithDistroId(newDistro.Id) 103 if err != nil { 104 message := fmt.Sprintf("error decommissioning hosts: %v", err) 105 PushFlash(uis.CookieStore, r, w, NewErrorFlash(message)) 106 http.Error(w, message, http.StatusBadRequest) 107 return 108 } 109 } 110 111 event.LogDistroModified(id, u.Username(), newDistro) 112 113 message := fmt.Sprintf("Distro %v successfully updated.", id) 114 if shouldDeco { 115 message = fmt.Sprintf("Distro %v successfully updated and running hosts decommissioned", id) 116 } 117 PushFlash(uis.CookieStore, r, w, NewSuccessFlash(message)) 118 uis.WriteJSON(w, http.StatusOK, "distro successfully updated") 119 } 120 121 func (uis *UIServer) removeDistro(w http.ResponseWriter, r *http.Request) { 122 id := mux.Vars(r)["distro_id"] 123 124 u := MustHaveUser(r) 125 126 d, err := distro.FindOne(distro.ById(id)) 127 if err != nil { 128 message := fmt.Sprintf("error finding distro: %v", err) 129 PushFlash(uis.CookieStore, r, w, NewErrorFlash(message)) 130 http.Error(w, message, http.StatusInternalServerError) 131 return 132 } 133 134 if err = distro.Remove(id); err != nil { 135 message := fmt.Sprintf("error removing distro '%v': %v", id, err) 136 PushFlash(uis.CookieStore, r, w, NewErrorFlash(message)) 137 http.Error(w, message, http.StatusInternalServerError) 138 return 139 } 140 141 event.LogDistroRemoved(id, u.Username(), d) 142 143 PushFlash(uis.CookieStore, r, w, NewSuccessFlash(fmt.Sprintf("Distro %v successfully removed.", id))) 144 uis.WriteJSON(w, http.StatusOK, "distro successfully removed") 145 } 146 147 func (uis *UIServer) getDistro(w http.ResponseWriter, r *http.Request) { 148 id := mux.Vars(r)["distro_id"] 149 150 d, err := distro.FindOne(distro.ById(id)) 151 if err != nil { 152 message := fmt.Sprintf("error fetching distro '%v': %v", id, err) 153 PushFlash(uis.CookieStore, r, w, NewErrorFlash(message)) 154 http.Error(w, message, http.StatusInternalServerError) 155 return 156 } 157 158 uis.WriteJSON(w, http.StatusOK, d) 159 } 160 161 func (uis *UIServer) addDistro(w http.ResponseWriter, r *http.Request) { 162 id, hasId := mux.Vars(r)["distro_id"] 163 164 u := MustHaveUser(r) 165 166 body := util.NewRequestReader(r) 167 defer body.Close() 168 169 b, err := ioutil.ReadAll(body) 170 if err != nil { 171 message := fmt.Sprintf("error adding distro: %v", err) 172 PushFlash(uis.CookieStore, r, w, NewErrorFlash(message)) 173 http.Error(w, err.Error(), http.StatusBadRequest) 174 return 175 } 176 177 var d distro.Distro 178 179 if err = json.Unmarshal(b, &d); err != nil { 180 message := fmt.Sprintf("error adding distro: %v", err) 181 PushFlash(uis.CookieStore, r, w, NewErrorFlash(message)) 182 http.Error(w, message, http.StatusBadRequest) 183 return 184 } 185 186 if hasId { 187 d.Id = id 188 } 189 190 vErrs, err := validator.CheckDistro(&d, &uis.Settings, true) 191 if err != nil { 192 message := fmt.Sprintf("error retrieving distroIds: %v", err) 193 PushFlash(uis.CookieStore, r, w, NewErrorFlash(message)) 194 http.Error(w, message, http.StatusInternalServerError) 195 return 196 } 197 198 if len(vErrs) != 0 { 199 for _, e := range vErrs { 200 PushFlash(uis.CookieStore, r, w, NewErrorFlash(e.Error())) 201 } 202 uis.WriteJSON(w, http.StatusBadRequest, vErrs) 203 return 204 } 205 206 if err = d.Insert(); err != nil { 207 message := fmt.Sprintf("error inserting distro '%v': %v", d.Id, err) 208 PushFlash(uis.CookieStore, r, w, NewErrorFlash(message)) 209 uis.WriteJSON(w, http.StatusInternalServerError, err) 210 return 211 } 212 213 event.LogDistroAdded(d.Id, u.Username(), d) 214 215 PushFlash(uis.CookieStore, r, w, NewSuccessFlash(fmt.Sprintf("Distro %v successfully added.", d.Id))) 216 uis.WriteJSON(w, http.StatusOK, "distro successfully added") 217 } 218 219 type sortableDistro struct { 220 distros []distro.Distro 221 } 222 223 func (s *sortableDistro) Len() int { 224 return len(s.distros) 225 } 226 227 func (s *sortableDistro) Less(i, j int) bool { 228 return s.distros[i].Id < s.distros[j].Id 229 } 230 231 func (s *sortableDistro) Swap(i, j int) { 232 s.distros[i], s.distros[j] = s.distros[j], s.distros[i] 233 }