influxdb/http/api_handler.go

280 lines
8.9 KiB
Go

package http
import (
http "net/http"
"strings"
"github.com/influxdata/platform"
"github.com/influxdata/platform/chronograf/server"
"github.com/influxdata/platform/query"
"github.com/influxdata/platform/storage"
"go.uber.org/zap"
)
// APIHandler is a collection of all the service handlers.
type APIHandler struct {
BucketHandler *BucketHandler
UserHandler *UserHandler
OrgHandler *OrgHandler
AuthorizationHandler *AuthorizationHandler
DashboardHandler *DashboardHandler
AssetHandler *AssetHandler
ChronografHandler *ChronografHandler
SourceHandler *SourceHandler
MacroHandler *MacroHandler
TaskHandler *TaskHandler
TelegrafHandler *TelegrafHandler
QueryHandler *FluxHandler
ProtoHandler *ProtoHandler
WriteHandler *WriteHandler
SetupHandler *SetupHandler
SessionHandler *SessionHandler
}
// APIBackend is all services and associated parameters required to construct
// an APIHandler.
type APIBackend struct {
DeveloperMode bool
Logger *zap.Logger
NewBucketService func(*platform.Source) (platform.BucketService, error)
NewQueryService func(*platform.Source) (query.ProxyQueryService, error)
PointsWriter storage.PointsWriter
AuthorizationService platform.AuthorizationService
BucketService platform.BucketService
SessionService platform.SessionService
UserService platform.UserService
OrganizationService platform.OrganizationService
UserResourceMappingService platform.UserResourceMappingService
LabelService platform.LabelService
DashboardService platform.DashboardService
DashboardOperationLogService platform.DashboardOperationLogService
BucketOperationLogService platform.BucketOperationLogService
UserOperationLogService platform.UserOperationLogService
OrganizationOperationLogService platform.OrganizationOperationLogService
SourceService platform.SourceService
MacroService platform.MacroService
BasicAuthService platform.BasicAuthService
OnboardingService platform.OnboardingService
ProxyQueryService query.ProxyQueryService
TaskService platform.TaskService
TelegrafService platform.TelegrafConfigStore
ScraperTargetStoreService platform.ScraperTargetStoreService
SecretService platform.SecretService
LookupService platform.LookupService
ChronografService *server.Service
ProtoService platform.ProtoService
}
// NewAPIHandler constructs all api handlers beneath it and returns an APIHandler
func NewAPIHandler(b *APIBackend) *APIHandler {
h := &APIHandler{}
sessionBackend := NewSessionBackend(b)
h.SessionHandler = NewSessionHandler(sessionBackend)
h.BucketHandler = NewBucketHandler(b.UserResourceMappingService, b.LabelService, b.UserService)
h.BucketHandler.BucketService = b.BucketService
h.BucketHandler.BucketOperationLogService = b.BucketOperationLogService
h.OrgHandler = NewOrgHandler(b.UserResourceMappingService, b.LabelService, b.UserService)
h.OrgHandler.OrganizationService = b.OrganizationService
h.OrgHandler.BucketService = b.BucketService
h.OrgHandler.OrganizationOperationLogService = b.OrganizationOperationLogService
h.OrgHandler.SecretService = b.SecretService
h.UserHandler = NewUserHandler()
h.UserHandler.UserService = b.UserService
h.UserHandler.BasicAuthService = b.BasicAuthService
h.UserHandler.UserOperationLogService = b.UserOperationLogService
h.DashboardHandler = NewDashboardHandler(b.UserResourceMappingService, b.LabelService, b.UserService)
h.DashboardHandler.DashboardService = b.DashboardService
h.DashboardHandler.DashboardOperationLogService = b.DashboardOperationLogService
h.MacroHandler = NewMacroHandler()
h.MacroHandler.MacroService = b.MacroService
h.AuthorizationHandler = NewAuthorizationHandler(b.UserService)
h.AuthorizationHandler.OrganizationService = b.OrganizationService
h.AuthorizationHandler.AuthorizationService = b.AuthorizationService
h.AuthorizationHandler.LookupService = b.LookupService
h.AuthorizationHandler.Logger = b.Logger.With(zap.String("handler", "auth"))
h.SourceHandler = NewSourceHandler()
h.SourceHandler.SourceService = b.SourceService
h.SourceHandler.NewBucketService = b.NewBucketService
h.SourceHandler.NewQueryService = b.NewQueryService
h.SetupHandler = NewSetupHandler()
h.SetupHandler.OnboardingService = b.OnboardingService
h.TaskHandler = NewTaskHandler(b.UserResourceMappingService, b.LabelService, b.Logger, b.UserService)
h.TaskHandler.TaskService = b.TaskService
h.TaskHandler.AuthorizationService = b.AuthorizationService
h.TaskHandler.UserResourceMappingService = b.UserResourceMappingService
h.TelegrafHandler = NewTelegrafHandler(
b.Logger.With(zap.String("handler", "telegraf")),
b.UserResourceMappingService,
b.LabelService,
b.TelegrafService,
b.UserService,
)
h.WriteHandler = NewWriteHandler(b.PointsWriter)
h.WriteHandler.OrganizationService = b.OrganizationService
h.WriteHandler.BucketService = b.BucketService
h.WriteHandler.Logger = b.Logger.With(zap.String("handler", "write"))
h.QueryHandler = NewFluxHandler()
h.QueryHandler.OrganizationService = b.OrganizationService
h.QueryHandler.Logger = b.Logger.With(zap.String("handler", "query"))
h.QueryHandler.ProxyQueryService = b.ProxyQueryService
h.ProtoHandler = NewProtoHandler(NewProtoBackend(b))
h.ChronografHandler = NewChronografHandler(b.ChronografService)
return h
}
var apiLinks = map[string]interface{}{
// when adding new links, please take care to keep this list alphabetical
// as this makes it easier to verify values against the swagger document.
"authorizations": "/api/v2/authorizations",
"buckets": "/api/v2/buckets",
"dashboards": "/api/v2/dashboards",
"external": map[string]string{
"statusFeed": "https://www.influxdata.com/feed/json",
},
"macros": "/api/v2/macros",
"me": "/api/v2/me",
"orgs": "/api/v2/orgs",
"protos": "/api/v2/protos",
"query": map[string]string{
"self": "/api/v2/query",
"ast": "/api/v2/query/ast",
"analyze": "/api/v2/query/analyze",
"spec": "/api/v2/query/spec",
"suggestions": "/api/v2/query/suggestions",
},
"setup": "/api/v2/setup",
"signin": "/api/v2/signin",
"signout": "/api/v2/signout",
"sources": "/api/v2/sources",
"system": map[string]string{
"metrics": "/metrics",
"debug": "/debug/pprof",
"health": "/health",
},
"tasks": "/api/v2/tasks",
"telegrafs": "/api/v2/telegrafs",
"users": "/api/v2/users",
"write": "/api/v2/write",
}
func (h *APIHandler) serveLinks(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
if err := encodeResponse(ctx, w, http.StatusOK, apiLinks); err != nil {
EncodeError(ctx, err, w)
return
}
}
// ServeHTTP delegates a request to the appropriate subhandler.
func (h *APIHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
setCORSResponseHeaders(w, r)
if r.Method == "OPTIONS" {
return
}
// Serve the links base links for the API.
if r.URL.Path == "/api/v2/" || r.URL.Path == "/api/v2" {
h.serveLinks(w, r)
return
}
if r.URL.Path == "/api/v2/signin" || r.URL.Path == "/api/v2/signout" {
h.SessionHandler.ServeHTTP(w, r)
return
}
if strings.HasPrefix(r.URL.Path, "/api/v2/setup") {
h.SetupHandler.ServeHTTP(w, r)
return
}
if strings.HasPrefix(r.URL.Path, "/api/v2/write") {
h.WriteHandler.ServeHTTP(w, r)
return
}
if strings.HasPrefix(r.URL.Path, "/api/v2/query") {
h.QueryHandler.ServeHTTP(w, r)
return
}
if strings.HasPrefix(r.URL.Path, "/api/v2/buckets") {
h.BucketHandler.ServeHTTP(w, r)
return
}
if strings.HasPrefix(r.URL.Path, "/api/v2/users") {
h.UserHandler.ServeHTTP(w, r)
return
}
if strings.HasPrefix(r.URL.Path, "/api/v2/me") {
h.UserHandler.ServeHTTP(w, r)
return
}
if strings.HasPrefix(r.URL.Path, "/api/v2/orgs") {
h.OrgHandler.ServeHTTP(w, r)
return
}
if strings.HasPrefix(r.URL.Path, "/api/v2/authorizations") {
h.AuthorizationHandler.ServeHTTP(w, r)
return
}
if strings.HasPrefix(r.URL.Path, "/api/v2/dashboards") {
h.DashboardHandler.ServeHTTP(w, r)
return
}
if strings.HasPrefix(r.URL.Path, "/api/v2/sources") {
h.SourceHandler.ServeHTTP(w, r)
return
}
if strings.HasPrefix(r.URL.Path, "/api/v2/tasks") {
h.TaskHandler.ServeHTTP(w, r)
return
}
if strings.HasPrefix(r.URL.Path, "/api/v2/telegrafs") {
h.TelegrafHandler.ServeHTTP(w, r)
return
}
if strings.HasPrefix(r.URL.Path, "/api/v2/macros") {
h.MacroHandler.ServeHTTP(w, r)
return
}
if strings.HasPrefix(r.URL.Path, "/api/v2/protos") {
h.ProtoHandler.ServeHTTP(w, r)
return
}
if strings.HasPrefix(r.URL.Path, "/chronograf/") {
h.ChronografHandler.ServeHTTP(w, r)
return
}
notFoundHandler(w, r)
}