Ejemplo n.º 1
0
Archivo: node.go Proyecto: tsuru/tsuru
func addNodeForParams(p provision.NodeProvisioner, params provision.AddNodeOptions) (string, map[string]string, error) {
	response := make(map[string]string)
	var address string
	if params.Register {
		address, _ = params.Metadata["address"]
		delete(params.Metadata, "address")
	} else {
		desc, _ := iaas.Describe(params.Metadata["iaas"])
		response["description"] = desc
		m, err := iaas.CreateMachine(params.Metadata)
		if err != nil {
			return address, response, err
		}
		address = m.FormatNodeAddress()
		params.CaCert = m.CaCert
		params.ClientCert = m.ClientCert
		params.ClientKey = m.ClientKey
	}
	prov, _, err := provision.FindNode(address)
	if err != provision.ErrNodeNotFound {
		if err == nil {
			return "", nil, errors.Errorf("node with address %q already exists in provisioner %q", address, prov.GetName())
		}
		return "", nil, err
	}
	err = validateNodeAddress(address)
	if err != nil {
		return address, response, err
	}
	params.Address = address
	err = p.AddNode(params)
	return address, response, err
}
Ejemplo n.º 2
0
Archivo: node.go Proyecto: tsuru/tsuru
// title: list units by node
// path: /{provisioner}/node/{address}/containers
// method: GET
// produce: application/json
// responses:
//   200: Ok
//   204: No content
//   401: Unauthorized
//   404: Not found
func listUnitsByNode(w http.ResponseWriter, r *http.Request, t auth.Token) error {
	address := r.URL.Query().Get(":address")
	_, node, err := provision.FindNode(address)
	if err != nil {
		if err == provision.ErrNodeNotFound {
			return &tsuruErrors.HTTP{
				Code:    http.StatusNotFound,
				Message: err.Error(),
			}
		}
		return err
	}
	hasAccess := permission.Check(t, permission.PermNodeRead,
		permission.Context(permission.CtxPool, node.Pool()))
	if !hasAccess {
		return permission.ErrUnauthorized
	}
	units, err := node.Units()
	if err != nil {
		return err
	}
	if len(units) == 0 {
		w.WriteHeader(http.StatusNoContent)
		return nil
	}
	w.Header().Set("Content-Type", "application/json")
	return json.NewEncoder(w).Encode(units)
}
Ejemplo n.º 3
0
Archivo: node.go Proyecto: tsuru/tsuru
// title: update nodes
// path: /{provisioner}/node
// method: PUT
// consume: application/x-www-form-urlencoded
// responses:
//   200: Ok
//   400: Invalid data
//   401: Unauthorized
//   404: Not found
func updateNodeHandler(w http.ResponseWriter, r *http.Request, t auth.Token) (err error) {
	err = r.ParseForm()
	if err != nil {
		return &tsuruErrors.HTTP{Code: http.StatusBadRequest, Message: err.Error()}
	}
	var params provision.UpdateNodeOptions
	dec := form.NewDecoder(nil)
	dec.IgnoreUnknownKeys(true)
	err = dec.DecodeValues(&params, r.Form)
	if err != nil {
		return &tsuruErrors.HTTP{Code: http.StatusBadRequest, Message: err.Error()}
	}
	if params.Disable && params.Enable {
		return &tsuruErrors.HTTP{
			Code:    http.StatusBadRequest,
			Message: "A node can't be enabled and disabled simultaneously.",
		}
	}
	if params.Address == "" {
		return &tsuruErrors.HTTP{Code: http.StatusBadRequest, Message: "address is required"}
	}
	prov, node, err := provision.FindNode(params.Address)
	if err != nil {
		if err == provision.ErrNodeNotFound {
			return &tsuruErrors.HTTP{
				Code:    http.StatusNotFound,
				Message: err.Error(),
			}
		}
		return err
	}
	nodeProv := prov.(provision.NodeProvisioner)
	oldPool := node.Pool()
	allowedOldPool := permission.Check(t, permission.PermNodeUpdate,
		permission.Context(permission.CtxPool, oldPool),
	)
	if !allowedOldPool {
		return permission.ErrUnauthorized
	}
	newPool, ok := params.Metadata["pool"]
	if ok {
		allowedNewPool := permission.Check(t, permission.PermNodeUpdate,
			permission.Context(permission.CtxPool, newPool),
		)
		if !allowedNewPool {
			return permission.ErrUnauthorized
		}
	}
	evt, err := event.New(&event.Opts{
		Target:     event.Target{Type: event.TargetTypeNode, Value: node.Address()},
		Kind:       permission.PermNodeUpdate,
		Owner:      t,
		CustomData: event.FormToCustomData(r.Form),
		Allowed: event.Allowed(permission.PermPoolReadEvents,
			permission.Context(permission.CtxPool, oldPool),
			permission.Context(permission.CtxPool, newPool),
		),
	})
	if err != nil {
		return err
	}
	defer func() { evt.Done(err) }()
	return nodeProv.UpdateNode(params)
}
Ejemplo n.º 4
0
Archivo: node.go Proyecto: tsuru/tsuru
// title: remove node
// path: /{provisioner}/node/{address}
// method: DELETE
// responses:
//   200: Ok
//   401: Unauthorized
//   404: Not found
func removeNodeHandler(w http.ResponseWriter, r *http.Request, t auth.Token) (err error) {
	r.ParseForm()
	address := r.URL.Query().Get(":address")
	if address == "" {
		return errors.Errorf("Node address is required.")
	}
	prov, node, err := provision.FindNode(address)
	if err != nil {
		if err == provision.ErrNodeNotFound {
			return &tsuruErrors.HTTP{
				Code:    http.StatusNotFound,
				Message: err.Error(),
			}
		}
		return err
	}
	nodeProv := prov.(provision.NodeProvisioner)
	pool := node.Pool()
	allowedNodeRemove := permission.Check(t, permission.PermNodeDelete,
		permission.Context(permission.CtxPool, pool),
	)
	if !allowedNodeRemove {
		return permission.ErrUnauthorized
	}
	removeIaaS, _ := strconv.ParseBool(r.URL.Query().Get("remove-iaas"))
	if removeIaaS {
		allowedIaasRemove := permission.Check(t, permission.PermMachineDelete,
			permission.Context(permission.CtxIaaS, node.Metadata()["iaas"]),
		)
		if !allowedIaasRemove {
			return permission.ErrUnauthorized
		}
	}
	evt, err := event.New(&event.Opts{
		Target:     event.Target{Type: event.TargetTypeNode, Value: node.Address()},
		Kind:       permission.PermNodeDelete,
		Owner:      t,
		CustomData: event.FormToCustomData(r.Form),
		Allowed:    event.Allowed(permission.PermPoolReadEvents, permission.Context(permission.CtxPool, pool)),
	})
	if err != nil {
		return err
	}
	defer func() { evt.Done(err) }()
	noRebalance, _ := strconv.ParseBool(r.URL.Query().Get("no-rebalance"))
	err = nodeProv.RemoveNode(provision.RemoveNodeOptions{
		Address:   address,
		Rebalance: !noRebalance,
		Writer:    w,
	})
	if err != nil {
		return err
	}
	if removeIaaS {
		var m iaas.Machine
		m, err = iaas.FindMachineByIdOrAddress(node.Metadata()["iaas-id"], net.URLToHost(address))
		if err != nil && err != mgo.ErrNotFound {
			return nil
		}
		return m.Destroy()
	}
	return nil
}