Example #1
0
func (s *S) TestGetS3Endpoint(c *gocheck.C) {
	oldRegion, _ := config.Get("aws:s3:region-name")
	defer config.Set("aws:s3:region-name", oldRegion)
	config.Set("aws:s3:region-name", "myregion")
	edp, err := config.GetString("aws:s3:endpoint")
	c.Assert(err, gocheck.IsNil)
	locConst, err := config.GetBool("aws:s3:location-constraint")
	c.Assert(err, gocheck.IsNil)
	lwrCaseBucket, err := config.GetBool("aws:s3:lowercase-bucket")
	c.Assert(err, gocheck.IsNil)
	s3 := getS3Endpoint()
	c.Assert(s3.S3Endpoint, gocheck.Equals, edp)
	c.Assert(s3.S3LocationConstraint, gocheck.Equals, locConst)
	c.Assert(s3.S3LowercaseBucket, gocheck.Equals, lwrCaseBucket)
	c.Assert(s3.Region.Name, gocheck.Equals, "myregion")
}
Example #2
0
func (p *JujuProvisioner) elbSupport() bool {
	if p.elb == nil {
		elb, _ := config.GetBool("juju:use-elb")
		p.elb = &elb
	}
	return *p.elb
}
Example #3
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 S3 bucket for the app (if the bucket support is enabled)
//       4. Create the git repository using gandalf
//       5. Provision units within the provisioner
func CreateApp(app *App, units uint, teams []auth.Team) error {
	if units == 0 {
		return &errors.ValidationError{Message: "Cannot create app with 0 units."}
	}
	if len(teams) == 0 {
		return NoTeamsError{}
	}
	app.SetTeams(teams)
	if !app.isValid() {
		msg := "Invalid app name, your app should have at most 63 " +
			"characters, containing only lower case letters or numbers, " +
			"starting with a letter."
		return &errors.ValidationError{Message: msg}
	}
	actions := []*action.Action{&insertApp}
	useS3, _ := config.GetBool("bucket-support")
	if useS3 {
		actions = append(actions, &createIAMUserAction,
			&createIAMAccessKeyAction,
			&createBucketAction, &createUserPolicyAction)
	}
	actions = append(actions, &exportEnvironmentsAction,
		&createRepository, &provisionApp, &provisionAddUnits)
	pipeline := action.NewPipeline(actions...)
	err := pipeline.Execute(app, units)
	if err != nil {
		return &appCreationError{app: app.Name, err: err}
	}
	return nil
}
Example #4
0
func dockerCluster() *cluster.Cluster {
	cmutex.Lock()
	defer cmutex.Unlock()
	if dCluster == nil {
		if segregate, _ := config.GetBool("docker:segregate"); segregate {
			dCluster, _ = cluster.New(segScheduler)
		} else {
			clusterNodes = make(map[string]string)
			servers, _ := config.GetList("docker:servers")
			if len(servers) < 1 {
				log.Fatal(`Tsuru is misconfigured. Setting "docker:servers" is mandatory`)
			}
			nodes := make([]cluster.Node, len(servers))
			for index, server := range servers {
				id := fmt.Sprintf("server%d", index)
				node := cluster.Node{
					ID:      id,
					Address: server,
				}
				nodes[index] = node
				clusterNodes[id] = server
			}
			dCluster, _ = cluster.New(nil, nodes...)
		}
		if redisServer, err := config.GetString("docker:scheduler:redis-server"); err == nil {
			prefix, _ := config.GetString("docker:scheduler:redis-prefix")
			if password, err := config.GetString("docker:scheduler:redis-password"); err == nil {
				dCluster.SetStorage(storage.AuthenticatedRedis(redisServer, password, prefix))
			} else {
				dCluster.SetStorage(storage.Redis(redisServer, prefix))
			}
		}
	}
	return dCluster
}
Example #5
0
File: app.go Project: nemx/tsuru
// 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 S3 bucket for the app (if the bucket support is enabled)
//       4. Create the git repository using gandalf
//       5. 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.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}
	}
	actions := []*action.Action{&reserveUserApp, &createAppQuota, &insertApp}
	useS3, _ := config.GetBool("bucket-support")
	if useS3 {
		actions = append(actions, &createIAMUserAction,
			&createIAMAccessKeyAction,
			&createBucketAction, &createUserPolicyAction)
	}
	actions = append(actions, &exportEnvironmentsAction,
		&createRepository, &provisionApp)
	pipeline := action.NewPipeline(actions...)
	err = pipeline.Execute(app, user)
	if err != nil {
		return &AppCreationError{app: app.Name, Err: err}
	}
	return nil
}
Example #6
0
func (r elbRouter) AddBackend(name string) error {
	var err error
	options := elb.CreateLoadBalancer{
		Name: name,
		Listeners: []elb.Listener{
			{
				InstancePort:     80,
				InstanceProtocol: "HTTP",
				LoadBalancerPort: 80,
				Protocol:         "HTTP",
			},
		},
	}
	vpc, _ := config.GetBool("juju:elb-use-vpc")
	if vpc {
		options.Subnets, err = config.GetList("juju:elb-vpc-subnets")
		if err != nil {
			return err
		}
		options.SecurityGroups, err = config.GetList("juju:elb-vpc-secgroups")
		if err != nil {
			return err
		}
		options.Scheme = "internal"
	} else {
		options.AvailZones, err = config.GetList("juju:elb-avail-zones")
		if err != nil {
			return err
		}
	}
	_, err = r.elb().CreateLoadBalancer(&options)
	return router.Store(name, name)
}
Example #7
0
func (h elbInstanceHealer) checkInstances(names []string) ([]elbInstance, error) {
	if elbSupport, _ := config.GetBool("juju:use-elb"); !elbSupport {
		return nil, nil
	}
	lbs, err := h.describeLoadBalancers(names)
	if err != nil {
		return nil, err
	}
	var unhealthy []elbInstance
	description := "Instance has failed at least the UnhealthyThreshold number of health checks consecutively."
	state := "OutOfService"
	reasonCode := "Instance"
	for _, lb := range lbs {
		instances, err := h.describeInstancesHealth(lb)
		if err != nil {
			return nil, err
		}
		for _, instance := range instances {
			if instance.description == description &&
				instance.state == state &&
				instance.reasonCode == reasonCode {
				unhealthy = append(unhealthy, instance)
			}
		}
	}
	log.Printf("Found %d unhealthy instances.", len(unhealthy))
	return unhealthy, nil
}
Example #8
0
func (p *JujuProvisioner) elbSupport() bool {
	if p.elb == nil {
		p.elb = new(bool)
		if elb, err := config.GetBool("juju:use-elb"); err == nil {
			*p.elb = elb
		}
	}
	return *p.elb
}
Example #9
0
func getHostAddr(hostID string) string {
	var fullAddress string
	if seg, _ := config.GetBool("docker:segregate"); seg {
		node, _ := segScheduler.GetNode(hostID)
		fullAddress = node.Address
	} else {
		fullAddress = clusterNodes[hostID]
	}
	url, _ := url.Parse(fullAddress)
	host, _, _ := net.SplitHostPort(url.Host)
	return host
}
Example #10
0
File: log.go Project: nemx/tsuru
func Init() {
	debug, err := config.GetBool("debug")
	if err != nil {
		debug = false
	}
	logFileName, err := config.GetString("log:file")
	var logger Logger
	if err != nil {
		logger = NewSyslogLogger("tsr", debug)
	} else {
		logger = NewFileLogger(logFileName, debug)
	}
	SetLogger(logger)
}
Example #11
0
File: s3.go Project: JoeyFan/tsuru
func getS3Endpoint() *s3.S3 {
	regionName, _ := config.GetString("aws:s3:region-name")
	endpoint, err := config.GetString("aws:s3:endpoint")
	if err != nil {
		panic("FATAL: aws:s3:endpoint must be defined in configuration file.")
	}
	bucketEndpoint, _ := config.GetString("aws:s3:bucketEndpoint")
	locationConstraint, err := config.GetBool("aws:s3:location-constraint")
	if err != nil {
		panic("FATAL: aws:s3:location-constraint must be defined in configuration file.")
	}
	lowercaseBucket, err := config.GetBool("aws:s3:lowercase-bucket")
	if err != nil {
		panic("FATAL: aws:s3:lowercase-bucket must be defined in configuration file.")
	}
	region := aws.Region{
		Name:                 regionName,
		S3Endpoint:           endpoint,
		S3BucketEndpoint:     bucketEndpoint,
		S3LocationConstraint: locationConstraint,
		S3LowercaseBucket:    lowercaseBucket,
	}
	return s3.New(getAWSAuth(), region)
}
Example #12
0
// ForceDestroy destroys an app with force.
//
// Destroying an app is a process composed of four steps:
//
//       1. Destroy the bucket and S3 credentials (if bucket-support is
//       enabled).
//       2. Destroy the app unit using juju
//       3. Unbind all service instances from the app
//       4. Remove the app from the database
func ForceDestroy(app *App) error {
	gUrl := repository.GitServerUri()
	(&gandalf.Client{Endpoint: gUrl}).RemoveRepository(app.Name)
	useS3, _ := config.GetBool("bucket-support")
	if useS3 {
		destroyBucket(app)
	}
	if len(app.Units) > 0 {
		Provisioner.Destroy(app)
		app.unbind()
	}
	conn, err := db.Conn()
	if err != nil {
		return err
	}
	defer conn.Close()
	return conn.Apps().Remove(bson.M{"name": app.Name})
}
// ReadWriteURL formats the git ssh url and return it. If no remote is configured in
// gandalf.conf, this method panics.
func (r *Repository) ReadWriteURL() string {
	uid, err := config.GetString("uid")
	if err != nil {
		panic(err.Error())
	}
	remote := uid + "@%s:%s.git"
	if useSSH, _ := config.GetBool("git:ssh:use"); useSSH {
		port, err := config.GetString("git:ssh:port")
		if err == nil {
			remote = "ssh://" + uid + "@%s:" + port + "/%s.git"
		} else {
			remote = "ssh://" + uid + "@%s/%s.git"
		}
	}
	host, err := config.GetString("host")
	if err != nil {
		panic(err.Error())
	}
	return fmt.Sprintf(remote, host, r.Name)
}
Example #14
0
File: app.go Project: nemx/tsuru
// Delete deletes an app.
//
// Delete an app is a process composed of four steps:
//
//       1. Destroy the bucket and S3 credentials (if bucket-support is
//       enabled).
//       2. Destroy the app unit using juju
//       3. Unbind all service instances from the app
//       4. Remove the app from the database
func Delete(app *App) error {
	gURL := repository.ServerURL()
	(&gandalf.Client{Endpoint: gURL}).RemoveRepository(app.Name)
	useS3, _ := config.GetBool("bucket-support")
	if useS3 {
		destroyBucket(app)
	}
	if len(app.Units) > 0 {
		Provisioner.Destroy(app)
		app.unbind()
	}
	token := app.Env["TSURU_APP_TOKEN"].Value
	auth.DeleteToken(token)
	quota.Release(app.Owner, app.Name)
	conn, err := db.Conn()
	if err != nil {
		return err
	}
	defer conn.Close()
	quota.Delete(app.Name)
	return conn.Apps().Remove(bson.M{"name": app.Name})
}
Example #15
0
func dockerCluster() *cluster.Cluster {
	cmutex.Lock()
	defer cmutex.Unlock()
	var clusterStorage cluster.Storage
	if dCluster == nil {
		if redisServer, err := config.GetString("docker:scheduler:redis-server"); err == nil {
			prefix, _ := config.GetString("docker:scheduler:redis-prefix")
			if password, err := config.GetString("docker:scheduler:redis-password"); err == nil {
				clusterStorage = storage.AuthenticatedRedis(redisServer, password, prefix)
			} else {
				clusterStorage = storage.Redis(redisServer, prefix)
			}
		}
		var nodes []cluster.Node
		if segregate, _ := config.GetBool("docker:segregate"); segregate {
			dCluster, _ = cluster.New(segScheduler, clusterStorage)
		} else {
			nodes = getDockerServers()
			dCluster, _ = cluster.New(nil, clusterStorage, nodes...)
		}
	}
	return dCluster
}
Example #16
0
// RunServer starts Tsuru API server. The dry parameter indicates whether the
// server should run in dry mode, not starting the HTTP listener (for testing
// purposes).
func RunServer(dry bool) {
	log.Init()
	connString, err := config.GetString("database:url")
	if err != nil {
		fatal(err)
	}
	dbName, err := config.GetString("database:name")
	if err != nil {
		fatal(err)
	}
	fmt.Printf("Using the database %q from the server %q.\n\n", dbName, connString)

	m := pat.New()

	m.Get("/schema/app", authorizationRequiredHandler(appSchema))
	m.Get("/schema/service", authorizationRequiredHandler(serviceSchema))
	m.Get("/schema/services", authorizationRequiredHandler(servicesSchema))

	m.Get("/quota/:owner", authorizationRequiredHandler(quotaByOwner))

	m.Get("/services/instances", authorizationRequiredHandler(serviceInstances))
	m.Get("/services/instances/:name", authorizationRequiredHandler(serviceInstance))
	m.Del("/services/instances/:name", authorizationRequiredHandler(removeServiceInstance))
	m.Post("/services/instances", authorizationRequiredHandler(createServiceInstance))
	m.Put("/services/instances/:instance/:app", authorizationRequiredHandler(bindServiceInstance))
	m.Del("/services/instances/:instance/:app", authorizationRequiredHandler(unbindServiceInstance))
	m.Get("/services/instances/:instance/status", authorizationRequiredHandler(serviceInstanceStatus))

	m.Get("/services", authorizationRequiredHandler(serviceList))
	m.Post("/services", authorizationRequiredHandler(serviceCreate))
	m.Put("/services", authorizationRequiredHandler(serviceUpdate))
	m.Del("/services/:name", authorizationRequiredHandler(serviceDelete))
	m.Get("/services/:name", authorizationRequiredHandler(serviceInfo))
	m.Get("/services/:name/doc", authorizationRequiredHandler(serviceDoc))
	m.Put("/services/:name/doc", authorizationRequiredHandler(serviceAddDoc))
	m.Put("/services/:service/:team", authorizationRequiredHandler(grantServiceAccess))
	m.Del("/services/:service/:team", authorizationRequiredHandler(revokeServiceAccess))

	m.Del("/apps/:app", authorizationRequiredHandler(appDelete))
	m.Get("/apps/:app", authorizationRequiredHandler(appInfo))
	m.Post("/apps/:app/cname", authorizationRequiredHandler(setCName))
	m.Del("/apps/:app/cname", authorizationRequiredHandler(unsetCName))
	m.Post("/apps/:app/run", authorizationRequiredHandler(runCommand))
	m.Get("/apps/:app/restart", authorizationRequiredHandler(restart))
	m.Get("/apps/:app/env", authorizationRequiredHandler(getEnv))
	m.Post("/apps/:app/env", authorizationRequiredHandler(setEnv))
	m.Del("/apps/:app/env", authorizationRequiredHandler(unsetEnv))
	m.Get("/apps", authorizationRequiredHandler(appList))
	m.Post("/apps", authorizationRequiredHandler(createApp))
	m.Put("/apps/:app/units", authorizationRequiredHandler(addUnits))
	m.Del("/apps/:app/units", authorizationRequiredHandler(removeUnits))
	m.Put("/apps/:app/:team", authorizationRequiredHandler(grantAppAccess))
	m.Del("/apps/:app/:team", authorizationRequiredHandler(revokeAppAccess))
	m.Get("/apps/:app/log", authorizationRequiredHandler(appLog))
	m.Post("/apps/:app/log", authorizationRequiredHandler(addLog))

	m.Get("/platforms", authorizationRequiredHandler(platformList))

	// These handlers don't use :app on purpose. Using :app means that only
	// the token generate for the given app is valid, but these handlers
	// use a token generated for Gandalf.
	m.Get("/apps/:appname/available", authorizationRequiredHandler(appIsAvailable))
	m.Post("/apps/:appname/repository/clone", authorizationRequiredHandler(cloneRepository))

	if registrationEnabled, _ := config.GetBool("auth:user-registration"); registrationEnabled {
		m.Post("/users", handler(createUser))
	}

	m.Post("/users/:email/password", handler(resetPassword))
	m.Post("/users/:email/tokens", handler(login))
	m.Del("/users/tokens", authorizationRequiredHandler(logout))
	m.Put("/users/password", authorizationRequiredHandler(changePassword))
	m.Del("/users", authorizationRequiredHandler(removeUser))
	m.Get("/users/:email/keys", authorizationRequiredHandler(listKeys))
	m.Post("/users/keys", authorizationRequiredHandler(addKeyToUser))
	m.Del("/users/keys", authorizationRequiredHandler(removeKeyFromUser))

	m.Post("/tokens", adminRequiredHandler(generateAppToken))

	m.Del("/logs", adminRequiredHandler(logRemove))

	m.Get("/teams", authorizationRequiredHandler(teamList))
	m.Post("/teams", authorizationRequiredHandler(createTeam))
	m.Get("/teams/:name", authorizationRequiredHandler(getTeam))
	m.Del("/teams/:name", authorizationRequiredHandler(removeTeam))
	m.Put("/teams/:team/:user", authorizationRequiredHandler(addUserToTeam))
	m.Del("/teams/:team/:user", authorizationRequiredHandler(removeUserFromTeam))

	m.Get("/healers", authorizationRequiredHandler(healers))
	m.Get("/healers/:healer", authorizationRequiredHandler(healer))

	m.Put("/swap", authorizationRequiredHandler(swap))

	if !dry {
		provisioner, err := getProvisioner()
		if err != nil {
			fmt.Printf("Warning: configuration didn't declare a provisioner, using default provisioner.\n")
		}
		app.Provisioner, err = provision.Get(provisioner)
		if err != nil {
			fatal(err)
		}
		fmt.Printf("Using %q provisioner.\n\n", provisioner)

		listen, err := config.GetString("listen")
		if err != nil {
			fatal(err)
		}
		tls, _ := config.GetBool("use-tls")
		if tls {
			certFile, err := config.GetString("tls:cert-file")
			if err != nil {
				fatal(err)
			}
			keyFile, err := config.GetString("tls:key-file")
			if err != nil {
				fatal(err)
			}
			fmt.Printf("tsuru HTTP/TLS server listening at %s...\n", listen)
			fatal(http.ListenAndServeTLS(listen, certFile, keyFile, m))
		} else {
			listener, err := net.Listen("tcp", listen)
			if err != nil {
				fatal(err)
			}
			fmt.Printf("tsuru HTTP server listening at %s...\n", listen)
			http.Handle("/", m)
			fatal(http.Serve(listener, nil))
		}
	}
}
Example #17
0
func main() {
	logger, err := syslog.NewLogger(syslog.LOG_INFO, stdlog.LstdFlags)
	if err != nil {
		stdlog.Fatal(err)
	}
	log.SetLogger(logger)
	configFile := flag.String("config", "/etc/tsuru/tsuru.conf", "tsuru config file")
	dry := flag.Bool("dry", false, "dry-run: does not start the server (for testing purpose)")
	flag.Parse()
	err = config.ReadAndWatchConfigFile(*configFile)
	if err != nil {
		fatal(err)
	}
	connString, err := config.GetString("database:url")
	if err != nil {
		fatal(err)
	}
	dbName, err := config.GetString("database:name")
	if err != nil {
		fatal(err)
	}
	fmt.Printf("Using the database %q from the server %q.\n\n", dbName, connString)

	m := pat.New()

	m.Get("/services/instances", AuthorizationRequiredHandler(ServicesInstancesHandler))
	m.Post("/services/instances", AuthorizationRequiredHandler(CreateInstanceHandler))
	m.Put("/services/instances/:instance/:app", AuthorizationRequiredHandler(BindHandler))
	m.Del("/services/instances/:instance/:app", AuthorizationRequiredHandler(UnbindHandler))
	m.Del("/services/c/instances/:name", AuthorizationRequiredHandler(RemoveServiceInstanceHandler))
	m.Get("/services/instances/:instance/status", AuthorizationRequiredHandler(ServiceInstanceStatusHandler))

	m.Get("/services", AuthorizationRequiredHandler(ServicesHandler))
	m.Post("/services", AuthorizationRequiredHandler(CreateHandler))
	m.Put("/services", AuthorizationRequiredHandler(UpdateHandler))
	m.Del("/services/:name", AuthorizationRequiredHandler(DeleteHandler))
	m.Get("/services/:name", AuthorizationRequiredHandler(ServiceInfoHandler))
	m.Get("/services/c/:name/doc", AuthorizationRequiredHandler(Doc))
	m.Get("/services/:name/doc", AuthorizationRequiredHandler(GetDocHandler))
	m.Put("/services/:name/doc", AuthorizationRequiredHandler(AddDocHandler))
	m.Put("/services/:service/:team", AuthorizationRequiredHandler(GrantServiceAccessToTeamHandler))
	m.Del("/services/:service/:team", AuthorizationRequiredHandler(RevokeServiceAccessFromTeamHandler))

	m.Del("/apps/:name", AuthorizationRequiredHandler(appDelete))
	m.Get("/apps/:name/repository/clone", Handler(CloneRepositoryHandler))
	m.Get("/apps/:name/avaliable", Handler(AppIsAvailableHandler))
	m.Get("/apps/:name", AuthorizationRequiredHandler(AppInfo))
	m.Post("/apps/:name", AuthorizationRequiredHandler(setCName))
	m.Post("/apps/:name/run", AuthorizationRequiredHandler(RunCommand))
	m.Get("/apps/:name/restart", AuthorizationRequiredHandler(RestartHandler))
	m.Get("/apps/:name/env", AuthorizationRequiredHandler(GetEnv))
	m.Post("/apps/:name/env", AuthorizationRequiredHandler(SetEnv))
	m.Del("/apps/:name/env", AuthorizationRequiredHandler(UnsetEnv))
	m.Get("/apps", AuthorizationRequiredHandler(AppList))
	m.Post("/apps", AuthorizationRequiredHandler(CreateAppHandler))
	m.Put("/apps/:name/units", AuthorizationRequiredHandler(AddUnitsHandler))
	m.Del("/apps/:name/units", AuthorizationRequiredHandler(RemoveUnitsHandler))
	m.Put("/apps/:app/:team", AuthorizationRequiredHandler(GrantAccessToTeamHandler))
	m.Del("/apps/:app/:team", AuthorizationRequiredHandler(RevokeAccessFromTeamHandler))
	m.Get("/apps/:name/log", AuthorizationRequiredHandler(appLog))
	m.Post("/apps/:name/log", Handler(AddLogHandler))

	m.Post("/users", Handler(CreateUser))
	m.Post("/users/:email/tokens", Handler(Login))
	m.Put("/users/password", AuthorizationRequiredHandler(ChangePassword))
	m.Del("/users", AuthorizationRequiredHandler(RemoveUser))
	m.Post("/users/keys", AuthorizationRequiredHandler(AddKeyToUser))
	m.Del("/users/keys", AuthorizationRequiredHandler(RemoveKeyFromUser))

	m.Get("/teams", AuthorizationRequiredHandler(ListTeams))
	m.Post("/teams", AuthorizationRequiredHandler(CreateTeam))
	m.Del("/teams/:name", AuthorizationRequiredHandler(RemoveTeam))
	m.Put("/teams/:team/:user", AuthorizationRequiredHandler(AddUserToTeam))
	m.Del("/teams/:team/:user", AuthorizationRequiredHandler(RemoveUserFromTeam))

	m.Get("/healers", Handler(healers))
	m.Get("/healers/:healer", Handler(healer))

	if !*dry {
		provisioner, err := config.GetString("provisioner")
		if err != nil {
			fmt.Printf("Warning: %q didn't declare a provisioner, using default provisioner.\n", configFile)
			provisioner = "juju"
		}
		app.Provisioner, err = provision.Get(provisioner)
		if err != nil {
			fatal(err)
		}
		fmt.Printf("Using %q provisioner.\n\n", provisioner)

		listen, err := config.GetString("listen")
		if err != nil {
			fatal(err)
		}
		tls, _ := config.GetBool("use-tls")
		if tls {
			certFile, err := config.GetString("tls-cert-file")
			if err != nil {
				fatal(err)
			}
			keyFile, err := config.GetString("tls-key-file")
			if err != nil {
				fatal(err)
			}
			fmt.Printf("tsuru HTTP/TLS server listening at %s...\n", listen)
			fatal(http.ListenAndServeTLS(listen, certFile, keyFile, m))
		} else {
			fmt.Printf("tsuru HTTP server listening at %s...\n", listen)
			fatal(http.ListenAndServe(listen, m))
		}
	}
}
Example #18
0
func (m *ELBManager) vpc() bool {
	vpc, _ := config.GetBool("juju:elb-use-vpc")
	return vpc
}
Example #19
0
func RunServer(flags map[string]interface{}) {
	logger, err := syslog.NewLogger(syslog.LOG_INFO, stdlog.LstdFlags)
	if err != nil {
		stdlog.Fatal(err)
	}
	log.SetLogger(logger)
	configFile, ok := flags["config"].(string)
	if !ok {
		configFile = "/etc/tsuru/tsuru.conf"
	}
	dry, ok := flags["dry"].(bool)
	if !ok {
		dry = false
	}
	err = config.ReadAndWatchConfigFile(configFile)
	if err != nil {
		fatal(err)
	}
	connString, err := config.GetString("database:url")
	if err != nil {
		fatal(err)
	}
	dbName, err := config.GetString("database:name")
	if err != nil {
		fatal(err)
	}
	fmt.Printf("Using the database %q from the server %q.\n\n", dbName, connString)

	m := pat.New()

	m.Get("/schema/app", authorizationRequiredHandler(appSchema))

	m.Get("/services/instances", authorizationRequiredHandler(serviceInstances))
	m.Post("/services/instances", authorizationRequiredHandler(createServiceInstance))
	m.Put("/services/instances/:instance/:app", authorizationRequiredHandler(bindServiceInstance))
	m.Del("/services/instances/:instance/:app", authorizationRequiredHandler(unbindServiceInstance))
	m.Del("/services/c/instances/:name", authorizationRequiredHandler(removeServiceInstance))
	m.Get("/services/instances/:instance/status", authorizationRequiredHandler(serviceInstanceStatus))

	m.Get("/services", authorizationRequiredHandler(serviceList))
	m.Post("/services", authorizationRequiredHandler(serviceCreate))
	m.Put("/services", authorizationRequiredHandler(serviceUpdate))
	m.Del("/services/:name", authorizationRequiredHandler(serviceDelete))
	m.Get("/services/:name", authorizationRequiredHandler(serviceInfo))
	m.Get("/services/:name/doc", authorizationRequiredHandler(serviceDoc))
	m.Put("/services/:name/doc", authorizationRequiredHandler(serviceAddDoc))
	m.Put("/services/:service/:team", authorizationRequiredHandler(grantServiceAccess))
	m.Del("/services/:service/:team", authorizationRequiredHandler(revokeServiceAccess))

	m.Del("/apps/:app", authorizationRequiredHandler(appDelete))
	m.Get("/apps/:app", authorizationRequiredHandler(appInfo))
	m.Post("/apps/:app", authorizationRequiredHandler(setCName))
	m.Post("/apps/:app/run", authorizationRequiredHandler(runCommand))
	m.Get("/apps/:app/restart", authorizationRequiredHandler(restart))
	m.Get("/apps/:app/env", authorizationRequiredHandler(getEnv))
	m.Post("/apps/:app/env", authorizationRequiredHandler(setEnv))
	m.Del("/apps/:app/env", authorizationRequiredHandler(unsetEnv))
	m.Get("/apps", authorizationRequiredHandler(appList))
	m.Post("/apps", authorizationRequiredHandler(createApp))
	m.Put("/apps/:app/units", authorizationRequiredHandler(addUnits))
	m.Del("/apps/:app/units", authorizationRequiredHandler(removeUnits))
	m.Put("/apps/:app/:team", authorizationRequiredHandler(grantAppAccess))
	m.Del("/apps/:app/:team", authorizationRequiredHandler(revokeAppAccess))
	m.Get("/apps/:app/log", authorizationRequiredHandler(appLog))
	m.Post("/apps/:app/log", authorizationRequiredHandler(addLog))

	m.Get("/platforms", authorizationRequiredHandler(platformList))

	// These handlers don't use :app on purpose. Using :app means that only
	// the token generate for the given app is valid, but these handlers
	// use a token generated for Gandalf.
	m.Get("/apps/:appname/available", authorizationRequiredHandler(appIsAvailable))
	m.Get("/apps/:appname/repository/clone", authorizationRequiredHandler(cloneRepository))

	if registrationEnabled, _ := config.GetBool("auth:user-registration"); registrationEnabled {
		m.Post("/users", handler(createUser))
	}

	m.Post("/users/:email/password", handler(resetPassword))
	m.Post("/users/:email/tokens", handler(login))
	m.Del("/users/tokens", authorizationRequiredHandler(logout))
	m.Put("/users/password", authorizationRequiredHandler(changePassword))
	m.Del("/users", authorizationRequiredHandler(removeUser))
	m.Post("/users/keys", authorizationRequiredHandler(addKeyToUser))
	m.Del("/users/keys", authorizationRequiredHandler(removeKeyFromUser))

	m.Post("/tokens", adminRequiredHandler(generateAppToken))

	m.Get("/teams", authorizationRequiredHandler(teamList))
	m.Post("/teams", authorizationRequiredHandler(createTeam))
	m.Del("/teams/:name", authorizationRequiredHandler(removeTeam))
	m.Put("/teams/:team/:user", authorizationRequiredHandler(addUserToTeam))
	m.Del("/teams/:team/:user", authorizationRequiredHandler(removeUserFromTeam))

	m.Get("/healers", authorizationRequiredHandler(healers))
	m.Get("/healers/:healer", authorizationRequiredHandler(healer))

	if !dry {
		provisioner, err := config.GetString("provisioner")
		if err != nil {
			fmt.Printf("Warning: %q didn't declare a provisioner, using default provisioner.\n", configFile)
			provisioner = "juju"
		}
		app.Provisioner, err = provision.Get(provisioner)
		if err != nil {
			fatal(err)
		}
		fmt.Printf("Using %q provisioner.\n\n", provisioner)

		listen, err := config.GetString("listen")
		if err != nil {
			fatal(err)
		}
		tls, _ := config.GetBool("use-tls")
		if tls {
			certFile, err := config.GetString("tls-cert-file")
			if err != nil {
				fatal(err)
			}
			keyFile, err := config.GetString("tls-key-file")
			if err != nil {
				fatal(err)
			}
			fmt.Printf("tsuru HTTP/TLS server listening at %s...\n", listen)
			fatal(http.ListenAndServeTLS(listen, certFile, keyFile, m))
		} else {
			listener, err := net.Listen("tcp", listen)
			if err != nil {
				fatal(err)
			}
			fmt.Printf("tsuru HTTP server listening at %s...\n", listen)
			http.Handle("/", m)
			fatal(http.Serve(listener, nil))
		}
	}
}