Make adding routes a bit simpler (#1771)

* Make adding routes a bit simpler

* Remove unused handle

* Lint

* More lint
This commit is contained in:
Tomas Touceda 2021-08-25 10:08:14 -03:00 committed by GitHub
parent eead6d8bd1
commit 1f5094d97e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
7 changed files with 58 additions and 127 deletions

View file

@ -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,
)
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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