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