influxdb/tenant/http_server_org.go

192 lines
4.5 KiB
Go

package tenant
import (
"fmt"
"net/http"
"github.com/go-chi/chi"
"github.com/go-chi/chi/middleware"
"github.com/influxdata/influxdb"
kithttp "github.com/influxdata/influxdb/kit/transport/http"
"go.uber.org/zap"
)
// OrgHandler represents an HTTP API handler for organizations.
type OrgHandler struct {
chi.Router
api *kithttp.API
log *zap.Logger
orgSvc influxdb.OrganizationService
}
const (
prefixOrganizations = "/api/v2/orgs"
)
func (h *OrgHandler) Prefix() string {
return prefixOrganizations
}
// NewHTTPOrgHandler constructs a new http server.
func NewHTTPOrgHandler(log *zap.Logger, orgService influxdb.OrganizationService, urm http.Handler, labelHandler http.Handler, secretHandler http.Handler) *OrgHandler {
svr := &OrgHandler{
api: kithttp.NewAPI(kithttp.WithLog(log)),
log: log,
orgSvc: orgService,
}
r := chi.NewRouter()
r.Use(
middleware.Recoverer,
middleware.RequestID,
middleware.RealIP,
)
r.Route("/", func(r chi.Router) {
r.Post("/", svr.handlePostOrg)
r.Get("/", svr.handleGetOrgs)
r.Route("/{id}", func(r chi.Router) {
r.Get("/", svr.handleGetOrg)
r.Patch("/", svr.handlePatchOrg)
r.Delete("/", svr.handleDeleteOrg)
// mount embedded resources
r.Mount("/members", urm)
r.Mount("/owners", urm)
r.Mount("/labels", labelHandler)
r.Mount("/secrets", secretHandler)
})
})
svr.Router = r
return svr
}
type orgResponse struct {
influxdb.Organization
}
func newOrgResponse(o influxdb.Organization) orgResponse {
return orgResponse{
Organization: o,
}
}
type orgsResponse struct {
Organizations []orgResponse `json:"orgs"`
}
func newOrgsResponse(orgs []*influxdb.Organization) *orgsResponse {
res := orgsResponse{
Organizations: []orgResponse{},
}
for _, org := range orgs {
res.Organizations = append(res.Organizations, newOrgResponse(*org))
}
return &res
}
// handlePostOrg is the HTTP handler for the POST /api/v2/orgs route.
func (h *OrgHandler) handlePostOrg(w http.ResponseWriter, r *http.Request) {
var org influxdb.Organization
if err := h.api.DecodeJSON(r.Body, &org); err != nil {
h.api.Err(w, err)
return
}
if err := h.orgSvc.CreateOrganization(r.Context(), &org); err != nil {
h.api.Err(w, err)
return
}
h.log.Debug("Org created", zap.String("org", fmt.Sprint(org)))
h.api.Respond(w, http.StatusCreated, newOrgResponse(org))
}
// handleGetOrg is the HTTP handler for the GET /api/v2/orgs/:id route.
func (h *OrgHandler) handleGetOrg(w http.ResponseWriter, r *http.Request) {
id, err := influxdb.IDFromString(chi.URLParam(r, "id"))
if err != nil {
h.api.Err(w, err)
return
}
org, err := h.orgSvc.FindOrganizationByID(r.Context(), *id)
if err != nil {
h.api.Err(w, err)
return
}
h.log.Debug("Org retrieved", zap.String("org", fmt.Sprint(org)))
h.api.Respond(w, http.StatusOK, newOrgResponse(*org))
}
// handleGetOrgs is the HTTP handler for the GET /api/v2/orgs route.
func (h *OrgHandler) handleGetOrgs(w http.ResponseWriter, r *http.Request) {
var filter influxdb.OrganizationFilter
qp := r.URL.Query()
if name := qp.Get("org"); name != "" {
filter.Name = &name
}
if id := qp.Get("orgID"); id != "" {
i, err := influxdb.IDFromString(id)
if err == nil {
filter.ID = i
}
}
orgs, _, err := h.orgSvc.FindOrganizations(r.Context(), filter)
if err != nil {
h.api.Err(w, err)
return
}
h.log.Debug("Orgs retrieved", zap.String("org", fmt.Sprint(orgs)))
h.api.Respond(w, http.StatusOK, newOrgsResponse(orgs))
}
// handlePatchOrg is the HTTP handler for the PATH /api/v2/orgs route.
func (h *OrgHandler) handlePatchOrg(w http.ResponseWriter, r *http.Request) {
id, err := influxdb.IDFromString(chi.URLParam(r, "id"))
if err != nil {
h.api.Err(w, err)
return
}
var upd influxdb.OrganizationUpdate
if err := h.api.DecodeJSON(r.Body, &upd); err != nil {
h.api.Err(w, err)
return
}
org, err := h.orgSvc.UpdateOrganization(r.Context(), *id, upd)
if err != nil {
h.api.Err(w, err)
return
}
h.log.Debug("Org updated", zap.String("org", fmt.Sprint(org)))
h.api.Respond(w, http.StatusOK, newOrgResponse(*org))
}
// handleDeleteOrganization is the HTTP handler for the DELETE /api/v2/orgs/:id route.
func (h *OrgHandler) handleDeleteOrg(w http.ResponseWriter, r *http.Request) {
id, err := influxdb.IDFromString(chi.URLParam(r, "id"))
if err != nil {
h.api.Err(w, err)
return
}
ctx := r.Context()
if err := h.orgSvc.DeleteOrganization(ctx, *id); err != nil {
h.api.Err(w, err)
return
}
h.log.Debug("Org deleted", zap.String("orgID", fmt.Sprint(id)))
h.api.Respond(w, http.StatusNoContent, nil)
}