Beispiel #1
0
// Run is the function that starts the collector. The dryMode parameter
// indicates whether the collector should loop forever or not.
//
// It assumes the configuration has already been defined (from a config file or
// memory).
func Run(dryMode bool) {
	log.Init()
	connString, err := config.GetString("database:url")
	if err != nil {
		connString = db.DefaultDatabaseURL
	}
	dbName, err := config.GetString("database:name")
	if err != nil {
		dbName = db.DefaultDatabaseName
	}

	fmt.Printf("Using the database %q from the server %q.\n\n", dbName, connString)
	if !dryMode {
		provisioner, err := config.GetString("provisioner")
		if err != nil {
			fmt.Println("Warning: configuration didn't declare a provisioner, using default provisioner.")
			provisioner = "docker"
		}
		app.Provisioner, err = provision.Get(provisioner)
		if err != nil {
			fatal(err)
		}
		fmt.Printf("Using %q provisioner.\n\n", provisioner)

		timer, err := config.GetInt("collector:ticker-time")
		if err != nil {
			timer = 60
		}
		ticker := time.Tick(time.Duration(timer) * time.Second)
		fmt.Println("tsuru collector agent started...")
		collect(ticker)
	}
}
Beispiel #2
0
// RunAdminServer starts tsuru administrative api
func RunAdminServer(dry bool) {
	log.Init()
	connString, err := config.GetString("database:url")
	if err != nil {
		connString = db.DefaultDatabaseURL
	}
	dbName, err := config.GetString("database:name")
	if err != nil {
		dbName = db.DefaultDatabaseName
	}
	fmt.Printf("Using the database %q from the server %q.\n\n", dbName, connString)
	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("admin-listen")
		if err != nil {
			fatal(err)
		}
		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))
	}
}
Beispiel #3
0
func main() {
	dry := flag.Bool("dry", false, "dry-run: does not start the server (for testing purpose)")
	configFile := flag.String("config", "/etc/gandalf.conf", "Gandalf configuration file")
	gVersion := flag.Bool("version", false, "Print version and exit")
	flag.Parse()
	if *gVersion {
		fmt.Printf("gandalf-webserver version %s\n", version)
		return
	}
	log.Debugf("Opening config file: %s ...\n", *configFile)
	err := config.ReadAndWatchConfigFile(*configFile)
	if err != nil {
		msg := `Could not open gandalf config file at %s (%s).
  For an example, see: gandalf/etc/gandalf.conf
  Note that you can specify a different config file with the --config option -- e.g.: --config=./etc/gandalf.conf`
		log.Fatalf(msg, *configFile, err)
	}
	log.Init()
	log.Debugf("Successfully read config file: %s\n", *configFile)
	router := api.SetupRouter()
	n := negroni.New()
	n.Use(api.NewLoggerMiddleware())
	n.Use(api.NewResponseHeaderMiddleware("Server", "gandalf-webserver/"+version))
	n.Use(api.NewResponseHeaderMiddleware("Cache-Control", "private, max-age=0"))
	n.Use(api.NewResponseHeaderMiddleware("Expires", "-1"))
	n.UseHandler(router)
	bind, err := config.GetString("bind")
	if err != nil {
		var perr error
		bind, perr = config.GetString("webserver:port")
		if perr != nil {
			panic(err)
		}
	}
	if !*dry {
		bareLocation, err := config.GetString("git:bare:location")
		if err != nil {
			panic("You should configure a git:bare:location for gandalf.")
		}
		fmt.Printf("Repository location: %s\n", bareLocation)
		fmt.Printf("gandalf-webserver %s listening on %s\n", version, bind)
		http.ListenAndServe(bind, router)
	}
}
Beispiel #4
0
func init() {
	log.Init()
}
Beispiel #5
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) http.Handler {
	log.Init()
	connString, err := config.GetString("database:url")
	if err != nil {
		connString = db.DefaultDatabaseURL
	}
	dbName, err := config.GetString("database:name")
	if err != nil {
		dbName = db.DefaultDatabaseName
	}
	fmt.Printf("Using mongodb database %q from the server %q.\n", dbName, connString)

	m := &delayedRouter{}

	for _, handler := range tsuruHandlerList {
		m.Add(handler.method, handler.path, handler.h)
	}

	if disableIndex, _ := config.GetBool("disable-index-page"); !disableIndex {
		m.Add("Get", "/", Handler(index))
	}
	m.Add("Get", "/info", Handler(info))

	m.Add("Get", "/services/instances", authorizationRequiredHandler(serviceInstances))
	m.Add("Get", "/services/instances/{name}", authorizationRequiredHandler(serviceInstance))
	m.Add("Delete", "/services/instances/{name}", authorizationRequiredHandler(removeServiceInstance))
	m.Add("Post", "/services/instances", authorizationRequiredHandler(createServiceInstance))
	m.Add("Put", "/services/instances/{instance}/{app}", authorizationRequiredHandler(bindServiceInstance))
	m.Add("Delete", "/services/instances/{instance}/{app}", authorizationRequiredHandler(unbindServiceInstance))
	m.Add("Get", "/services/instances/{instance}/status", authorizationRequiredHandler(serviceInstanceStatus))
	m.Add("Put", "/services/instances/permission/{instance}/{team}", authorizationRequiredHandler(serviceInstanceGrantTeam))
	m.Add("Delete", "/services/instances/permission/{instance}/{team}", authorizationRequiredHandler(serviceInstanceRevokeTeam))

	m.AddAll("/services/proxy/{instance}", authorizationRequiredHandler(serviceInstanceProxy))
	m.AddAll("/services/proxy/service/{service}", authorizationRequiredHandler(serviceProxy))

	m.Add("Get", "/services", authorizationRequiredHandler(serviceList))
	m.Add("Post", "/services", authorizationRequiredHandler(serviceCreate))
	m.Add("Put", "/services", authorizationRequiredHandler(serviceUpdate))
	m.Add("Delete", "/services/{name}", authorizationRequiredHandler(serviceDelete))
	m.Add("Get", "/services/{name}", authorizationRequiredHandler(serviceInfo))
	m.Add("Get", "/services/{name}/plans", authorizationRequiredHandler(servicePlans))
	m.Add("Get", "/services/{name}/doc", authorizationRequiredHandler(serviceDoc))
	m.Add("Put", "/services/{name}/doc", authorizationRequiredHandler(serviceAddDoc))
	m.Add("Put", "/services/{service}/team/{team}", authorizationRequiredHandler(grantServiceAccess))
	m.Add("Delete", "/services/{service}/team/{team}", authorizationRequiredHandler(revokeServiceAccess))

	m.Add("Delete", "/apps/{app}", authorizationRequiredHandler(appDelete))
	m.Add("Get", "/apps/{app}", authorizationRequiredHandler(appInfo))
	m.Add("Post", "/apps/{app}/cname", authorizationRequiredHandler(setCName))
	m.Add("Delete", "/apps/{app}/cname", authorizationRequiredHandler(unsetCName))
	m.Add("Post", "/apps/{app}/plan", authorizationRequiredHandler(changePlan))
	runHandler := authorizationRequiredHandler(runCommand)
	m.Add("Post", "/apps/{app}/run", runHandler)
	m.Add("Post", "/apps/{app}/restart", authorizationRequiredHandler(restart))
	m.Add("Post", "/apps/{app}/start", authorizationRequiredHandler(start))
	m.Add("Post", "/apps/{app}/stop", authorizationRequiredHandler(stop))
	m.Add("Get", "/apps/{appname}/quota", AdminRequiredHandler(getAppQuota))
	m.Add("Post", "/apps/{appname}/quota", AdminRequiredHandler(changeAppQuota))
	m.Add("Get", "/apps/{app}/env", authorizationRequiredHandler(getEnv))
	m.Add("Post", "/apps/{app}/env", authorizationRequiredHandler(setEnv))
	m.Add("Delete", "/apps/{app}/env", authorizationRequiredHandler(unsetEnv))
	m.Add("Get", "/apps", authorizationRequiredHandler(appList))
	m.Add("Post", "/apps", authorizationRequiredHandler(createApp))
	m.Add("Post", "/apps/{app}/team-owner", authorizationRequiredHandler(setTeamOwner))
	forceDeleteLockHandler := AdminRequiredHandler(forceDeleteLock)
	m.Add("Delete", "/apps/{app}/lock", forceDeleteLockHandler)
	m.Add("Put", "/apps/{app}/units", authorizationRequiredHandler(addUnits))
	m.Add("Delete", "/apps/{app}/units", authorizationRequiredHandler(removeUnits))
	registerUnitHandler := authorizationRequiredHandler(registerUnit)
	m.Add("Post", "/apps/{app}/units/register", registerUnitHandler)
	setUnitStatusHandler := authorizationRequiredHandler(setUnitStatus)
	m.Add("Post", "/apps/{app}/units/{unit}", setUnitStatusHandler)
	m.Add("Put", "/apps/{app}/teams/{team}", authorizationRequiredHandler(grantAppAccess))
	m.Add("Delete", "/apps/{app}/teams/{team}", authorizationRequiredHandler(revokeAppAccess))
	m.Add("Get", "/apps/{app}/log", authorizationRequiredHandler(appLog))
	logPostHandler := authorizationRequiredHandler(addLog)
	m.Add("Post", "/apps/{app}/log", logPostHandler)
	m.Add("Post", "/apps/{appname}/deploy/rollback", authorizationRequiredHandler(deployRollback))
	m.Add("Post", "/apps/{app}/pool", authorizationRequiredHandler(appChangePool))
	m.Add("Get", "/apps/{app}/metric/envs", authorizationRequiredHandler(appMetricEnvs))
	m.Add("Post", "/apps/{app}/routes", AdminRequiredHandler(appRebuildRoutes))

	m.Add("Post", "/units/status", authorizationRequiredHandler(setUnitsStatus))

	m.Add("Get", "/deploys", authorizationRequiredHandler(deploysList))
	m.Add("Get", "/deploys/{deploy}", authorizationRequiredHandler(deployInfo))

	m.Add("Get", "/platforms", authorizationRequiredHandler(platformList))
	m.Add("Post", "/platforms", AdminRequiredHandler(platformAdd))
	m.Add("Put", "/platforms/{name}", AdminRequiredHandler(platformUpdate))
	m.Add("Delete", "/platforms/{name}", AdminRequiredHandler(platformRemove))

	// 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.Add("Get", "/apps/{appname}/available", authorizationRequiredHandler(appIsAvailable))
	m.Add("Post", "/apps/{appname}/repository/clone", authorizationRequiredHandler(deploy))
	m.Add("Post", "/apps/{appname}/deploy", authorizationRequiredHandler(deploy))

	// Shell also doesn't use {app} on purpose. Middlewares don't play well
	// with websocket.
	m.Add("Get", "/apps/{appname}/shell", websocket.Handler(remoteShellHandler))

	m.Add("Get", "/users", AdminRequiredHandler(listUsers))
	m.Add("Post", "/users", Handler(createUser))
	m.Add("Get", "/users/info", authorizationRequiredHandler(userInfo))
	m.Add("Get", "/auth/scheme", Handler(authScheme))
	m.Add("Post", "/auth/login", Handler(login))
	m.Add("Post", "/users/{email}/password", Handler(resetPassword))
	m.Add("Post", "/users/{email}/tokens", Handler(login))
	m.Add("Get", "/users/{email}/quota", AdminRequiredHandler(getUserQuota))
	m.Add("Post", "/users/{email}/quota", AdminRequiredHandler(changeUserQuota))
	m.Add("Delete", "/users/tokens", authorizationRequiredHandler(logout))
	m.Add("Put", "/users/password", authorizationRequiredHandler(changePassword))
	m.Add("Delete", "/users", authorizationRequiredHandler(removeUser))
	m.Add("Get", "/users/keys", authorizationRequiredHandler(listKeys))
	m.Add("Post", "/users/keys", authorizationRequiredHandler(addKeyToUser))
	m.Add("Delete", "/users/keys", authorizationRequiredHandler(removeKeyFromUser))
	m.Add("Get", "/users/api-key", authorizationRequiredHandler(showAPIToken))
	m.Add("Post", "/users/api-key", authorizationRequiredHandler(regenerateAPIToken))

	m.Add("Delete", "/logs", AdminRequiredHandler(logRemove))
	m.Add("Get", "/logs", websocket.Handler(addLogs))

	m.Add("Get", "/teams", authorizationRequiredHandler(teamList))
	m.Add("Post", "/teams", authorizationRequiredHandler(createTeam))
	m.Add("Get", "/teams/{name}", authorizationRequiredHandler(getTeam))
	m.Add("Delete", "/teams/{name}", authorizationRequiredHandler(removeTeam))
	m.Add("Put", "/teams/{team}/{user}", authorizationRequiredHandler(addUserToTeam))
	m.Add("Delete", "/teams/{team}/{user}", authorizationRequiredHandler(removeUserFromTeam))

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

	m.Add("Get", "/healthcheck/", http.HandlerFunc(healthcheck))

	m.Add("Get", "/iaas/machines", AdminRequiredHandler(machinesList))
	m.Add("Delete", "/iaas/machines/{machine_id}", AdminRequiredHandler(machineDestroy))
	m.Add("Get", "/iaas/templates", AdminRequiredHandler(templatesList))
	m.Add("Post", "/iaas/templates", AdminRequiredHandler(templateCreate))
	m.Add("Put", "/iaas/templates/{template_name}", AdminRequiredHandler(templateUpdate))
	m.Add("Delete", "/iaas/templates/{template_name}", AdminRequiredHandler(templateDestroy))

	m.Add("Get", "/plans", authorizationRequiredHandler(listPlans))
	m.Add("Post", "/plans", AdminRequiredHandler(addPlan))
	m.Add("Delete", "/plans/{planname}", AdminRequiredHandler(removePlan))
	m.Add("Get", "/plans/routers", AdminRequiredHandler(listRouters))

	m.Add("Get", "/debug/goroutines", AdminRequiredHandler(dumpGoroutines))

	m.Add("Get", "/pools", authorizationRequiredHandler(listPoolsToUser))
	m.Add("Get", "/pool", AdminRequiredHandler(listPoolHandler))
	m.Add("Post", "/pool", AdminRequiredHandler(addPoolHandler))
	m.Add("Delete", "/pool", AdminRequiredHandler(removePoolHandler))
	m.Add("Post", "/pool/{name}", AdminRequiredHandler(poolUpdateHandler))
	m.Add("Post", "/pool/{name}/team", AdminRequiredHandler(addTeamToPoolHandler))
	m.Add("Delete", "/pool/{name}/team", AdminRequiredHandler(removeTeamToPoolHandler))

	m.Add("Get", "/debug/pprof/", AdminRequiredHandler(indexHandler))
	m.Add("Get", "/debug/pprof/cmdline", AdminRequiredHandler(cmdlineHandler))
	m.Add("Get", "/debug/pprof/profile", AdminRequiredHandler(profileHandler))
	m.Add("Get", "/debug/pprof/symbol", AdminRequiredHandler(symbolHandler))
	m.Add("Get", "/debug/pprof/heap", AdminRequiredHandler(indexHandler))
	m.Add("Get", "/debug/pprof/goroutine", AdminRequiredHandler(indexHandler))
	m.Add("Get", "/debug/pprof/threadcreate", AdminRequiredHandler(indexHandler))
	m.Add("Get", "/debug/pprof/block", AdminRequiredHandler(indexHandler))

	n := negroni.New()
	n.Use(negroni.NewRecovery())
	n.Use(newLoggerMiddleware())
	n.UseHandler(m)
	n.Use(negroni.HandlerFunc(contextClearerMiddleware))
	n.Use(negroni.HandlerFunc(flushingWriterMiddleware))
	n.Use(negroni.HandlerFunc(errorHandlingMiddleware))
	n.Use(negroni.HandlerFunc(setVersionHeadersMiddleware))
	n.Use(negroni.HandlerFunc(authTokenMiddleware))
	n.Use(&appLockMiddleware{excludedHandlers: []http.Handler{
		logPostHandler,
		runHandler,
		forceDeleteLockHandler,
		registerUnitHandler,
		setUnitStatusHandler,
	}})
	n.UseHandler(http.HandlerFunc(runDelayedHandler))

	if !dry {
		var startupMessage string
		routers, err := router.List()
		if err != nil {
			fatal(err)
		}
		for _, routerDesc := range routers {
			var r router.Router
			r, err = router.Get(routerDesc.Name)
			if err != nil {
				fatal(err)
			}
			fmt.Printf("Registered router %q", routerDesc.Name)
			if messageRouter, ok := r.(router.MessageRouter); ok {
				startupMessage, err = messageRouter.StartupMessage()
				if err == nil && startupMessage != "" {
					fmt.Printf(": %s", startupMessage)
				}
			}
			fmt.Println()
		}
		defaultRouter, _ := config.GetString("docker:router")
		fmt.Printf("Default router is %q.\n", defaultRouter)
		repoManager, err := config.GetString("repo-manager")
		if err != nil {
			repoManager = "gandalf"
			fmt.Println("Warning: configuration didn't declare a repository manager, using default manager.")
		}
		fmt.Printf("Using %q repository manager.\n", repoManager)
		provisioner, err := getProvisioner()
		if err != nil {
			fmt.Println("Warning: configuration didn't declare a provisioner, using default provisioner.")
		}
		app.Provisioner, err = provision.Get(provisioner)
		if err != nil {
			fatal(err)
		}
		fmt.Printf("Using %q provisioner.\n", provisioner)
		if initializableProvisioner, ok := app.Provisioner.(provision.InitializableProvisioner); ok {
			err = initializableProvisioner.Initialize()
			if err != nil {
				fatal(err)
			}
		}
		if messageProvisioner, ok := app.Provisioner.(provision.MessageProvisioner); ok {
			startupMessage, err = messageProvisioner.StartupMessage()
			if err == nil && startupMessage != "" {
				fmt.Print(startupMessage)
			}
		}
		scheme, err := getAuthScheme()
		if err != nil {
			fmt.Printf("Warning: configuration didn't declare auth:scheme, using default scheme.\n")
		}
		app.AuthScheme, err = auth.GetScheme(scheme)
		if err != nil {
			fatal(err)
		}
		fmt.Printf("Using %q auth scheme.\n", scheme)
		fmt.Println("Checking components status:")
		results := hc.Check()
		for _, result := range results {
			if result.Status != hc.HealthCheckOK {
				fmt.Printf("    WARNING: %q is not working: %s\n", result.Name, result.Status)
			}
		}
		fmt.Println("    Components checked.")
		listen, err := config.GetString("listen")
		if err != nil {
			fatal(err)
		}
		shutdownChan := make(chan bool)
		shutdownTimeout, _ := config.GetInt("shutdown-timeout")
		if shutdownTimeout == 0 {
			shutdownTimeout = 10 * 60
		}
		idleTracker := newIdleTracker()
		shutdown.Register(idleTracker)
		shutdown.Register(&logTracker)
		readTimeout, _ := config.GetInt("server:read-timeout")
		writeTimeout, _ := config.GetInt("server:write-timeout")
		srv := &graceful.Server{
			Timeout: time.Duration(shutdownTimeout) * time.Second,
			Server: &http.Server{
				ReadTimeout:  time.Duration(readTimeout) * time.Second,
				WriteTimeout: time.Duration(writeTimeout) * time.Second,
				Addr:         listen,
				Handler:      n,
			},
			ConnState: func(conn net.Conn, state http.ConnState) {
				idleTracker.trackConn(conn, state)
			},
			ShutdownInitiated: func() {
				fmt.Println("tsuru is shutting down, waiting for pending connections to finish.")
				handlers := shutdown.All()
				wg := sync.WaitGroup{}
				for _, h := range handlers {
					wg.Add(1)
					go func(h shutdown.Shutdownable) {
						defer wg.Done()
						fmt.Printf("running shutdown handler for %v...\n", h)
						h.Shutdown()
						fmt.Printf("running shutdown handler for %v. DONE.\n", h)
					}(h)
				}
				wg.Wait()
				close(shutdownChan)
			},
		}
		tls, _ := config.GetBool("use-tls")
		if tls {
			var (
				certFile string
				keyFile  string
			)
			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)
			err = srv.ListenAndServeTLS(certFile, keyFile)
		} else {
			fmt.Printf("tsuru HTTP server listening at %s...\n", listen)
			err = srv.ListenAndServe()
		}
		if err != nil {
			fmt.Printf("Listening stopped: %s\n", err)
		}
		<-shutdownChan
	}
	return n
}
Beispiel #6
0
func (s *CallerSuite) SetUpSuite(c *gocheck.C) {
	log.Init()
}
// 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) http.Handler {
	log.Init()
	connString, err := config.GetString("database:url")
	if err != nil {
		connString = db.DefaultDatabaseURL
	}
	dbName, err := config.GetString("database:name")
	if err != nil {
		dbName = db.DefaultDatabaseName
	}
	fmt.Printf("Using the database %q from the server %q.\n\n", dbName, connString)

	m := &delayedRouter{}

	for _, handler := range tsuruHandlerList {
		m.Add(handler.method, handler.path, handler.h)
	}

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

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

	m.AddAll("/services/proxy/{instance}", authorizationRequiredHandler(serviceProxy))

	m.Add("Get", "/services", authorizationRequiredHandler(serviceList))
	m.Add("Post", "/services", authorizationRequiredHandler(serviceCreate))
	m.Add("Put", "/services", authorizationRequiredHandler(serviceUpdate))
	m.Add("Delete", "/services/{name}", authorizationRequiredHandler(serviceDelete))
	m.Add("Get", "/services/{name}", authorizationRequiredHandler(serviceInfo))
	m.Add("Get", "/services/{name}/plans", authorizationRequiredHandler(servicePlans))
	m.Add("Get", "/services/{name}/doc", authorizationRequiredHandler(serviceDoc))
	m.Add("Put", "/services/{name}/doc", authorizationRequiredHandler(serviceAddDoc))
	m.Add("Put", "/services/{service}/{team}", authorizationRequiredHandler(grantServiceAccess))
	m.Add("Delete", "/services/{service}/{team}", authorizationRequiredHandler(revokeServiceAccess))

	m.Add("Delete", "/apps/{app}", authorizationRequiredHandler(appDelete))
	m.Add("Get", "/apps/{app}", authorizationRequiredHandler(appInfo))
	m.Add("Post", "/apps/{app}/cname", authorizationRequiredHandler(setCName))
	m.Add("Delete", "/apps/{app}/cname", authorizationRequiredHandler(unsetCName))
	runHandler := authorizationRequiredHandler(runCommand)
	m.Add("Post", "/apps/{app}/run", runHandler)
	m.Add("Post", "/apps/{app}/restart", authorizationRequiredHandler(restart))
	m.Add("Post", "/apps/{app}/start", authorizationRequiredHandler(start))
	m.Add("Post", "/apps/{app}/stop", authorizationRequiredHandler(stop))
	m.Add("Get", "/apps/{app}/env", authorizationRequiredHandler(getEnv))
	m.Add("Post", "/apps/{app}/env", authorizationRequiredHandler(setEnv))
	m.Add("Delete", "/apps/{app}/env", authorizationRequiredHandler(unsetEnv))
	m.Add("Get", "/apps", authorizationRequiredHandler(appList))
	m.Add("Post", "/apps", authorizationRequiredHandler(createApp))
	m.Add("Put", "/apps/{app}/units", authorizationRequiredHandler(addUnits))
	m.Add("Delete", "/apps/{app}/units", authorizationRequiredHandler(removeUnits))
	m.Add("Post", "/apps/{app}/units/{unit}", authorizationRequiredHandler(setUnitStatus))
	m.Add("Put", "/apps/{app}/{team}", authorizationRequiredHandler(grantAppAccess))
	m.Add("Delete", "/apps/{app}/{team}", authorizationRequiredHandler(revokeAppAccess))
	m.Add("Get", "/apps/{app}/log", authorizationRequiredHandler(appLog))
	logPostHandler := authorizationRequiredHandler(addLog)
	m.Add("Post", "/apps/{app}/log", logPostHandler)

	m.Add("Get", "/deploys", AdminRequiredHandler(deploysList))
	m.Add("Get", "/deploys/{deploy}", AdminRequiredHandler(deployInfo))

	m.Add("Get", "/platforms", authorizationRequiredHandler(platformList))
	m.Add("Post", "/platforms", AdminRequiredHandler(platformAdd))
	m.Add("Put", "/platforms/{name}", AdminRequiredHandler(platformUpdate))

	// 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.Add("Get", "/apps/{appname}/available", authorizationRequiredHandler(appIsAvailable))
	m.Add("Post", "/apps/{appname}/repository/clone", authorizationRequiredHandler(deploy))
	m.Add("Post", "/apps/{appname}/deploy", authorizationRequiredHandler(deploy))

	m.Add("Post", "/users", Handler(createUser))
	m.Add("Get", "/auth/scheme", Handler(authScheme))
	m.Add("Post", "/auth/login", Handler(login))
	m.Add("Post", "/users/{email}/password", Handler(resetPassword))
	m.Add("Post", "/users/{email}/tokens", Handler(login))
	m.Add("Delete", "/users/tokens", authorizationRequiredHandler(logout))
	m.Add("Put", "/users/password", authorizationRequiredHandler(changePassword))
	m.Add("Delete", "/users", authorizationRequiredHandler(removeUser))
	m.Add("Get", "/users/{email}/keys", authorizationRequiredHandler(listKeys))
	m.Add("Post", "/users/keys", authorizationRequiredHandler(addKeyToUser))
	m.Add("Delete", "/users/keys", authorizationRequiredHandler(removeKeyFromUser))

	m.Add("Post", "/tokens", AdminRequiredHandler(generateAppToken))

	m.Add("Delete", "/logs", AdminRequiredHandler(logRemove))

	m.Add("Get", "/teams", authorizationRequiredHandler(teamList))
	m.Add("Post", "/teams", authorizationRequiredHandler(createTeam))
	m.Add("Get", "/teams/{name}", authorizationRequiredHandler(getTeam))
	m.Add("Delete", "/teams/{name}", authorizationRequiredHandler(removeTeam))
	m.Add("Put", "/teams/{team}/{user}", authorizationRequiredHandler(addUserToTeam))
	m.Add("Delete", "/teams/{team}/{user}", authorizationRequiredHandler(removeUserFromTeam))

	m.Add("Get", "/healers", authorizationRequiredHandler(healers))
	m.Add("Get", "/healers/{healer}", authorizationRequiredHandler(healer))

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

	m.Add("Get", "/healthcheck/", http.HandlerFunc(healthcheck))

	m.Add("Get", "/iaas/machines", AdminRequiredHandler(machinesList))
	m.Add("Delete", "/iaas/machines/{machine_id}", AdminRequiredHandler(machineDestroy))

	n := negroni.New()
	n.Use(negroni.NewRecovery())
	n.Use(negroni.NewLogger())
	n.UseHandler(m)
	n.Use(negroni.HandlerFunc(contextClearerMiddleware))
	n.Use(negroni.HandlerFunc(flushingWriterMiddleware))
	n.Use(negroni.HandlerFunc(errorHandlingMiddleware))
	n.Use(negroni.HandlerFunc(setVersionHeadersMiddleware))
	n.Use(negroni.HandlerFunc(authTokenMiddleware))
	n.Use(&appLockMiddleware{excludedHandlers: []http.Handler{
		logPostHandler,
		runHandler,
	}})
	n.UseHandler(http.HandlerFunc(runDelayedHandler))

	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)
		scheme, err := getAuthScheme()
		if err != nil {
			fmt.Printf("Warning: configuration didn't declare a auth:scheme, using default scheme.\n")
		}
		app.AuthScheme, err = auth.GetScheme(scheme)
		if err != nil {
			fatal(err)
		}
		fmt.Printf("Using %q auth scheme.\n\n", scheme)
		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, n))
		} else {
			listener, err := net.Listen("tcp", listen)
			if err != nil {
				fatal(err)
			}
			fmt.Printf("tsuru HTTP server listening at %s...\n", listen)
			http.Handle("/", n)
			fatal(http.Serve(listener, nil))
		}
	}
	return n
}
Beispiel #8
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 {
		connString = db.DefaultDatabaseURL
	}
	dbName, err := config.GetString("database:name")
	if err != nil {
		dbName = db.DefaultDatabaseName
	}
	fmt.Printf("Using the database %q from the server %q.\n\n", dbName, connString)

	m := pat.New()

	for _, handler := range tsuruHandlerList {
		m.Add(handler.method, handler.path, handler.h)
	}

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

	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/plans", authorizationRequiredHandler(servicePlans))
	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/start", authorizationRequiredHandler(start))
	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("/deploys", AdminRequiredHandler(deploysList))

	m.Get("/platforms", authorizationRequiredHandler(platformList))
	m.Put("/platforms/add", AdminRequiredHandler(platformAdd))

	// 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(deploy))
	m.Post("/apps/:appname/deploy", authorizationRequiredHandler(deploy))

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

	m.Get("/healthcheck/", http.HandlerFunc(healthcheck))

	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))
		}
	}
}
Beispiel #9
0
func (c *healerCmd) Run(context *cmd.Context, client *cmd.Client) error {
	log.Init()
	heal.RegisterHealerTicker(time.Tick(time.Minute*15), c.host)
	heal.HealTicker(time.Tick(time.Minute))
	return nil
}
Beispiel #10
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) http.Handler {
	log.Init()
	connString, err := config.GetString("database:url")
	if err != nil {
		connString = db.DefaultDatabaseURL
	}
	dbName, err := config.GetString("database:name")
	if err != nil {
		dbName = db.DefaultDatabaseName
	}
	if !dry {
		fmt.Printf("Using mongodb database %q from the server %q.\n", dbName, connString)
	}

	m := apiRouter.NewRouter()

	for _, handler := range tsuruHandlerList {
		m.Add("1.0", handler.method, handler.path, handler.h)
	}

	if disableIndex, _ := config.GetBool("disable-index-page"); !disableIndex {
		m.Add("1.0", "Get", "/", Handler(index))
	}
	m.Add("1.0", "Get", "/info", Handler(info))

	m.Add("1.0", "Get", "/services/instances", AuthorizationRequiredHandler(serviceInstances))
	m.Add("1.0", "Get", "/services/{service}/instances/{instance}", AuthorizationRequiredHandler(serviceInstance))
	m.Add("1.0", "Delete", "/services/{service}/instances/{instance}", AuthorizationRequiredHandler(removeServiceInstance))
	m.Add("1.0", "Post", "/services/{service}/instances", AuthorizationRequiredHandler(createServiceInstance))
	m.Add("1.0", "Put", "/services/{service}/instances/{instance}", AuthorizationRequiredHandler(updateServiceInstance))
	m.Add("1.0", "Put", "/services/{service}/instances/{instance}/{app}", AuthorizationRequiredHandler(bindServiceInstance))
	m.Add("1.0", "Delete", "/services/{service}/instances/{instance}/{app}", AuthorizationRequiredHandler(unbindServiceInstance))
	m.Add("1.0", "Get", "/services/{service}/instances/{instance}/status", AuthorizationRequiredHandler(serviceInstanceStatus))
	m.Add("1.0", "Put", "/services/{service}/instances/permission/{instance}/{team}", AuthorizationRequiredHandler(serviceInstanceGrantTeam))
	m.Add("1.0", "Delete", "/services/{service}/instances/permission/{instance}/{team}", AuthorizationRequiredHandler(serviceInstanceRevokeTeam))

	m.AddAll("1.0", "/services/{service}/proxy/{instance}", AuthorizationRequiredHandler(serviceInstanceProxy))
	m.AddAll("1.0", "/services/proxy/service/{service}", AuthorizationRequiredHandler(serviceProxy))

	m.Add("1.0", "Get", "/services", AuthorizationRequiredHandler(serviceList))
	m.Add("1.0", "Post", "/services", AuthorizationRequiredHandler(serviceCreate))
	m.Add("1.0", "Put", "/services/{name}", AuthorizationRequiredHandler(serviceUpdate))
	m.Add("1.0", "Delete", "/services/{name}", AuthorizationRequiredHandler(serviceDelete))
	m.Add("1.0", "Get", "/services/{name}", AuthorizationRequiredHandler(serviceInfo))
	m.Add("1.0", "Get", "/services/{name}/plans", AuthorizationRequiredHandler(servicePlans))
	m.Add("1.0", "Get", "/services/{name}/doc", AuthorizationRequiredHandler(serviceDoc))
	m.Add("1.0", "Put", "/services/{name}/doc", AuthorizationRequiredHandler(serviceAddDoc))
	m.Add("1.0", "Put", "/services/{service}/team/{team}", AuthorizationRequiredHandler(grantServiceAccess))
	m.Add("1.0", "Delete", "/services/{service}/team/{team}", AuthorizationRequiredHandler(revokeServiceAccess))

	m.Add("1.0", "Delete", "/apps/{app}", AuthorizationRequiredHandler(appDelete))
	m.Add("1.0", "Get", "/apps/{app}", AuthorizationRequiredHandler(appInfo))
	m.Add("1.0", "Post", "/apps/{app}/cname", AuthorizationRequiredHandler(setCName))
	m.Add("1.0", "Delete", "/apps/{app}/cname", AuthorizationRequiredHandler(unsetCName))
	runHandler := AuthorizationRequiredHandler(runCommand)
	m.Add("1.0", "Post", "/apps/{app}/run", runHandler)
	m.Add("1.0", "Post", "/apps/{app}/restart", AuthorizationRequiredHandler(restart))
	m.Add("1.0", "Post", "/apps/{app}/start", AuthorizationRequiredHandler(start))
	m.Add("1.0", "Post", "/apps/{app}/stop", AuthorizationRequiredHandler(stop))
	m.Add("1.0", "Post", "/apps/{app}/sleep", AuthorizationRequiredHandler(sleep))
	m.Add("1.0", "Get", "/apps/{appname}/quota", AuthorizationRequiredHandler(getAppQuota))
	m.Add("1.0", "Put", "/apps/{appname}/quota", AuthorizationRequiredHandler(changeAppQuota))
	m.Add("1.0", "Put", "/apps/{appname}", AuthorizationRequiredHandler(updateApp))
	m.Add("1.0", "Get", "/apps/{app}/env", AuthorizationRequiredHandler(getEnv))
	m.Add("1.0", "Post", "/apps/{app}/env", AuthorizationRequiredHandler(setEnv))
	m.Add("1.0", "Delete", "/apps/{app}/env", AuthorizationRequiredHandler(unsetEnv))
	m.Add("1.0", "Get", "/apps", AuthorizationRequiredHandler(appList))
	m.Add("1.0", "Post", "/apps", AuthorizationRequiredHandler(createApp))
	forceDeleteLockHandler := AuthorizationRequiredHandler(forceDeleteLock)
	m.Add("1.0", "Delete", "/apps/{app}/lock", forceDeleteLockHandler)
	m.Add("1.0", "Put", "/apps/{app}/units", AuthorizationRequiredHandler(addUnits))
	m.Add("1.0", "Delete", "/apps/{app}/units", AuthorizationRequiredHandler(removeUnits))
	registerUnitHandler := AuthorizationRequiredHandler(registerUnit)
	m.Add("1.0", "Post", "/apps/{app}/units/register", registerUnitHandler)
	setUnitStatusHandler := AuthorizationRequiredHandler(setUnitStatus)
	m.Add("1.0", "Post", "/apps/{app}/units/{unit}", setUnitStatusHandler)
	m.Add("1.0", "Put", "/apps/{app}/teams/{team}", AuthorizationRequiredHandler(grantAppAccess))
	m.Add("1.0", "Delete", "/apps/{app}/teams/{team}", AuthorizationRequiredHandler(revokeAppAccess))
	m.Add("1.0", "Get", "/apps/{app}/log", AuthorizationRequiredHandler(appLog))
	logPostHandler := AuthorizationRequiredHandler(addLog)
	m.Add("1.0", "Post", "/apps/{app}/log", logPostHandler)
	m.Add("1.0", "Post", "/apps/{appname}/deploy/rollback", AuthorizationRequiredHandler(deployRollback))
	m.Add("1.0", "Get", "/apps/{app}/metric/envs", AuthorizationRequiredHandler(appMetricEnvs))
	m.Add("1.0", "Post", "/apps/{app}/routes", AuthorizationRequiredHandler(appRebuildRoutes))

	m.Add("1.0", "Post", "/node/status", AuthorizationRequiredHandler(setNodeStatus))

	m.Add("1.0", "Get", "/deploys", AuthorizationRequiredHandler(deploysList))
	m.Add("1.0", "Get", "/deploys/{deploy}", AuthorizationRequiredHandler(deployInfo))

	m.Add("1.1", "Get", "/events", AuthorizationRequiredHandler(eventList))
	m.Add("1.1", "Get", "/events/kinds", AuthorizationRequiredHandler(kindList))
	m.Add("1.1", "Get", "/events/{uuid}", AuthorizationRequiredHandler(eventInfo))
	m.Add("1.1", "Post", "/events/{uuid}/cancel", AuthorizationRequiredHandler(eventCancel))

	m.Add("1.0", "Get", "/platforms", AuthorizationRequiredHandler(platformList))
	m.Add("1.0", "Post", "/platforms", AuthorizationRequiredHandler(platformAdd))
	m.Add("1.0", "Put", "/platforms/{name}", AuthorizationRequiredHandler(platformUpdate))
	m.Add("1.0", "Delete", "/platforms/{name}", AuthorizationRequiredHandler(platformRemove))

	// 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.Add("1.0", "Post", "/apps/{appname}/repository/clone", AuthorizationRequiredHandler(deploy))
	m.Add("1.0", "Post", "/apps/{appname}/deploy", AuthorizationRequiredHandler(deploy))
	diffDeployHandler := AuthorizationRequiredHandler(diffDeploy)
	m.Add("1.0", "Post", "/apps/{appname}/diff", diffDeployHandler)

	// Shell also doesn't use {app} on purpose. Middlewares don't play well
	// with websocket.
	m.Add("1.0", "Get", "/apps/{appname}/shell", websocket.Handler(remoteShellHandler))

	m.Add("1.0", "Get", "/users", AuthorizationRequiredHandler(listUsers))
	m.Add("1.0", "Post", "/users", Handler(createUser))
	m.Add("1.0", "Get", "/users/info", AuthorizationRequiredHandler(userInfo))
	m.Add("1.0", "Get", "/auth/scheme", Handler(authScheme))
	m.Add("1.0", "Post", "/auth/login", Handler(login))

	m.Add("1.0", "Post", "/auth/saml", Handler(samlCallbackLogin))
	m.Add("1.0", "Get", "/auth/saml", Handler(samlMetadata))

	m.Add("1.0", "Post", "/users/{email}/password", Handler(resetPassword))
	m.Add("1.0", "Post", "/users/{email}/tokens", Handler(login))
	m.Add("1.0", "Get", "/users/{email}/quota", AuthorizationRequiredHandler(getUserQuota))
	m.Add("1.0", "Put", "/users/{email}/quota", AuthorizationRequiredHandler(changeUserQuota))
	m.Add("1.0", "Delete", "/users/tokens", AuthorizationRequiredHandler(logout))
	m.Add("1.0", "Put", "/users/password", AuthorizationRequiredHandler(changePassword))
	m.Add("1.0", "Delete", "/users", AuthorizationRequiredHandler(removeUser))
	m.Add("1.0", "Get", "/users/keys", AuthorizationRequiredHandler(listKeys))
	m.Add("1.0", "Post", "/users/keys", AuthorizationRequiredHandler(addKeyToUser))
	m.Add("1.0", "Delete", "/users/keys/{key}", AuthorizationRequiredHandler(removeKeyFromUser))
	m.Add("1.0", "Get", "/users/api-key", AuthorizationRequiredHandler(showAPIToken))
	m.Add("1.0", "Post", "/users/api-key", AuthorizationRequiredHandler(regenerateAPIToken))

	m.Add("1.0", "Get", "/logs", websocket.Handler(addLogs))

	m.Add("1.0", "Get", "/teams", AuthorizationRequiredHandler(teamList))
	m.Add("1.0", "Post", "/teams", AuthorizationRequiredHandler(createTeam))
	m.Add("1.0", "Delete", "/teams/{name}", AuthorizationRequiredHandler(removeTeam))

	m.Add("1.0", "Post", "/swap", AuthorizationRequiredHandler(swap))

	m.Add("1.0", "Get", "/healthcheck/", http.HandlerFunc(healthcheck))
	m.Add("1.0", "Get", "/healthcheck", http.HandlerFunc(healthcheck))

	m.Add("1.0", "Get", "/iaas/machines", AuthorizationRequiredHandler(machinesList))
	m.Add("1.0", "Delete", "/iaas/machines/{machine_id}", AuthorizationRequiredHandler(machineDestroy))
	m.Add("1.0", "Get", "/iaas/templates", AuthorizationRequiredHandler(templatesList))
	m.Add("1.0", "Post", "/iaas/templates", AuthorizationRequiredHandler(templateCreate))
	m.Add("1.0", "Put", "/iaas/templates/{template_name}", AuthorizationRequiredHandler(templateUpdate))
	m.Add("1.0", "Delete", "/iaas/templates/{template_name}", AuthorizationRequiredHandler(templateDestroy))

	m.Add("1.0", "Get", "/plans", AuthorizationRequiredHandler(listPlans))
	m.Add("1.0", "Post", "/plans", AuthorizationRequiredHandler(addPlan))
	m.Add("1.0", "Delete", "/plans/{planname}", AuthorizationRequiredHandler(removePlan))
	m.Add("1.0", "Get", "/plans/routers", AuthorizationRequiredHandler(listRouters))

	m.Add("1.0", "Get", "/pools", AuthorizationRequiredHandler(poolList))
	m.Add("1.0", "Post", "/pools", AuthorizationRequiredHandler(addPoolHandler))
	m.Add("1.0", "Delete", "/pools/{name}", AuthorizationRequiredHandler(removePoolHandler))
	m.Add("1.0", "Put", "/pools/{name}", AuthorizationRequiredHandler(poolUpdateHandler))
	m.Add("1.0", "Post", "/pools/{name}/team", AuthorizationRequiredHandler(addTeamToPoolHandler))
	m.Add("1.0", "Delete", "/pools/{name}/team", AuthorizationRequiredHandler(removeTeamToPoolHandler))

	m.Add("1.0", "Get", "/roles", AuthorizationRequiredHandler(listRoles))
	m.Add("1.0", "Post", "/roles", AuthorizationRequiredHandler(addRole))
	m.Add("1.0", "Get", "/roles/{name}", AuthorizationRequiredHandler(roleInfo))
	m.Add("1.0", "Delete", "/roles/{name}", AuthorizationRequiredHandler(removeRole))
	m.Add("1.0", "Post", "/roles/{name}/permissions", AuthorizationRequiredHandler(addPermissions))
	m.Add("1.0", "Delete", "/roles/{name}/permissions/{permission}", AuthorizationRequiredHandler(removePermissions))
	m.Add("1.0", "Post", "/roles/{name}/user", AuthorizationRequiredHandler(assignRole))
	m.Add("1.0", "Delete", "/roles/{name}/user/{email}", AuthorizationRequiredHandler(dissociateRole))
	m.Add("1.0", "Get", "/role/default", AuthorizationRequiredHandler(listDefaultRoles))
	m.Add("1.0", "Post", "/role/default", AuthorizationRequiredHandler(addDefaultRole))
	m.Add("1.0", "Delete", "/role/default", AuthorizationRequiredHandler(removeDefaultRole))
	m.Add("1.0", "Get", "/permissions", AuthorizationRequiredHandler(listPermissions))

	m.Add("1.0", "Get", "/debug/goroutines", AuthorizationRequiredHandler(dumpGoroutines))
	m.Add("1.0", "Get", "/debug/pprof/", AuthorizationRequiredHandler(indexHandler))
	m.Add("1.0", "Get", "/debug/pprof/cmdline", AuthorizationRequiredHandler(cmdlineHandler))
	m.Add("1.0", "Get", "/debug/pprof/profile", AuthorizationRequiredHandler(profileHandler))
	m.Add("1.0", "Get", "/debug/pprof/symbol", AuthorizationRequiredHandler(symbolHandler))
	m.Add("1.0", "Get", "/debug/pprof/heap", AuthorizationRequiredHandler(indexHandler))
	m.Add("1.0", "Get", "/debug/pprof/goroutine", AuthorizationRequiredHandler(indexHandler))
	m.Add("1.0", "Get", "/debug/pprof/threadcreate", AuthorizationRequiredHandler(indexHandler))
	m.Add("1.0", "Get", "/debug/pprof/block", AuthorizationRequiredHandler(indexHandler))
	m.Add("1.0", "Get", "/debug/pprof/trace", AuthorizationRequiredHandler(traceHandler))

	m.Add("1.2", "GET", "/node", AuthorizationRequiredHandler(listNodesHandler))
	m.Add("1.2", "GET", "/node/apps/{appname}/containers", AuthorizationRequiredHandler(listUnitsByApp))
	m.Add("1.2", "GET", "/node/{address:.*}/containers", AuthorizationRequiredHandler(listUnitsByNode))
	m.Add("1.2", "POST", "/node", AuthorizationRequiredHandler(addNodeHandler))
	m.Add("1.2", "PUT", "/node", AuthorizationRequiredHandler(updateNodeHandler))
	m.Add("1.2", "DELETE", "/node/{address:.*}", AuthorizationRequiredHandler(removeNodeHandler))

	m.Add("1.2", "GET", "/nodecontainers", AuthorizationRequiredHandler(nodeContainerList))
	m.Add("1.2", "POST", "/nodecontainers", AuthorizationRequiredHandler(nodeContainerCreate))
	m.Add("1.2", "GET", "/nodecontainers/{name}", AuthorizationRequiredHandler(nodeContainerInfo))
	m.Add("1.2", "DELETE", "/nodecontainers/{name}", AuthorizationRequiredHandler(nodeContainerDelete))
	m.Add("1.2", "POST", "/nodecontainers/{name}", AuthorizationRequiredHandler(nodeContainerUpdate))
	m.Add("1.2", "POST", "/nodecontainers/{name}/upgrade", AuthorizationRequiredHandler(nodeContainerUpgrade))

	m.Add("1.2", "POST", "/install/hosts", AuthorizationRequiredHandler(installHostAdd))
	m.Add("1.2", "GET", "/install/hosts", AuthorizationRequiredHandler(installHostList))
	m.Add("1.2", "GET", "/install/hosts/{name}", AuthorizationRequiredHandler(installHostInfo))

	m.Add("1.2", "GET", "/healing/node", AuthorizationRequiredHandler(nodeHealingRead))
	m.Add("1.2", "POST", "/healing/node", AuthorizationRequiredHandler(nodeHealingUpdate))
	m.Add("1.2", "DELETE", "/healing/node", AuthorizationRequiredHandler(nodeHealingDelete))

	m.Add("1.2", "GET", "/metrics", promhttp.Handler())

	// Handlers for compatibility reasons, should be removed on tsuru 2.0.
	m.Add("1.0", "GET", "/docker/node", AuthorizationRequiredHandler(listNodesHandler))
	m.Add("1.0", "GET", "/docker/node/apps/{appname}/containers", AuthorizationRequiredHandler(listUnitsByApp))
	m.Add("1.0", "GET", "/docker/node/{address:.*}/containers", AuthorizationRequiredHandler(listUnitsByNode))
	m.Add("1.0", "POST", "/docker/node", AuthorizationRequiredHandler(addNodeHandler))
	m.Add("1.0", "PUT", "/docker/node", AuthorizationRequiredHandler(updateNodeHandler))
	m.Add("1.0", "DELETE", "/docker/node/{address:.*}", AuthorizationRequiredHandler(removeNodeHandler))

	m.Add("1.0", "GET", "/docker/nodecontainers", AuthorizationRequiredHandler(nodeContainerList))
	m.Add("1.0", "POST", "/docker/nodecontainers", AuthorizationRequiredHandler(nodeContainerCreate))
	m.Add("1.0", "GET", "/docker/nodecontainers/{name}", AuthorizationRequiredHandler(nodeContainerInfo))
	m.Add("1.0", "DELETE", "/docker/nodecontainers/{name}", AuthorizationRequiredHandler(nodeContainerDelete))
	m.Add("1.0", "POST", "/docker/nodecontainers/{name}", AuthorizationRequiredHandler(nodeContainerUpdate))
	m.Add("1.0", "POST", "/docker/nodecontainers/{name}/upgrade", AuthorizationRequiredHandler(nodeContainerUpgrade))

	m.Add("1.0", "GET", "/docker/healing/node", AuthorizationRequiredHandler(nodeHealingRead))
	m.Add("1.0", "POST", "/docker/healing/node", AuthorizationRequiredHandler(nodeHealingUpdate))
	m.Add("1.0", "DELETE", "/docker/healing/node", AuthorizationRequiredHandler(nodeHealingDelete))

	n := negroni.New()
	n.Use(negroni.NewRecovery())
	n.Use(negroni.HandlerFunc(contextClearerMiddleware))
	if !dry {
		n.Use(newLoggerMiddleware())
	}
	n.UseHandler(m)
	n.Use(negroni.HandlerFunc(flushingWriterMiddleware))
	n.Use(negroni.HandlerFunc(setRequestIDHeaderMiddleware))
	n.Use(negroni.HandlerFunc(errorHandlingMiddleware))
	n.Use(negroni.HandlerFunc(setVersionHeadersMiddleware))
	n.Use(negroni.HandlerFunc(authTokenMiddleware))
	n.Use(&appLockMiddleware{excludedHandlers: []http.Handler{
		logPostHandler,
		runHandler,
		forceDeleteLockHandler,
		registerUnitHandler,
		setUnitStatusHandler,
		diffDeployHandler,
	}})
	n.UseHandler(http.HandlerFunc(runDelayedHandler))

	if !dry {
		startServer(n)
	}
	return n
}