mirror of
https://github.com/fleetdm/fleet
synced 2026-05-23 08:58:41 +00:00
Make adding routes a bit simpler (#1771)
* Make adding routes a bit simpler * Remove unused handle * Lint * More lint
This commit is contained in:
parent
eead6d8bd1
commit
1f5094d97e
7 changed files with 58 additions and 127 deletions
|
|
@ -11,8 +11,8 @@ import (
|
|||
"strings"
|
||||
|
||||
"github.com/fleetdm/fleet/v4/server/fleet"
|
||||
"github.com/go-kit/kit/endpoint"
|
||||
kithttp "github.com/go-kit/kit/transport/http"
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
|
|
@ -70,6 +70,11 @@ func allFields(ifv reflect.Value) []reflect.StructField {
|
|||
// IDs are expected to be uint, and can be optional by setting the tag as follows: `url:"some-id,optional"`
|
||||
// list-options are optional by default and it'll ignore the optional portion of the tag.
|
||||
func makeDecoder(iface interface{}) kithttp.DecodeRequestFunc {
|
||||
if iface == nil {
|
||||
return func(ctx context.Context, r *http.Request) (interface{}, error) {
|
||||
return nil, nil
|
||||
}
|
||||
}
|
||||
t := reflect.TypeOf(iface)
|
||||
if t.Kind() != reflect.Struct {
|
||||
panic(fmt.Sprintf("makeDecoder only understands structs, not %T", iface))
|
||||
|
|
@ -132,18 +137,48 @@ func makeDecoder(iface interface{}) kithttp.DecodeRequestFunc {
|
|||
}
|
||||
}
|
||||
|
||||
func makeNopDecoder() kithttp.DecodeRequestFunc {
|
||||
return func(ctx context.Context, r *http.Request) (interface{}, error) {
|
||||
return nil, nil
|
||||
}
|
||||
type UserAuthEndpointer struct {
|
||||
svc fleet.Service
|
||||
opts []kithttp.ServerOption
|
||||
r *mux.Router
|
||||
}
|
||||
|
||||
func makeAuthenticatedServiceEndpoint(svc fleet.Service, f handlerFunc) endpoint.Endpoint {
|
||||
return authenticatedUser(svc, makeServiceEndpoint(svc, f))
|
||||
func NewUserAuthenticatedEndpointer(svc fleet.Service, opts []kithttp.ServerOption, r *mux.Router) *UserAuthEndpointer {
|
||||
return &UserAuthEndpointer{svc: svc, opts: opts, r: r}
|
||||
}
|
||||
|
||||
func makeServiceEndpoint(svc fleet.Service, f handlerFunc) endpoint.Endpoint {
|
||||
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
||||
return f(ctx, request, svc)
|
||||
}
|
||||
func getNameFromPathAndVerb(verb, path string) string {
|
||||
return strings.ToLower(verb) + "_" + strings.ReplaceAll(strings.TrimSuffix("/api/v1/fleet/", strings.TrimRight(path, "/")), "/", "_")
|
||||
}
|
||||
|
||||
func (e *UserAuthEndpointer) POST(path string, f handlerFunc, v interface{}) {
|
||||
e.handle(path, f, v, "POST")
|
||||
}
|
||||
|
||||
func (e *UserAuthEndpointer) GET(path string, f handlerFunc, v interface{}) {
|
||||
e.handle(path, f, v, "GET")
|
||||
}
|
||||
|
||||
func (e *UserAuthEndpointer) PATCH(path string, f handlerFunc, v interface{}) {
|
||||
e.handle(path, f, v, "PATCH")
|
||||
}
|
||||
|
||||
func (e *UserAuthEndpointer) DELETE(path string, f handlerFunc, v interface{}) {
|
||||
e.handle(path, f, v, "DELETE")
|
||||
}
|
||||
|
||||
func (e *UserAuthEndpointer) handle(path string, f handlerFunc, v interface{}, verb string) *mux.Route {
|
||||
return e.r.Handle(path, e.makeEndpoint(f, v)).Methods(verb).Name(getNameFromPathAndVerb(verb, path))
|
||||
}
|
||||
|
||||
func (e *UserAuthEndpointer) makeEndpoint(f handlerFunc, v interface{}) http.Handler {
|
||||
return newServer(
|
||||
authenticatedUser(
|
||||
e.svc,
|
||||
func(ctx context.Context, request interface{}) (interface{}, error) {
|
||||
return f(ctx, request, e.svc)
|
||||
}),
|
||||
makeDecoder(v),
|
||||
e.opts,
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,10 +2,8 @@ package service
|
|||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/fleetdm/fleet/v4/server/fleet"
|
||||
kithttp "github.com/go-kit/kit/transport/http"
|
||||
)
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
@ -23,14 +21,6 @@ type globalPolicyResponse struct {
|
|||
|
||||
func (r globalPolicyResponse) error() error { return r.Err }
|
||||
|
||||
func makeGlobalPolicyEndpoint(svc fleet.Service, opts []kithttp.ServerOption) http.Handler {
|
||||
return newServer(
|
||||
makeAuthenticatedServiceEndpoint(svc, globalPolicyEndpoint),
|
||||
makeDecoder(globalPolicyRequest{}),
|
||||
opts,
|
||||
)
|
||||
}
|
||||
|
||||
func globalPolicyEndpoint(ctx context.Context, request interface{}, svc fleet.Service) (interface{}, error) {
|
||||
req := request.(*globalPolicyRequest)
|
||||
resp, err := svc.NewGlobalPolicy(ctx, req.QueryID)
|
||||
|
|
@ -59,14 +49,6 @@ type listGlobalPoliciesResponse struct {
|
|||
|
||||
func (r listGlobalPoliciesResponse) error() error { return r.Err }
|
||||
|
||||
func makeListGlobalPoliciesEndpoint(svc fleet.Service, opts []kithttp.ServerOption) http.Handler {
|
||||
return newServer(
|
||||
makeAuthenticatedServiceEndpoint(svc, listGlobalPoliciesEndpoint),
|
||||
makeNopDecoder(),
|
||||
opts,
|
||||
)
|
||||
}
|
||||
|
||||
func listGlobalPoliciesEndpoint(ctx context.Context, _ interface{}, svc fleet.Service) (interface{}, error) {
|
||||
resp, err := svc.ListGlobalPolicies(ctx)
|
||||
if err != nil {
|
||||
|
|
@ -98,14 +80,6 @@ type getPolicyByIDResponse struct {
|
|||
|
||||
func (r getPolicyByIDResponse) error() error { return r.Err }
|
||||
|
||||
func makeGetPolicyByIDEndpoint(svc fleet.Service, opts []kithttp.ServerOption) http.Handler {
|
||||
return newServer(
|
||||
makeAuthenticatedServiceEndpoint(svc, getPolicyByIDEndpoint),
|
||||
makeDecoder(getPolicyByIDRequest{}),
|
||||
opts,
|
||||
)
|
||||
}
|
||||
|
||||
func getPolicyByIDEndpoint(ctx context.Context, request interface{}, svc fleet.Service) (interface{}, error) {
|
||||
req := request.(*getPolicyByIDRequest)
|
||||
policy, err := svc.GetPolicyByIDQueries(ctx, req.PolicyID)
|
||||
|
|
@ -143,14 +117,6 @@ type deleteGlobalPoliciesResponse struct {
|
|||
|
||||
func (r deleteGlobalPoliciesResponse) error() error { return r.Err }
|
||||
|
||||
func makeDeleteGlobalPoliciesEndpoint(svc fleet.Service, opts []kithttp.ServerOption) http.Handler {
|
||||
return newServer(
|
||||
makeAuthenticatedServiceEndpoint(svc, deleteGlobalPoliciesEndpoint),
|
||||
makeDecoder(deleteGlobalPoliciesRequest{}),
|
||||
opts,
|
||||
)
|
||||
}
|
||||
|
||||
func deleteGlobalPoliciesEndpoint(ctx context.Context, request interface{}, svc fleet.Service) (interface{}, error) {
|
||||
req := request.(*deleteGlobalPoliciesRequest)
|
||||
resp, err := svc.DeleteGlobalPolicies(ctx, req.IDs)
|
||||
|
|
|
|||
|
|
@ -676,26 +676,20 @@ func attachFleetAPIRoutes(r *mux.Router, h *fleetHandlers) {
|
|||
}
|
||||
|
||||
func attachNewStyleFleetAPIRoutes(r *mux.Router, svc fleet.Service, opts []kithttp.ServerOption) {
|
||||
handle("POST", "/api/v1/fleet/users/roles/spec", makeApplyUserRoleSpecsEndpoint(svc, opts), "apply_user_roles_spec", r)
|
||||
handle("POST", "/api/v1/fleet/translate", makeTranslatorEndpoint(svc, opts), "translator", r)
|
||||
handle("POST", "/api/v1/fleet/spec/teams", makeApplyTeamSpecsEndpoint(svc, opts), "apply_team_specs", r)
|
||||
e := NewUserAuthenticatedEndpointer(svc, opts, r)
|
||||
e.POST("/api/v1/fleet/users/roles/spec", applyUserRoleSpecsEndpoint, applyUserRoleSpecsRequest{})
|
||||
e.POST("/api/v1/fleet/translate", translatorEndpoint, translatorRequest{})
|
||||
e.POST("/api/v1/fleet/spec/teams", applyTeamSpecsEndpoint, applyTeamSpecsRequest{})
|
||||
|
||||
handle("GET", "/api/v1/fleet/team/{team_id}/schedule", makeGetTeamScheduleEndpoint(svc, opts), "get_team_schedule", r)
|
||||
handle("POST", "/api/v1/fleet/team/{team_id}/schedule", makeTeamScheduleQueryEndpoint(svc, opts), "add_to_team_schedule", r)
|
||||
handle("PATCH", "/api/v1/fleet/team/{team_id}/schedule/{scheduled_query_id}", makeModifyTeamScheduleEndpoint(svc, opts), "edit_team_schedule", r)
|
||||
handle("DELETE", "/api/v1/fleet/team/{team_id}/schedule/{scheduled_query_id}", makeDeleteTeamScheduleEndpoint(svc, opts), "delete_team_schedule", r)
|
||||
e.GET("/api/v1/fleet/team/{team_id}/schedule", getTeamScheduleEndpoint, getTeamScheduleRequest{})
|
||||
e.POST("/api/v1/fleet/team/{team_id}/schedule", teamScheduleQueryEndpoint, teamScheduleQueryRequest{})
|
||||
e.PATCH("/api/v1/fleet/team/{team_id}/schedule/{scheduled_query_id}", modifyTeamScheduleEndpoint, modifyTeamScheduleRequest{})
|
||||
e.DELETE("/api/v1/fleet/team/{team_id}/schedule/{scheduled_query_id}", deleteTeamScheduleEndpoint, deleteTeamScheduleRequest{})
|
||||
|
||||
handle("POST", "/api/v1/fleet/global/policies", makeGlobalPolicyEndpoint(svc, opts), "add_to_global_policy", r)
|
||||
handle("GET", "/api/v1/fleet/global/policies", makeListGlobalPoliciesEndpoint(svc, opts), "list_global_policies", r)
|
||||
handle("GET", "/api/v1/fleet/global/policies/{policy_id}", makeGetPolicyByIDEndpoint(svc, opts), "get_global_policy_by_id", r)
|
||||
handle("POST", "/api/v1/fleet/global/policies/delete", makeDeleteGlobalPoliciesEndpoint(svc, opts), "delete_global_policies", r)
|
||||
}
|
||||
|
||||
func handle(verb, path string, handler http.Handler, name string, r *mux.Router) {
|
||||
r.Handle(
|
||||
path,
|
||||
handler,
|
||||
).Methods(verb).Name(name)
|
||||
e.POST("/api/v1/fleet/global/policies", globalPolicyEndpoint, globalPolicyRequest{})
|
||||
e.GET("/api/v1/fleet/global/policies", listGlobalPoliciesEndpoint, nil)
|
||||
e.GET("/api/v1/fleet/global/policies/{policy_id}", getPolicyByIDEndpoint, getPolicyByIDRequest{})
|
||||
e.POST("/api/v1/fleet/global/policies/delete", deleteGlobalPoliciesEndpoint, deleteGlobalPoliciesRequest{})
|
||||
}
|
||||
|
||||
// TODO: this duplicates the one in makeKitHandler
|
||||
|
|
|
|||
|
|
@ -2,11 +2,9 @@ package service
|
|||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/fleetdm/fleet/v4/server/fleet"
|
||||
"github.com/fleetdm/fleet/v4/server/ptr"
|
||||
kithttp "github.com/go-kit/kit/transport/http"
|
||||
"gopkg.in/guregu/null.v3"
|
||||
)
|
||||
|
||||
|
|
@ -22,14 +20,6 @@ type getTeamScheduleResponse struct {
|
|||
|
||||
func (r getTeamScheduleResponse) error() error { return r.Err }
|
||||
|
||||
func makeGetTeamScheduleEndpoint(svc fleet.Service, opts []kithttp.ServerOption) http.Handler {
|
||||
return newServer(
|
||||
makeAuthenticatedServiceEndpoint(svc, getTeamScheduleEndpoint),
|
||||
makeDecoder(getTeamScheduleRequest{}),
|
||||
opts,
|
||||
)
|
||||
}
|
||||
|
||||
func getTeamScheduleEndpoint(ctx context.Context, request interface{}, svc fleet.Service) (interface{}, error) {
|
||||
req := request.(*getTeamScheduleRequest)
|
||||
resp := getTeamScheduleResponse{Scheduled: []scheduledQueryResponse{}}
|
||||
|
|
@ -74,14 +64,6 @@ type teamScheduleQueryResponse struct {
|
|||
|
||||
func (r teamScheduleQueryResponse) error() error { return r.Err }
|
||||
|
||||
func makeTeamScheduleQueryEndpoint(svc fleet.Service, opts []kithttp.ServerOption) http.Handler {
|
||||
return newServer(
|
||||
makeAuthenticatedServiceEndpoint(svc, teamScheduleQueryEndpoint),
|
||||
makeDecoder(teamScheduleQueryRequest{}),
|
||||
opts,
|
||||
)
|
||||
}
|
||||
|
||||
func uintValueOrZero(v *uint) uint {
|
||||
if v == nil {
|
||||
return 0
|
||||
|
|
@ -147,14 +129,6 @@ type modifyTeamScheduleResponse struct {
|
|||
|
||||
func (r modifyTeamScheduleResponse) error() error { return r.Err }
|
||||
|
||||
func makeModifyTeamScheduleEndpoint(svc fleet.Service, opts []kithttp.ServerOption) http.Handler {
|
||||
return newServer(
|
||||
makeAuthenticatedServiceEndpoint(svc, modifyTeamScheduleEndpoint),
|
||||
makeDecoder(modifyTeamScheduleRequest{}),
|
||||
opts,
|
||||
)
|
||||
}
|
||||
|
||||
func modifyTeamScheduleEndpoint(ctx context.Context, request interface{}, svc fleet.Service) (interface{}, error) {
|
||||
req := request.(*modifyTeamScheduleRequest)
|
||||
resp, err := svc.ModifyTeamScheduledQueries(ctx, req.TeamID, req.ScheduledQueryID, req.ScheduledQueryPayload)
|
||||
|
|
@ -196,14 +170,6 @@ type deleteTeamScheduleResponse struct {
|
|||
|
||||
func (r deleteTeamScheduleResponse) error() error { return r.Err }
|
||||
|
||||
func makeDeleteTeamScheduleEndpoint(svc fleet.Service, opts []kithttp.ServerOption) http.Handler {
|
||||
return newServer(
|
||||
makeAuthenticatedServiceEndpoint(svc, deleteTeamScheduleEndpoint),
|
||||
makeDecoder(deleteTeamScheduleRequest{}),
|
||||
opts,
|
||||
)
|
||||
}
|
||||
|
||||
func deleteTeamScheduleEndpoint(ctx context.Context, request interface{}, svc fleet.Service) (interface{}, error) {
|
||||
req := request.(*deleteTeamScheduleRequest)
|
||||
err := svc.DeleteTeamScheduledQueries(ctx, req.TeamID, req.ScheduledQueryID)
|
||||
|
|
|
|||
|
|
@ -3,11 +3,9 @@ package service
|
|||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"net/http"
|
||||
|
||||
"github.com/fleetdm/fleet/v4/server/fleet"
|
||||
"github.com/fleetdm/fleet/v4/server/ptr"
|
||||
kithttp "github.com/go-kit/kit/transport/http"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
|
|
@ -21,14 +19,6 @@ type applyTeamSpecsResponse struct {
|
|||
|
||||
func (r applyTeamSpecsResponse) error() error { return r.Err }
|
||||
|
||||
func makeApplyTeamSpecsEndpoint(svc fleet.Service, opts []kithttp.ServerOption) http.Handler {
|
||||
return newServer(
|
||||
makeAuthenticatedServiceEndpoint(svc, applyTeamSpecsEndpoint),
|
||||
makeDecoder(applyTeamSpecsRequest{}),
|
||||
opts,
|
||||
)
|
||||
}
|
||||
|
||||
func applyTeamSpecsEndpoint(ctx context.Context, request interface{}, svc fleet.Service) (interface{}, error) {
|
||||
req := request.(*applyTeamSpecsRequest)
|
||||
err := svc.ApplyTeamSpecs(ctx, req.Specs)
|
||||
|
|
|
|||
|
|
@ -2,10 +2,8 @@ package service
|
|||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/fleetdm/fleet/v4/server/fleet"
|
||||
kithttp "github.com/go-kit/kit/transport/http"
|
||||
)
|
||||
|
||||
type translatorRequest struct {
|
||||
|
|
@ -19,14 +17,6 @@ type translatorResponse struct {
|
|||
|
||||
func (r translatorResponse) error() error { return r.Err }
|
||||
|
||||
func makeTranslatorEndpoint(svc fleet.Service, opts []kithttp.ServerOption) http.Handler {
|
||||
return newServer(
|
||||
makeAuthenticatedServiceEndpoint(svc, translatorEndpoint),
|
||||
makeDecoder(translatorRequest{}),
|
||||
opts,
|
||||
)
|
||||
}
|
||||
|
||||
func translatorEndpoint(ctx context.Context, request interface{}, svc fleet.Service) (interface{}, error) {
|
||||
req := request.(*translatorRequest)
|
||||
resp, err := svc.Translate(ctx, req.List)
|
||||
|
|
|
|||
|
|
@ -2,10 +2,8 @@ package service
|
|||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
|
||||
"github.com/fleetdm/fleet/v4/server/fleet"
|
||||
kithttp "github.com/go-kit/kit/transport/http"
|
||||
"gopkg.in/guregu/null.v3"
|
||||
)
|
||||
|
||||
|
|
@ -19,14 +17,6 @@ type applyUserRoleSpecsResponse struct {
|
|||
|
||||
func (r applyUserRoleSpecsResponse) error() error { return r.Err }
|
||||
|
||||
func makeApplyUserRoleSpecsEndpoint(svc fleet.Service, opts []kithttp.ServerOption) http.Handler {
|
||||
return newServer(
|
||||
makeAuthenticatedServiceEndpoint(svc, applyUserRoleSpecsEndpoint),
|
||||
makeDecoder(applyUserRoleSpecsRequest{}),
|
||||
opts,
|
||||
)
|
||||
}
|
||||
|
||||
func applyUserRoleSpecsEndpoint(ctx context.Context, request interface{}, svc fleet.Service) (interface{}, error) {
|
||||
req := request.(*applyUserRoleSpecsRequest)
|
||||
err := svc.ApplyUserRolesSpecs(ctx, *req.Spec)
|
||||
|
|
|
|||
Loading…
Reference in a new issue