Exemple #1
0
// CreateApp creates a new app.
//
// Creating a new app is a process composed of the following steps:
//
//       1. Save the app in the database
//       2. Create the git repository using the repository manager
//       3. Provision the app using the provisioner
func CreateApp(app *App, user *auth.User) error {
	teams, err := user.Teams()
	if err != nil {
		return err
	}
	if len(teams) == 0 {
		return NoTeamsError{}
	}
	platform, err := getPlatform(app.Platform)
	if err != nil {
		return err
	}
	if platform.Disabled && !user.IsAdmin() {
		return InvalidPlatformError{}
	}
	var plan *Plan
	if app.Plan.Name == "" {
		plan, err = DefaultPlan()
	} else {
		plan, err = findPlanByName(app.Plan.Name)
	}
	if err != nil {
		return err
	}
	if app.TeamOwner == "" {
		if len(teams) > 1 {
			return ManyTeamsError{}
		}
		app.TeamOwner = teams[0].Name
	}
	err = app.ValidateTeamOwner(user)
	if err != nil {
		return err
	}
	app.Plan = *plan
	err = app.SetPool()
	if err != nil {
		return err
	}
	app.Teams = []string{app.TeamOwner}
	app.Owner = user.Email
	err = app.validate()
	if err != nil {
		return err
	}
	actions := []*action.Action{
		&reserveUserApp,
		&insertApp,
		&exportEnvironmentsAction,
		&createRepository,
		&provisionApp,
		&setAppIp,
	}
	pipeline := action.NewPipeline(actions...)
	err = pipeline.Execute(app, user)
	if err != nil {
		return &AppCreationError{app: app.Name, Err: err}
	}
	return nil
}
func GetServiceInstancesByServicesAndTeams(services []Service, u *auth.User, appName string) ([]ServiceInstance, error) {
	var instances []ServiceInstance
	teams, err := u.Teams()
	if err != nil {
		return nil, err
	}
	if len(teams) == 0 {
		return nil, nil
	}
	conn, err := db.Conn()
	if err != nil {
		return nil, err
	}
	defer conn.Close()
	var teamNames []string
	if !u.IsAdmin() {
		teamNames = auth.GetTeamsNames(teams)
	}
	query := genericServiceInstancesFilter(services, teamNames)
	if appName != "" {
		query["apps"] = appName
	}
	err = conn.ServiceInstances().Find(query).All(&instances)
	return instances, err
}
Exemple #3
0
// List returns the list of apps that the given user has access to.
//
// If the user does not have access to any app, this function returns an empty
// list and a nil error.
//
// The list can be filtered through the filter parameter.
func List(u *auth.User, filter *Filter) ([]App, error) {
	var apps []App
	conn, err := db.Conn()
	if err != nil {
		return nil, err
	}
	defer conn.Close()
	query := filter.Query()
	if u == nil || u.IsAdmin() {
		if err = conn.Apps().Find(query).All(&apps); err != nil {
			return []App{}, err
		}
		return apps, nil
	}
	ts, err := u.Teams()
	if err != nil {
		return []App{}, err
	}
	teams := auth.GetTeamsNames(ts)
	query["teams"] = bson.M{"$in": teams}
	if err := conn.Apps().Find(query).All(&apps); err != nil {
		return []App{}, err
	}
	return apps, nil
}
Exemple #4
0
func GetServicesByOwnerTeams(teamKind string, u *auth.User) ([]Service, error) {
	teams, err := u.Teams()
	if err != nil {
		return nil, err
	}
	conn, err := db.Conn()
	if err != nil {
		return nil, err
	}
	defer conn.Close()
	teamsNames := auth.GetTeamsNames(teams)
	q := bson.M{teamKind: bson.M{"$in": teamsNames}}
	var services []Service
	err = conn.Services().Find(q).All(&services)
	return services, err
}
func GetServiceInstancesByServicesAndTeams(services []Service, u *auth.User) ([]ServiceInstance, error) {
	var instances []ServiceInstance
	teams, err := u.Teams()
	if err != nil {
		return nil, err
	}
	if len(teams) == 0 {
		return nil, nil
	}
	conn, err := db.Conn()
	if err != nil {
		return nil, err
	}
	defer conn.Close()
	q, f := genericServiceInstancesFilter(services, auth.GetTeamsNames(teams))
	err = conn.ServiceInstances().Find(q).Select(f).All(&instances)
	return instances, err
}
Exemple #6
0
func (app *App) ValidateTeamOwner(user *auth.User) error {
	if _, err := auth.GetTeam(app.TeamOwner); err == auth.ErrTeamNotFound {
		return err
	}
	if user.IsAdmin() {
		return nil
	}
	teams, err := user.Teams()
	if err != nil {
		return err
	}
	for _, t := range teams {
		if t.Name == app.TeamOwner {
			return nil
		}
	}
	errorMsg := fmt.Sprintf("You can not set %s team as app's owner. Please set one of your teams as app's owner.", app.TeamOwner)
	return stderr.New(errorMsg)
}
Exemple #7
0
func GetServicesByTeamKindAndNoRestriction(teamKind string, u *auth.User) ([]Service, error) {
	teams, err := u.Teams()
	if err != nil {
		return nil, err
	}
	conn, err := db.Conn()
	if err != nil {
		return nil, err
	}
	defer conn.Close()
	teamsNames := auth.GetTeamsNames(teams)
	q := bson.M{"$or": []bson.M{
		{teamKind: bson.M{"$in": teamsNames}},
		{"is_restricted": false},
	}}
	var services []Service
	err = conn.Services().Find(q).Select(bson.M{"name": 1}).All(&services)
	return services, err
}
Exemple #8
0
// List returns the list of apps that the given user has access to.
//
// If the user does not have acces to any app, this function returns an empty
// list and a nil error.
func List(u *auth.User) ([]App, error) {
	var apps []App
	conn, err := db.Conn()
	if err != nil {
		return nil, err
	}
	defer conn.Close()
	if u.IsAdmin() {
		if err := conn.Apps().Find(nil).All(&apps); err != nil {
			return []App{}, err
		}
		return apps, nil
	}
	ts, err := u.Teams()
	if err != nil {
		return []App{}, err
	}
	teams := auth.GetTeamsNames(ts)
	if err := conn.Apps().Find(bson.M{"teams": bson.M{"$in": teams}}).All(&apps); err != nil {
		return []App{}, err
	}
	return apps, nil
}
func CreateServiceInstance(instance ServiceInstance, service *Service, user *auth.User) error {
	err := validateServiceInstanceName(service.Name, instance.Name)
	if err != nil {
		return err
	}
	instance.ServiceName = service.Name
	teams, err := user.Teams()
	if err != nil {
		return err
	}
	instance.Teams = make([]string, 0, len(teams))
	for _, team := range teams {
		if service.HasTeam(&team) || !service.IsRestricted {
			instance.Teams = append(instance.Teams, team.Name)
		}
	}
	if instance.TeamOwner == "" {
		if len(instance.Teams) > 1 {
			return ErrMultipleTeams
		}
		instance.TeamOwner = instance.Teams[0]
	} else {
		var found bool
		for _, team := range instance.Teams {
			if instance.TeamOwner == team {
				found = true
				break
			}
		}
		if !found {
			return auth.ErrTeamNotFound
		}
	}
	actions := []*action.Action{&createServiceInstance, &insertServiceInstance}
	pipeline := action.NewPipeline(actions...)
	return pipeline.Execute(*service, instance, user.Email)
}
func CreateServiceInstance(name string, service *Service, planName string, user *auth.User) error {
	err := validateServiceInstanceName(name)
	if err != nil {
		return err
	}
	instance := ServiceInstance{
		Name:        name,
		ServiceName: service.Name,
	}
	instance.PlanName = planName
	teams, err := user.Teams()
	if err != nil {
		return err
	}
	instance.Teams = make([]string, 0, len(teams))
	for _, team := range teams {
		if service.HasTeam(&team) || !service.IsRestricted {
			instance.Teams = append(instance.Teams, team.Name)
		}
	}
	actions := []*action.Action{&createServiceInstance, &insertServiceInstance}
	pipeline := action.NewPipeline(actions...)
	return pipeline.Execute(*service, instance)
}
Exemple #11
0
// CreateApp creates a new app.
//
// Creating a new app is a process composed of four steps:
//
//       1. Save the app in the database
//       2. Create IAM credentials for the app
//       3. Create the git repository using gandalf
//       4. Provision units within the provisioner
func CreateApp(app *App, user *auth.User) error {
	teams, err := user.Teams()
	if err != nil {
		return err
	}
	if len(teams) == 0 {
		return NoTeamsError{}
	}
	if _, err := getPlatform(app.Platform); err != nil {
		return err
	}
	// app.Memory is empty, no custom memory passed from CLI
	if app.Memory < 1 {
		// get default memory limit from tsuru config
		configMemory, err := config.GetInt("docker:memory")
		if err != nil {
			// no default memory set in config (or error when reading), set it as unlimited (0)
			app.Memory = 0
		} else {
			// default memory set in config, use that.
			app.Memory = configMemory
		}
	}
	// app.Swap is empty, no custom swap passed from CLI
	if app.Swap < 1 {
		// get default swap limit from tsuru config
		configSwap, err := config.GetInt("docker:swap")
		if err != nil {
			// no default swap set in config (or error when reading), set it as unlimited (0)
			app.Swap = 0
		} else {
			// default swap set in config, use that.
			app.Swap = configSwap
		}
	}
	// Swap size must always be the sum of memory plus swap
	if app.Swap > 0 {
		app.Swap = app.Memory + app.Swap
	}
	if err := app.setTeamOwner(teams); err != nil {
		return err
	}
	app.SetTeams(teams)
	app.Owner = user.Email
	if !app.isValid() {
		msg := "Invalid app name, your app should have at most 63 " +
			"characters, containing only lower case letters, numbers or dashes, " +
			"starting with a letter."
		return &errors.ValidationError{Message: msg}
	}
	if app.equalAppNameAndPlatformName() {
		msg := "Invalid app name: platform name and app name " +
			"can not be the same"
		return &errors.ValidationError{Message: msg}
	}
	if app.equalToSomePlatformName() {
		msg := "Invalid app name: platform name already exists " +
			"with the same name"
		return &errors.ValidationError{Message: msg}
	}
	actions := []*action.Action{
		&reserveUserApp,
		&insertApp,
		&exportEnvironmentsAction,
		&createRepository,
		&provisionApp,
	}
	pipeline := action.NewPipeline(actions...)
	err = pipeline.Execute(app, user)
	if err != nil {
		return &AppCreationError{app: app.Name, Err: err}
	}
	return nil
}