Exemple #1
0
func PlatformRemove(name string) error {
	provisioners, err := provision.Registry()
	if err != nil {
		return err
	}
	if name == "" {
		return ErrPlatformNameMissing
	}
	conn, err := db.Conn()
	if err != nil {
		return err
	}
	defer conn.Close()
	apps, _ := conn.Apps().Find(bson.M{"framework": name}).Count()
	if apps > 0 {
		return ErrDeletePlatformWithApps
	}
	for _, p := range provisioners {
		if extensibleProv, ok := p.(provision.ExtensibleProvisioner); ok {
			err = extensibleProv.PlatformRemove(name)
			if err != nil {
				log.Errorf("Failed to remove platform from provisioner %q: %s", p.GetName(), err)
			}
		}
	}
	err = conn.Platforms().Remove(bson.M{"_id": name})
	if err == mgo.ErrNotFound {
		return ErrPlatformNotFound
	}
	return err
}
Exemple #2
0
// title: remove node container
// path: /docker/nodecontainers/{name}
// method: DELETE
// responses:
//   200: Ok
//   401: Unauthorized
//   404: Not found
func nodeContainerDelete(w http.ResponseWriter, r *http.Request, t auth.Token) (err error) {
	r.ParseForm()
	name := r.URL.Query().Get(":name")
	poolName := r.URL.Query().Get("pool")
	kill, _ := strconv.ParseBool(r.URL.Query().Get("kill"))
	var ctxs []permission.PermissionContext
	if poolName != "" {
		ctxs = append(ctxs, permission.Context(permission.CtxPool, poolName))
	}
	if !permission.Check(t, permission.PermNodecontainerDelete, ctxs...) {
		return permission.ErrUnauthorized
	}
	evt, err := event.New(&event.Opts{
		Target:     event.Target{Type: event.TargetTypeNodeContainer, Value: name},
		Kind:       permission.PermNodecontainerDelete,
		Owner:      t,
		CustomData: event.FormToCustomData(r.Form),
		Allowed:    event.Allowed(permission.PermPoolReadEvents, ctxs...),
	})
	if err != nil {
		return err
	}
	defer func() { evt.Done(err) }()
	err = nodecontainer.RemoveContainer(poolName, name)
	if err == nodecontainer.ErrNodeContainerNotFound {
		return &tsuruErrors.HTTP{
			Code:    http.StatusNotFound,
			Message: fmt.Sprintf("node container %q not found for pool %q", name, poolName),
		}
	}
	if err != nil || !kill {
		return err
	}
	provs, err := provision.Registry()
	if err != nil {
		return err
	}
	w.Header().Set("Content-Type", "application/x-json-stream")
	keepAliveWriter := tsuruIo.NewKeepAliveWriter(w, 15*time.Second, "")
	defer keepAliveWriter.Stop()
	writer := &tsuruIo.SimpleJsonMessageEncoderWriter{Encoder: json.NewEncoder(keepAliveWriter)}
	var allErrors []string
	for _, prov := range provs {
		ncProv, ok := prov.(provision.NodeContainerProvisioner)
		if !ok {
			continue
		}
		err = ncProv.RemoveNodeContainer(name, poolName, writer)
		if err != nil {
			allErrors = append(allErrors, err.Error())
		}
	}
	if len(allErrors) > 0 {
		return errors.Errorf("multiple errors removing node container: %s", strings.Join(allErrors, "; "))
	}
	return nil
}
Exemple #3
0
func registerProvisionersCommands(m *cmd.Manager) {
	provisioners := provision.Registry()
	for _, p := range provisioners {
		if c, ok := p.(cmd.Commandable); ok {
			commands := c.Commands()
			for _, cmd := range commands {
				m.Register(&tsurudCommand{Command: cmd})
			}
		}
	}
}
Exemple #4
0
func registerProvisionersCommands(m *cmd.Manager) {
	provisioners := provision.Registry()
	for _, p := range provisioners {
		if c, ok := p.(cmd.AdminCommandable); ok {
			commands := c.AdminCommands()
			for _, cmd := range commands {
				m.Register(cmd)
			}
		}
	}
}
Exemple #5
0
func PlatformUpdate(opts provision.PlatformOptions) error {
	provisioners, err := provision.Registry()
	if err != nil {
		return err
	}
	var platform Platform
	if opts.Name == "" {
		return ErrPlatformNameMissing
	}
	conn, err := db.Conn()
	if err != nil {
		return err
	}
	defer conn.Close()
	err = conn.Platforms().Find(bson.M{"_id": opts.Name}).One(&platform)
	if err != nil {
		if err == mgo.ErrNotFound {
			return ErrPlatformNotFound
		}
		return err
	}
	if opts.Args["dockerfile"] != "" || opts.Input != nil {
		for _, p := range provisioners {
			if extensibleProv, ok := p.(provision.ExtensibleProvisioner); ok {
				err = extensibleProv.PlatformUpdate(opts)
				if err != nil {
					return err
				}
			}
		}
		var apps []App
		err = conn.Apps().Find(bson.M{"framework": opts.Name}).All(&apps)
		if err != nil {
			return err
		}
		for _, app := range apps {
			app.SetUpdatePlatform(true)
		}
	}
	if opts.Args["disabled"] != "" {
		disableBool, err := strconv.ParseBool(opts.Args["disabled"])
		if err != nil {
			return err
		}
		err = conn.Platforms().Update(bson.M{"_id": opts.Name}, bson.M{"$set": bson.M{"disabled": disableBool}})
		if err != nil {
			return err
		}
	}
	return nil
}
Exemple #6
0
func registerProvisionersCommands(m *cmd.Manager) error {
	provisioners, err := provision.Registry()
	if err != nil {
		return err
	}
	for _, p := range provisioners {
		if c, ok := p.(cmd.Commandable); ok {
			commands := c.Commands()
			for _, cmd := range commands {
				m.Register(&tsurudCommand{Command: cmd})
			}
		}
	}
	return nil
}
Exemple #7
0
func allNodes() ([]provision.Node, error) {
	provs, err := provision.Registry()
	if err != nil {
		return nil, err
	}
	var nodes []provision.Node
	for _, p := range provs {
		if nodeProv, ok := p.(provision.NodeProvisioner); ok {
			var provNodes []provision.Node
			provNodes, err = nodeProv.ListNodes(nil)
			if err != nil {
				return nil, err
			}
			nodes = append(nodes, provNodes...)
		}
	}
	return nodes, nil
}
Exemple #8
0
// UpdateNodeStatus updates the status of the given node and its units,
// returning a map which units were found during the update.
func UpdateNodeStatus(nodeData provision.NodeStatusData) ([]UpdateUnitsResult, error) {
	provisioners, err := provision.Registry()
	if err != nil {
		return nil, err
	}
	var node provision.Node
	for _, p := range provisioners {
		if nodeProv, ok := p.(provision.NodeProvisioner); ok {
			node, err = nodeProv.NodeForNodeData(nodeData)
			if err == nil {
				break
			}
			if errors.Cause(err) != provision.ErrNodeNotFound {
				return nil, err
			}
		}
	}
	if node == nil {
		return nil, provision.ErrNodeNotFound
	}
	if healer.HealerInstance != nil {
		err = healer.HealerInstance.UpdateNodeData(node, nodeData.Checks)
		if err != nil {
			log.Errorf("unable to set node status in healer: %s", err)
		}
	}
	unitProv, ok := node.Provisioner().(provision.UnitStatusProvisioner)
	if !ok {
		return []UpdateUnitsResult{}, nil
	}
	result := make([]UpdateUnitsResult, len(nodeData.Units))
	for i, unitData := range nodeData.Units {
		unit := provision.Unit{ID: unitData.ID, Name: unitData.Name}
		err = unitProv.SetUnitStatus(unit, unitData.Status)
		_, isNotFound := err.(*provision.UnitNotFoundError)
		if err != nil && !isNotFound {
			return nil, err
		}
		result[i] = UpdateUnitsResult{ID: unitData.ID, Found: !isNotFound}
	}
	return result, nil
}
Exemple #9
0
// PlatformAdd add a new platform to tsuru
func PlatformAdd(opts provision.PlatformOptions) error {
	if opts.Name == "" {
		return ErrPlatformNameMissing
	}
	provisioners, err := provision.Registry()
	if err != nil {
		return err
	}
	p := Platform{Name: opts.Name}
	conn, err := db.Conn()
	if err != nil {
		return err
	}
	defer conn.Close()
	err = conn.Platforms().Insert(p)
	if err != nil {
		if mgo.IsDup(err) {
			return DuplicatePlatformError
		}
		return err
	}
	for _, p := range provisioners {
		if extensibleProv, ok := p.(provision.ExtensibleProvisioner); ok {
			err = extensibleProv.PlatformAdd(opts)
			if err != nil {
				break
			}
		}
	}
	if err != nil {
		dbErr := conn.Platforms().RemoveId(p.Name)
		if dbErr != nil {
			return tsuruErrors.NewMultiError(
				errors.Wrapf(dbErr, "unable to rollback platform add"),
				errors.Wrapf(err, "original platform add error"),
			)
		}
		return err
	}
	return nil
}
Exemple #10
0
func setAllowed(evt *event.Event) (err error) {
	defer func() {
		if err != nil {
			fmt.Printf("setting global context to evt %q: %s\n", evt.String(), err)
			err = nil
		}
	}()
	switch evt.Target.Type {
	case event.TargetTypeApp:
		var a *app.App
		a, err = app.GetByName(evt.Target.Value)
		if err != nil {
			evt.Allowed = event.Allowed(permission.PermAppReadEvents)
			if evt.Cancelable {
				evt.Allowed = event.Allowed(permission.PermAppUpdateEvents)
			}
			return err
		}
		ctxs := append(permission.Contexts(permission.CtxTeam, a.Teams),
			permission.Context(permission.CtxApp, a.Name),
			permission.Context(permission.CtxPool, a.Pool),
		)
		evt.Allowed = event.Allowed(permission.PermAppReadEvents, ctxs...)
		if evt.Cancelable {
			evt.Allowed = event.Allowed(permission.PermAppUpdateEvents, ctxs...)
		}
	case event.TargetTypeTeam:
		evt.Allowed = event.Allowed(permission.PermTeamReadEvents, permission.Context(permission.CtxTeam, evt.Target.Value))
	case event.TargetTypeService:
		s := service.Service{Name: evt.Target.Value}
		err = s.Get()
		if err != nil {
			evt.Allowed = event.Allowed(permission.PermServiceReadEvents)
			return err
		}
		evt.Allowed = event.Allowed(permission.PermServiceReadEvents,
			append(permission.Contexts(permission.CtxTeam, s.OwnerTeams),
				permission.Context(permission.CtxService, s.Name),
			)...,
		)
	case event.TargetTypeServiceInstance:
		v := strings.SplitN(evt.Target.Value, "/", 2)
		if len(v) != 2 {
			evt.Allowed = event.Allowed(permission.PermServiceInstanceReadEvents)
			return nil
		}
		var si *service.ServiceInstance
		si, err = service.GetServiceInstance(v[0], v[1])
		if err != nil {
			evt.Allowed = event.Allowed(permission.PermServiceInstanceReadEvents)
			return err
		}
		evt.Allowed = event.Allowed(permission.PermServiceReadEvents,
			append(permission.Contexts(permission.CtxTeam, si.Teams),
				permission.Context(permission.CtxServiceInstance, evt.Target.Value),
			)...,
		)
	case event.TargetTypePool:
		evt.Allowed = event.Allowed(permission.PermPoolReadEvents, permission.Context(permission.CtxPool, evt.Target.Value))
	case event.TargetTypeUser:
		evt.Allowed = event.Allowed(permission.PermUserReadEvents, permission.Context(permission.CtxUser, evt.Target.Value))
	case event.TargetTypeIaas:
		evt.Allowed = event.Allowed(permission.PermMachineReadEvents, permission.Context(permission.CtxIaaS, evt.Target.Value))
	case event.TargetTypeContainer:
		var provisioners []provision.Provisioner
		provisioners, err = provision.Registry()
		if err != nil {
			return err
		}
		var a provision.App
		for _, p := range provisioners {
			if finderProv, ok := p.(provision.UnitFinderProvisioner); ok {
				a, err = finderProv.GetAppFromUnitID(evt.Target.Value)
				_, isNotFound := err.(*provision.UnitNotFoundError)
				if err == nil || !isNotFound {
					break
				}
			}
		}
		if err != nil {
			return err
		}
		evt.Allowed = event.Allowed(permission.PermAppReadEvents,
			append(permission.Contexts(permission.CtxTeam, a.GetTeamsName()),
				permission.Context(permission.CtxApp, a.GetName()),
				permission.Context(permission.CtxPool, a.GetPool()),
			)...,
		)
	case event.TargetTypeNode:
		var provisioners []provision.Provisioner
		provisioners, err = provision.Registry()
		if err != nil {
			return err
		}
		var ctxs []permission.PermissionContext
		for _, p := range provisioners {
			if nodeProvisioner, ok := p.(provision.NodeProvisioner); ok {
				var nodes []provision.Node
				nodes, err = nodeProvisioner.ListNodes([]string{evt.Target.Value})
				if err != nil {
					return err
				}
				ctxs = append(ctxs, permission.Context(permission.CtxPool, nodes[0].Pool()))
			}
		}
		evt.Allowed = event.Allowed(permission.PermPoolReadEvents, ctxs...)
	case event.TargetTypeRole:
		evt.Allowed = event.Allowed(permission.PermRoleReadEvents)
	default:
		evt.Allowed = event.Allowed(permission.PermDebug)
	}
	return nil
}
Exemple #11
0
// title: list nodes
// path: /{provisioner}/node
// method: GET
// produce: application/json
// responses:
//   200: Ok
//   204: No content
func listNodesHandler(w http.ResponseWriter, r *http.Request, t auth.Token) error {
	pools, err := permission.ListContextValues(t, permission.PermNodeRead, false)
	if err != nil {
		return err
	}
	provs, err := provision.Registry()
	if err != nil {
		return err
	}
	provNameMap := map[string]string{}
	var allNodes []provision.Node
	for _, prov := range provs {
		nodeProv, ok := prov.(provision.NodeProvisioner)
		if !ok {
			continue
		}
		var nodes []provision.Node
		nodes, err = nodeProv.ListNodes(nil)
		if err != nil {
			return err
		}
		for _, n := range nodes {
			provNameMap[n.Address()] = prov.GetName()
		}
		allNodes = append(allNodes, nodes...)
	}
	if pools != nil {
		filteredNodes := make([]provision.Node, 0, len(allNodes))
		for _, node := range allNodes {
			for _, pool := range pools {
				if node.Pool() == pool {
					filteredNodes = append(filteredNodes, node)
					break
				}
			}
		}
		allNodes = filteredNodes
	}
	iaases, err := permission.ListContextValues(t, permission.PermMachineRead, false)
	if err != nil {
		return err
	}
	machines, err := iaas.ListMachines()
	if err != nil {
		return err
	}
	if iaases != nil {
		filteredMachines := make([]iaas.Machine, 0, len(machines))
		for _, machine := range machines {
			for _, iaas := range iaases {
				if machine.Iaas == iaas {
					filteredMachines = append(filteredMachines, machine)
					break
				}
			}
		}
		machines = filteredMachines
	}
	if len(allNodes) == 0 && len(machines) == 0 {
		w.WriteHeader(http.StatusNoContent)
		return nil
	}
	nodesJson := make([]json.RawMessage, len(allNodes))
	for i, n := range allNodes {
		nodesJson[i], err = provision.NodeToJSON(n)
		if err != nil {
			return err
		}
	}
	result := listNodeResponse{
		Nodes:    nodesJson,
		Machines: machines,
	}
	w.Header().Set("Content-Type", "application/json")
	return json.NewEncoder(w).Encode(result)
}