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 }
// 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 }
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}) } } } }
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) } } } }
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 }
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 }
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 }
// 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 }
// 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 }
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 }
// 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) }