api/cluster.go
func createCluster(w http.ResponseWriter, r *http.Request, t auth.Token) (err error) {
	allowed := permission.Check(t, permission.PermClusterCreate)
	if !allowed {
		return permission.ErrUnauthorized
	}
	var provCluster provTypes.Cluster
	err = ParseInput(r, &provCluster)
	if err != nil {
		return err
	}
	evt, err := event.New(&event.Opts{
		Target:     event.Target{Type: event.TargetTypeCluster, Value: provCluster.Name},
		Kind:       permission.PermClusterCreate,
		Owner:      t,
		CustomData: event.FormToCustomData(InputFields(r)),
		Allowed:    event.Allowed(permission.PermClusterReadEvents),
	})
	if err != nil {
		return err
	}
	defer func() { evt.Done(err) }()
	_, err = servicemanager.Cluster.FindByName(provCluster.Name)
	if err == nil {
		return &tsuruErrors.HTTP{
			Code:    http.StatusConflict,
			Message: "cluster already exists",
		}
	}
	for _, poolName := range provCluster.Pools {
		_, err = pool.GetPoolByName(poolName)
		if err != nil {
			if err == pool.ErrPoolNotFound {
				return &tsuruErrors.HTTP{
					Code:    http.StatusNotFound,
					Message: err.Error(),
				}
			}
			return err
		}
	}
	streamResponse := strings.HasPrefix(r.Header.Get("Accept"), "application/x-json-stream")
	if streamResponse {
		w.Header().Set("Content-Type", "application/x-json-stream")
		keepAliveWriter := tsuruIo.NewKeepAliveWriter(w, 30*time.Second, "")
		defer keepAliveWriter.Stop()
		writer := &tsuruIo.SimpleJsonMessageEncoderWriter{Encoder: json.NewEncoder(keepAliveWriter)}
		evt.SetLogWriter(writer)
	}
	provCluster.Writer = evt
	err = servicemanager.Cluster.Create(provCluster)
	if err != nil {
		return errors.WithStack(err)
	}
	return nil
}
func createCluster(w http.ResponseWriter, r *http.Request, t auth.Token) (err error) {
	allowed := permission.Check(t, permission.PermClusterCreate)
	if !allowed {
		return permission.ErrUnauthorized
	}
	var provCluster provTypes.Cluster
	err = ParseInput(r, &provCluster)
	if err != nil {
		return err
	}
	evt, err := event.New(&event.Opts{
		Target:     event.Target{Type: event.TargetTypeCluster, Value: provCluster.Name},
		Kind:       permission.PermClusterCreate,
		Owner:      t,
		CustomData: event.FormToCustomData(InputFields(r)),
		Allowed:    event.Allowed(permission.PermClusterReadEvents),
	})
	if err != nil {
		return err
	}
	defer func() { evt.Done(err) }()
	_, err = servicemanager.Cluster.FindByName(provCluster.Name)
	if err == nil {
		return &tsuruErrors.HTTP{
			Code:    http.StatusConflict,
			Message: "cluster already exists",
		}
	}
	for _, poolName := range provCluster.Pools {
		_, err = pool.GetPoolByName(poolName)
		if err != nil {
			if err == pool.ErrPoolNotFound {
				return &tsuruErrors.HTTP{
					Code:    http.StatusNotFound,
					Message: err.Error(),
				}
			}
			return err
		}
	}
	streamResponse := strings.HasPrefix(r.Header.Get("Accept"), "application/x-json-stream")
	if streamResponse {
		w.Header().Set("Content-Type", "application/x-json-stream")
		keepAliveWriter := tsuruIo.NewKeepAliveWriter(w, 30*time.Second, "")
		defer keepAliveWriter.Stop()
		writer := &tsuruIo.SimpleJsonMessageEncoderWriter{Encoder: json.NewEncoder(keepAliveWriter)}
		evt.SetLogWriter(writer)
	}
	provCluster.Writer = evt
	err = servicemanager.Cluster.Create(provCluster)
	if err != nil {
		return errors.WithStack(err)
	}
	return nil
}
// title: create provisioner cluster
// path: /provisioner/clusters
// method: POST
// consume: application/x-www-form-urlencoded
// produce: application/x-json-stream
// responses:
//   200: Ok
//   400: Invalid data
//   401: Unauthorized
//   404: Pool does not exist
//   409: Cluster already exists