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  }