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