github.com/jiasir/docker@v1.3.3-0.20170609024000-252e610103e7/api/server/router/swarm/cluster_routes.go (about) 1 package swarm 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "net/http" 7 "strconv" 8 9 "github.com/Sirupsen/logrus" 10 "github.com/docker/docker/api/errors" 11 "github.com/docker/docker/api/server/httputils" 12 basictypes "github.com/docker/docker/api/types" 13 "github.com/docker/docker/api/types/backend" 14 "github.com/docker/docker/api/types/filters" 15 types "github.com/docker/docker/api/types/swarm" 16 "github.com/docker/docker/api/types/versions" 17 "golang.org/x/net/context" 18 ) 19 20 func (sr *swarmRouter) initCluster(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { 21 var req types.InitRequest 22 if err := json.NewDecoder(r.Body).Decode(&req); err != nil { 23 return err 24 } 25 nodeID, err := sr.backend.Init(req) 26 if err != nil { 27 logrus.Errorf("Error initializing swarm: %v", err) 28 return err 29 } 30 return httputils.WriteJSON(w, http.StatusOK, nodeID) 31 } 32 33 func (sr *swarmRouter) joinCluster(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { 34 var req types.JoinRequest 35 if err := json.NewDecoder(r.Body).Decode(&req); err != nil { 36 return err 37 } 38 return sr.backend.Join(req) 39 } 40 41 func (sr *swarmRouter) leaveCluster(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { 42 if err := httputils.ParseForm(r); err != nil { 43 return err 44 } 45 46 force := httputils.BoolValue(r, "force") 47 return sr.backend.Leave(force) 48 } 49 50 func (sr *swarmRouter) inspectCluster(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { 51 swarm, err := sr.backend.Inspect() 52 if err != nil { 53 logrus.Errorf("Error getting swarm: %v", err) 54 return err 55 } 56 57 return httputils.WriteJSON(w, http.StatusOK, swarm) 58 } 59 60 func (sr *swarmRouter) updateCluster(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { 61 var swarm types.Spec 62 if err := json.NewDecoder(r.Body).Decode(&swarm); err != nil { 63 return err 64 } 65 66 rawVersion := r.URL.Query().Get("version") 67 version, err := strconv.ParseUint(rawVersion, 10, 64) 68 if err != nil { 69 err := fmt.Errorf("invalid swarm version '%s': %v", rawVersion, err) 70 return errors.NewBadRequestError(err) 71 } 72 73 var flags types.UpdateFlags 74 75 if value := r.URL.Query().Get("rotateWorkerToken"); value != "" { 76 rot, err := strconv.ParseBool(value) 77 if err != nil { 78 err := fmt.Errorf("invalid value for rotateWorkerToken: %s", value) 79 return errors.NewBadRequestError(err) 80 } 81 82 flags.RotateWorkerToken = rot 83 } 84 85 if value := r.URL.Query().Get("rotateManagerToken"); value != "" { 86 rot, err := strconv.ParseBool(value) 87 if err != nil { 88 err := fmt.Errorf("invalid value for rotateManagerToken: %s", value) 89 return errors.NewBadRequestError(err) 90 } 91 92 flags.RotateManagerToken = rot 93 } 94 95 if value := r.URL.Query().Get("rotateManagerUnlockKey"); value != "" { 96 rot, err := strconv.ParseBool(value) 97 if err != nil { 98 return errors.NewBadRequestError(fmt.Errorf("invalid value for rotateManagerUnlockKey: %s", value)) 99 } 100 101 flags.RotateManagerUnlockKey = rot 102 } 103 104 if err := sr.backend.Update(version, swarm, flags); err != nil { 105 logrus.Errorf("Error configuring swarm: %v", err) 106 return err 107 } 108 return nil 109 } 110 111 func (sr *swarmRouter) unlockCluster(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { 112 var req types.UnlockRequest 113 if err := json.NewDecoder(r.Body).Decode(&req); err != nil { 114 return err 115 } 116 117 if err := sr.backend.UnlockSwarm(req); err != nil { 118 logrus.Errorf("Error unlocking swarm: %v", err) 119 return err 120 } 121 return nil 122 } 123 124 func (sr *swarmRouter) getUnlockKey(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { 125 unlockKey, err := sr.backend.GetUnlockKey() 126 if err != nil { 127 logrus.WithError(err).Errorf("Error retrieving swarm unlock key") 128 return err 129 } 130 131 return httputils.WriteJSON(w, http.StatusOK, &basictypes.SwarmUnlockKeyResponse{ 132 UnlockKey: unlockKey, 133 }) 134 } 135 136 func (sr *swarmRouter) getServices(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { 137 if err := httputils.ParseForm(r); err != nil { 138 return err 139 } 140 filter, err := filters.FromParam(r.Form.Get("filters")) 141 if err != nil { 142 return err 143 } 144 145 services, err := sr.backend.GetServices(basictypes.ServiceListOptions{Filters: filter}) 146 if err != nil { 147 logrus.Errorf("Error getting services: %v", err) 148 return err 149 } 150 151 return httputils.WriteJSON(w, http.StatusOK, services) 152 } 153 154 func (sr *swarmRouter) getService(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { 155 var insertDefaults bool 156 if value := r.URL.Query().Get("insertDefaults"); value != "" { 157 var err error 158 insertDefaults, err = strconv.ParseBool(value) 159 if err != nil { 160 err := fmt.Errorf("invalid value for insertDefaults: %s", value) 161 return errors.NewBadRequestError(err) 162 } 163 } 164 165 service, err := sr.backend.GetService(vars["id"], insertDefaults) 166 if err != nil { 167 logrus.Errorf("Error getting service %s: %v", vars["id"], err) 168 return err 169 } 170 171 return httputils.WriteJSON(w, http.StatusOK, service) 172 } 173 174 func (sr *swarmRouter) createService(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { 175 var service types.ServiceSpec 176 if err := json.NewDecoder(r.Body).Decode(&service); err != nil { 177 return err 178 } 179 180 // Get returns "" if the header does not exist 181 encodedAuth := r.Header.Get("X-Registry-Auth") 182 cliVersion := r.Header.Get("version") 183 queryRegistry := false 184 if cliVersion != "" && versions.LessThan(cliVersion, "1.30") { 185 queryRegistry = true 186 } 187 188 resp, err := sr.backend.CreateService(service, encodedAuth, queryRegistry) 189 if err != nil { 190 logrus.Errorf("Error creating service %s: %v", service.Name, err) 191 return err 192 } 193 194 return httputils.WriteJSON(w, http.StatusCreated, resp) 195 } 196 197 func (sr *swarmRouter) updateService(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { 198 var service types.ServiceSpec 199 if err := json.NewDecoder(r.Body).Decode(&service); err != nil { 200 return err 201 } 202 203 rawVersion := r.URL.Query().Get("version") 204 version, err := strconv.ParseUint(rawVersion, 10, 64) 205 if err != nil { 206 err := fmt.Errorf("invalid service version '%s': %v", rawVersion, err) 207 return errors.NewBadRequestError(err) 208 } 209 210 var flags basictypes.ServiceUpdateOptions 211 212 // Get returns "" if the header does not exist 213 flags.EncodedRegistryAuth = r.Header.Get("X-Registry-Auth") 214 flags.RegistryAuthFrom = r.URL.Query().Get("registryAuthFrom") 215 flags.Rollback = r.URL.Query().Get("rollback") 216 cliVersion := r.Header.Get("version") 217 queryRegistry := false 218 if cliVersion != "" && versions.LessThan(cliVersion, "1.30") { 219 queryRegistry = true 220 } 221 222 resp, err := sr.backend.UpdateService(vars["id"], version, service, flags, queryRegistry) 223 if err != nil { 224 logrus.Errorf("Error updating service %s: %v", vars["id"], err) 225 return err 226 } 227 return httputils.WriteJSON(w, http.StatusOK, resp) 228 } 229 230 func (sr *swarmRouter) removeService(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { 231 if err := sr.backend.RemoveService(vars["id"]); err != nil { 232 logrus.Errorf("Error removing service %s: %v", vars["id"], err) 233 return err 234 } 235 return nil 236 } 237 238 func (sr *swarmRouter) getTaskLogs(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { 239 if err := httputils.ParseForm(r); err != nil { 240 return err 241 } 242 243 // make a selector to pass to the helper function 244 selector := &backend.LogSelector{ 245 Tasks: []string{vars["id"]}, 246 } 247 return sr.swarmLogs(ctx, w, r, selector) 248 } 249 250 func (sr *swarmRouter) getServiceLogs(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { 251 if err := httputils.ParseForm(r); err != nil { 252 return err 253 } 254 255 // make a selector to pass to the helper function 256 selector := &backend.LogSelector{ 257 Services: []string{vars["id"]}, 258 } 259 return sr.swarmLogs(ctx, w, r, selector) 260 } 261 262 func (sr *swarmRouter) getNodes(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { 263 if err := httputils.ParseForm(r); err != nil { 264 return err 265 } 266 filter, err := filters.FromParam(r.Form.Get("filters")) 267 if err != nil { 268 return err 269 } 270 271 nodes, err := sr.backend.GetNodes(basictypes.NodeListOptions{Filters: filter}) 272 if err != nil { 273 logrus.Errorf("Error getting nodes: %v", err) 274 return err 275 } 276 277 return httputils.WriteJSON(w, http.StatusOK, nodes) 278 } 279 280 func (sr *swarmRouter) getNode(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { 281 node, err := sr.backend.GetNode(vars["id"]) 282 if err != nil { 283 logrus.Errorf("Error getting node %s: %v", vars["id"], err) 284 return err 285 } 286 287 return httputils.WriteJSON(w, http.StatusOK, node) 288 } 289 290 func (sr *swarmRouter) updateNode(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { 291 var node types.NodeSpec 292 if err := json.NewDecoder(r.Body).Decode(&node); err != nil { 293 return err 294 } 295 296 rawVersion := r.URL.Query().Get("version") 297 version, err := strconv.ParseUint(rawVersion, 10, 64) 298 if err != nil { 299 err := fmt.Errorf("invalid node version '%s': %v", rawVersion, err) 300 return errors.NewBadRequestError(err) 301 } 302 303 if err := sr.backend.UpdateNode(vars["id"], version, node); err != nil { 304 logrus.Errorf("Error updating node %s: %v", vars["id"], err) 305 return err 306 } 307 return nil 308 } 309 310 func (sr *swarmRouter) removeNode(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { 311 if err := httputils.ParseForm(r); err != nil { 312 return err 313 } 314 315 force := httputils.BoolValue(r, "force") 316 317 if err := sr.backend.RemoveNode(vars["id"], force); err != nil { 318 logrus.Errorf("Error removing node %s: %v", vars["id"], err) 319 return err 320 } 321 return nil 322 } 323 324 func (sr *swarmRouter) getTasks(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { 325 if err := httputils.ParseForm(r); err != nil { 326 return err 327 } 328 filter, err := filters.FromParam(r.Form.Get("filters")) 329 if err != nil { 330 return err 331 } 332 333 tasks, err := sr.backend.GetTasks(basictypes.TaskListOptions{Filters: filter}) 334 if err != nil { 335 logrus.Errorf("Error getting tasks: %v", err) 336 return err 337 } 338 339 return httputils.WriteJSON(w, http.StatusOK, tasks) 340 } 341 342 func (sr *swarmRouter) getTask(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { 343 task, err := sr.backend.GetTask(vars["id"]) 344 if err != nil { 345 logrus.Errorf("Error getting task %s: %v", vars["id"], err) 346 return err 347 } 348 349 return httputils.WriteJSON(w, http.StatusOK, task) 350 } 351 352 func (sr *swarmRouter) getSecrets(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { 353 if err := httputils.ParseForm(r); err != nil { 354 return err 355 } 356 filters, err := filters.FromParam(r.Form.Get("filters")) 357 if err != nil { 358 return err 359 } 360 361 secrets, err := sr.backend.GetSecrets(basictypes.SecretListOptions{Filters: filters}) 362 if err != nil { 363 return err 364 } 365 366 return httputils.WriteJSON(w, http.StatusOK, secrets) 367 } 368 369 func (sr *swarmRouter) createSecret(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { 370 var secret types.SecretSpec 371 if err := json.NewDecoder(r.Body).Decode(&secret); err != nil { 372 return err 373 } 374 375 id, err := sr.backend.CreateSecret(secret) 376 if err != nil { 377 return err 378 } 379 380 return httputils.WriteJSON(w, http.StatusCreated, &basictypes.SecretCreateResponse{ 381 ID: id, 382 }) 383 } 384 385 func (sr *swarmRouter) removeSecret(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { 386 if err := sr.backend.RemoveSecret(vars["id"]); err != nil { 387 return err 388 } 389 w.WriteHeader(http.StatusNoContent) 390 391 return nil 392 } 393 394 func (sr *swarmRouter) getSecret(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { 395 secret, err := sr.backend.GetSecret(vars["id"]) 396 if err != nil { 397 return err 398 } 399 400 return httputils.WriteJSON(w, http.StatusOK, secret) 401 } 402 403 func (sr *swarmRouter) updateSecret(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { 404 var secret types.SecretSpec 405 if err := json.NewDecoder(r.Body).Decode(&secret); err != nil { 406 return errors.NewBadRequestError(err) 407 } 408 409 rawVersion := r.URL.Query().Get("version") 410 version, err := strconv.ParseUint(rawVersion, 10, 64) 411 if err != nil { 412 return errors.NewBadRequestError(fmt.Errorf("invalid secret version")) 413 } 414 415 id := vars["id"] 416 if err := sr.backend.UpdateSecret(id, version, secret); err != nil { 417 return err 418 } 419 420 return nil 421 } 422 423 func (sr *swarmRouter) getConfigs(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { 424 if err := httputils.ParseForm(r); err != nil { 425 return err 426 } 427 filters, err := filters.FromParam(r.Form.Get("filters")) 428 if err != nil { 429 return err 430 } 431 432 configs, err := sr.backend.GetConfigs(basictypes.ConfigListOptions{Filters: filters}) 433 if err != nil { 434 return err 435 } 436 437 return httputils.WriteJSON(w, http.StatusOK, configs) 438 } 439 440 func (sr *swarmRouter) createConfig(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { 441 var config types.ConfigSpec 442 if err := json.NewDecoder(r.Body).Decode(&config); err != nil { 443 return err 444 } 445 446 id, err := sr.backend.CreateConfig(config) 447 if err != nil { 448 return err 449 } 450 451 return httputils.WriteJSON(w, http.StatusCreated, &basictypes.ConfigCreateResponse{ 452 ID: id, 453 }) 454 } 455 456 func (sr *swarmRouter) removeConfig(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { 457 if err := sr.backend.RemoveConfig(vars["id"]); err != nil { 458 return err 459 } 460 w.WriteHeader(http.StatusNoContent) 461 462 return nil 463 } 464 465 func (sr *swarmRouter) getConfig(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { 466 config, err := sr.backend.GetConfig(vars["id"]) 467 if err != nil { 468 return err 469 } 470 471 return httputils.WriteJSON(w, http.StatusOK, config) 472 } 473 474 func (sr *swarmRouter) updateConfig(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error { 475 var config types.ConfigSpec 476 if err := json.NewDecoder(r.Body).Decode(&config); err != nil { 477 return errors.NewBadRequestError(err) 478 } 479 480 rawVersion := r.URL.Query().Get("version") 481 version, err := strconv.ParseUint(rawVersion, 10, 64) 482 if err != nil { 483 return errors.NewBadRequestError(fmt.Errorf("invalid config version")) 484 } 485 486 id := vars["id"] 487 if err := sr.backend.UpdateConfig(id, version, config); err != nil { 488 return err 489 } 490 491 return nil 492 }