Exemple #1
0
func generateAppToken(w http.ResponseWriter, r *http.Request, t *auth.Token) error {
	var body jToken
	defer r.Body.Close()
	err := json.NewDecoder(r.Body).Decode(&body)
	if err != nil {
		return err
	}
	if body.Client == "" {
		return &errors.HTTP{
			Code:    http.StatusBadRequest,
			Message: "Missing client name in JSON body",
		}
	}
	token, err := auth.CreateApplicationToken(body.Client)
	if err != nil {
		return err
	}
	if body.Export {
		a := app.App{Name: body.Client}
		if err := a.Get(); err == nil {
			envs := []bind.EnvVar{
				{
					Name:   "TSURU_APP_TOKEN",
					Value:  token.Token,
					Public: false,
				},
			}
			a.SetEnvs(envs, false)
		}
	}
	return json.NewEncoder(w).Encode(token)
}
Exemple #2
0
func (s *ELBSuite) TestELBInstanceHealerInstallingUnit(c *gocheck.C) {
	lb := "elbtest"
	instance := s.server.NewInstance()
	defer s.server.RemoveInstance(instance)
	s.server.NewLoadBalancer(lb)
	defer s.server.RemoveLoadBalancer(lb)
	s.server.RegisterInstance(instance, lb)
	defer s.server.DeregisterInstance(instance, lb)
	a := app.App{
		Name:  "elbtest",
		Units: []app.Unit{{InstanceId: instance, State: "installing", Name: "elbtest/0"}},
	}
	storage, err := db.Conn()
	c.Assert(err, gocheck.IsNil)
	err = storage.Apps().Insert(a)
	c.Assert(err, gocheck.IsNil)
	defer storage.Apps().Remove(bson.M{"name": a.Name})
	s.provisioner.Provision(&a)
	defer s.provisioner.Destroy(&a)
	state := elb.InstanceState{
		Description: "Instance has failed at least the UnhealthyThreshold number of health checks consecutively.",
		State:       "OutOfService",
		ReasonCode:  "Instance",
		InstanceId:  instance,
	}
	s.server.ChangeInstanceState(lb, state)
	healer := elbInstanceHealer{}
	err = healer.Heal()
	c.Assert(err, gocheck.IsNil)
	err = a.Get()
	c.Assert(err, gocheck.IsNil)
	c.Assert(a.Units, gocheck.HasLen, 1)
	c.Assert(a.Units[0].InstanceId, gocheck.Equals, instance)
}
Exemple #3
0
func (s *S) TestUnbindRemovesEnvironmentVariableFromApp(c *gocheck.C) {
	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.WriteHeader(http.StatusNoContent)
	}))
	defer ts.Close()
	srvc := service.Service{Name: "mysql", Endpoint: map[string]string{"production": ts.URL}}
	err := srvc.Create()
	c.Assert(err, gocheck.IsNil)
	defer s.conn.Services().Remove(bson.M{"_id": "mysql"})
	instance := service.ServiceInstance{
		Name:        "my-mysql",
		ServiceName: "mysql",
		Teams:       []string{s.team.Name},
		Apps:        []string{"painkiller"},
	}
	err = instance.Create()
	c.Assert(err, gocheck.IsNil)
	defer s.conn.ServiceInstances().Remove(bson.M{"_id": "my-mysql"})
	a := app.App{
		Name:  "painkiller",
		Teams: []string{s.team.Name},
		Env: map[string]bind.EnvVar{
			"DATABASE_HOST": {
				Name:         "DATABASE_HOST",
				Value:        "arrea",
				Public:       false,
				InstanceName: instance.Name,
			},
			"MY_VAR": {
				Name:  "MY_VAR",
				Value: "123",
			},
		},
		Units: []app.Unit{
			{
				Ip: "10.10.10.10",
			},
		},
	}
	err = s.conn.Apps().Insert(&a)
	c.Assert(err, gocheck.IsNil)
	defer s.conn.Apps().Remove(bson.M{"name": a.Name})
	err = instance.UnbindApp(&a)
	c.Assert(err, gocheck.IsNil)
	newApp := app.App{Name: a.Name}
	err = newApp.Get()
	c.Assert(err, gocheck.IsNil)
	expected := map[string]bind.EnvVar{
		"MY_VAR": {
			Name:  "MY_VAR",
			Value: "123",
		},
	}
	c.Assert(a.Env, gocheck.DeepEquals, expected)
}
Exemple #4
0
func (s segregatedScheduler) Schedule(cfg *docker.Config) (string, *docker.Container, error) {
	image := cfg.Image
	namespace, err := config.GetString("docker:repository-namespace")
	if err != nil {
		return "", nil, err
	}
	conn, err := db.Conn()
	if err != nil {
		return "", nil, err
	}
	defer conn.Close()
	appname := strings.Replace(image, namespace+"/", "", -1)
	app := app.App{Name: appname}
	err = app.Get()
	if err != nil {
		return s.fallback(cfg)
	}
	if len(app.Teams) == 1 {
		var nodes []node
		err = conn.Collection(schedulerCollection).Find(bson.M{"team": app.Teams[0]}).All(&nodes)
		if err != nil || len(nodes) < 1 {
			return s.fallback(cfg)
		}
		return s.handle(cfg, nodes)
	}
	return s.fallback(cfg)
}
Exemple #5
0
func (s *S) TestSaveUnitsForward(c *gocheck.C) {
	app := app.App{
		Name:     "otherapp",
		Platform: "zend",
	}
	conn, err := db.Conn()
	c.Assert(err, gocheck.IsNil)
	defer conn.Close()
	err = conn.Apps().Insert(app)
	c.Assert(err, gocheck.IsNil)
	defer conn.Apps().Remove(bson.M{"name": app.Name})
	container := container{
		ID:       "id",
		Type:     "python",
		HostAddr: "",
		AppName:  app.Name,
	}
	coll := collection()
	c.Assert(err, gocheck.IsNil)
	coll.Insert(&container)
	context := action.FWContext{Params: []interface{}{&app}}
	_, err = saveUnits.Forward(context)
	c.Assert(err, gocheck.IsNil)
	err = app.Get()
	c.Assert(err, gocheck.IsNil)
	c.Assert(app.Units[0].Name, gocheck.Equals, "id")
}
Exemple #6
0
func (s segregatedScheduler) Schedule(opts dcli.CreateContainerOptions, cfg *docker.Config) (string, *docker.Container, error) {
	conn, err := db.Conn()
	if err != nil {
		return "", nil, err
	}
	defer conn.Close()
	var cont container
	coll := collection()
	defer coll.Close()
	err = coll.Find(bson.M{"name": opts.Name}).One(&cont)
	if err != nil {
		return "", nil, err
	}
	app := app.App{Name: cont.AppName}
	err = app.Get()
	if err != nil {
		return s.fallback(opts, cfg)
	}
	var nodes []node
	query := bson.M{"teams": bson.M{"$in": app.Teams}}
	err = conn.Collection(schedulerCollection).Find(query).All(&nodes)
	if err != nil || len(nodes) < 1 {
		return s.fallback(opts, cfg)
	}
	return s.handle(opts, cfg, nodes)
}
Exemple #7
0
func addLog(w http.ResponseWriter, r *http.Request, t *auth.Token) error {
	queryValues := r.URL.Query()
	app := app.App{Name: queryValues.Get(":app")}
	err := app.Get()
	if err != nil {
		return err
	}
	defer r.Body.Close()
	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		return err
	}
	var logs []string
	err = json.Unmarshal(body, &logs)
	source := queryValues.Get("source")
	if len(source) == 0 {
		source = "app"
	}
	for _, log := range logs {
		err := app.Log(log, source)
		if err != nil {
			return err
		}
	}
	w.WriteHeader(http.StatusOK)
	return nil
}
Exemple #8
0
func (s *S) TestUpdateWithMultipleApps(c *gocheck.C) {
	appDicts := []map[string]string{
		{
			"name": "andrewzito3",
			"ip":   "10.10.10.163",
		},
		{
			"name": "flaviapp",
			"ip":   "10.10.10.208",
		},
		{
			"name": "mysqlapi",
			"ip":   "10.10.10.131",
		},
		{
			"name": "teste_api_semantica",
			"ip":   "10.10.10.189",
		},
		{
			"name": "xikin",
			"ip":   "10.10.10.168",
		},
	}
	apps := make([]app.App, len(appDicts))
	units := make([]provision.Unit, len(appDicts))
	for i, appDict := range appDicts {
		a := app.App{Name: appDict["name"]}
		err := s.conn.Apps().Insert(&a)
		c.Assert(err, gocheck.IsNil)
		apps[i] = a
		units[i] = provision.Unit{
			Name:    "i-00000",
			AppName: appDict["name"],
			Machine: i + 1,
			Type:    "python",
			Ip:      appDict["ip"],
			Status:  provision.StatusInstalling,
		}
	}
	update(units)
	for _, appDict := range appDicts {
		a := app.App{Name: appDict["name"]}
		err := a.Get()
		c.Assert(err, gocheck.IsNil)
		c.Assert(a.Units[0].Ip, gocheck.Equals, appDict["ip"])
	}
}
Exemple #9
0
func (s *S) TestUpdateWithDownMachine(c *gocheck.C) {
	a := app.App{Name: "barduscoapp"}
	err := s.conn.Apps().Insert(&a)
	c.Assert(err, gocheck.IsNil)
	units := []provision.Unit{
		{
			Name:    "i-00000zz8",
			AppName: "barduscoapp",
			Type:    "python",
			Machine: 2,
			Ip:      "",
			Status:  provision.StatusPending,
		},
	}
	update(units)
	err = a.Get()
	c.Assert(err, gocheck.IsNil)
}
Exemple #10
0
func (s *S) TestUpdateWithDownMachine(c *C) {
	a := app.App{Name: "barduscoapp"}
	err := db.Session.Apps().Insert(&a)
	c.Assert(err, IsNil)
	units := []provision.Unit{
		{
			Name:    "i-00000zz8",
			AppName: "barduscoapp",
			Type:    "python",
			Machine: 2,
			Ip:      "",
			Status:  provision.StatusPending,
		},
	}
	update(units)
	err = a.Get()
	c.Assert(err, IsNil)
	c.Assert(a.State, Equals, string(provision.StatusPending))
}
Exemple #11
0
func getAppOrError(name string, u *auth.User) (app.App, error) {
	app := app.App{Name: name}
	err := app.Get()
	if err != nil {
		return app, &errors.Http{Code: http.StatusNotFound, Message: fmt.Sprintf("App %s not found.", name)}
	}
	if !auth.CheckUserAccess(app.Teams, u) {
		return app, &errors.Http{Code: http.StatusForbidden, Message: "User does not have access to this app"}
	}
	return app, nil
}
Exemple #12
0
func (s *S) TestBindCallTheServiceAPIAndSetsEnvironmentVariableReturnedFromTheCall(c *gocheck.C) {
	ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte(`{"DATABASE_USER":"******","DATABASE_PASSWORD":"******"}`))
	}))
	defer ts.Close()
	srvc := service.Service{Name: "mysql", Endpoint: map[string]string{"production": ts.URL}}
	err := srvc.Create()
	c.Assert(err, gocheck.IsNil)
	defer s.conn.Services().Remove(bson.M{"_id": "mysql"})
	instance := service.ServiceInstance{
		Name:        "my-mysql",
		ServiceName: "mysql",
		Teams:       []string{s.team.Name},
	}
	err = instance.Create()
	c.Assert(err, gocheck.IsNil)
	defer s.conn.ServiceInstances().Remove(bson.M{"_id": "my-mysql"})
	a, err := createTestApp(s.conn, "painkiller", "", []string{s.team.Name}, []app.Unit{{Ip: "127.0.0.1"}})
	c.Assert(err, gocheck.IsNil)
	defer s.conn.Apps().Remove(bson.M{"name": a.Name})
	err = instance.BindApp(&a)
	c.Assert(err, gocheck.IsNil)
	newApp := app.App{Name: a.Name}
	err = newApp.Get()
	c.Assert(err, gocheck.IsNil)
	expectedEnv := map[string]bind.EnvVar{
		"DATABASE_USER": {
			Name:         "DATABASE_USER",
			Value:        "root",
			Public:       false,
			InstanceName: instance.Name,
		},
		"DATABASE_PASSWORD": {
			Name:         "DATABASE_PASSWORD",
			Value:        "s3cr3t",
			Public:       false,
			InstanceName: instance.Name,
		},
	}
	c.Assert(a.Env, gocheck.DeepEquals, expectedEnv)
}
Exemple #13
0
func appIsAvailable(w http.ResponseWriter, r *http.Request, t *auth.Token) error {
	app := app.App{Name: r.URL.Query().Get(":appname")}
	err := app.Get()
	if err != nil {
		return err
	}
	if !app.Available() {
		return fmt.Errorf("App must be available to receive pushs.")
	}
	w.WriteHeader(http.StatusOK)
	return nil
}
Exemple #14
0
// AppIsAvaliableHandler verify if the app.Unit().State() is
// started. If is started it returns 200 else returns 500 for
// status code.
func AppIsAvaliableHandler(w http.ResponseWriter, r *http.Request) error {
	app := app.App{Name: r.URL.Query().Get(":name")}
	err := app.Get()
	if err != nil {
		return err
	}
	if app.State != "started" {
		return fmt.Errorf("App must be started to receive pushs, but it is %q.", app.State)
	}
	w.WriteHeader(http.StatusOK)
	return nil
}
Exemple #15
0
func CloneRepositoryHandler(w http.ResponseWriter, r *http.Request) error {
	w.Header().Set("Content-Type", "text")
	instance := app.App{Name: r.URL.Query().Get(":name")}
	err := instance.Get()
	logWriter := LogWriter{&instance, w}
	if err != nil {
		return &errors.Http{Code: http.StatusNotFound, Message: fmt.Sprintf("App %s not found.", instance.Name)}
	}
	err = write(&logWriter, []byte("\n ---> Tsuru receiving push\n"))
	if err != nil {
		return err
	}
	err = write(&logWriter, []byte("\n ---> Replicating the application repository across units\n"))
	if err != nil {
		return err
	}
	out, err := repository.CloneOrPull(&instance) // should iterate over the machines
	if err != nil {
		return &errors.Http{Code: http.StatusInternalServerError, Message: string(out)}
	}
	err = write(&logWriter, out)
	if err != nil {
		return err
	}
	err = write(&logWriter, []byte("\n ---> Installing dependencies\n"))
	if err != nil {
		return err
	}
	err = instance.InstallDeps(&logWriter)
	if err != nil {
		return err
	}
	err = instance.Restart(&logWriter)
	if err != nil {
		return err
	}
	return write(&logWriter, []byte("\n ---> Deploy done!\n\n"))
}
Exemple #16
0
func ensureAppIsStarted(msg *queue.Message) (app.App, error) {
	a := app.App{Name: msg.Args[0]}
	err := a.Get()
	if err != nil {
		return a, fmt.Errorf("Error handling %q: app %q does not exist.", msg.Action, a.Name)
	}
	units := getUnits(&a, msg.Args[1:])
	if a.State != "started" || !units.Started() {
		format := "Error handling %q for the app %q:"
		switch a.State {
		case "error":
			format += " the app is in %q state."
			queue.Delete(msg)
		case "down":
			format += " the app is %s."
			queue.Delete(msg)
		default:
			format += ` The status of the app and all units should be "started" (the app is %q).`
		}
		return a, fmt.Errorf(format, msg.Action, a.Name, a.State)
	}
	return a, nil
}
Exemple #17
0
func (h *MessageHandler) ensureAppIsStarted(msg queue.Message) (app.App, error) {
	a := app.App{Name: msg.Args[0]}
	err := a.Get()
	if err != nil {
		return a, fmt.Errorf("Error handling %q: app %q does not exist.", msg.Action, a.Name)
	}
	units := h.getUnits(&a, msg.Args[1:])
	if a.State != "started" || !units.Started() {
		format := "Error handling %q for the app %q:"
		switch a.State {
		case "error":
			format += " the app is in %q state."
		case "down":
			format += " the app is %s."
		default:
			format += ` The status of the app and all units should be "started" (the app is %q).`
			time.Sleep(time.Duration(msg.Visits+1) * time.Second)
			h.server.PutBack(msg)
		}
		return a, fmt.Errorf(format, msg.Action, a.Name, a.State)
	}
	return a, nil
}
Exemple #18
0
func AddLogHandler(w http.ResponseWriter, r *http.Request) error {
	app := app.App{Name: r.URL.Query().Get(":name")}
	err := app.Get()
	if err != nil {
		return err
	}
	defer r.Body.Close()
	body, err := ioutil.ReadAll(r.Body)
	if err != nil {
		return err
	}
	var logs []string
	err = json.Unmarshal(body, &logs)
	for _, log := range logs {
		err := app.Log(log, "app")
		if err != nil {
			return err
		}
	}
	w.WriteHeader(http.StatusOK)
	return nil
}