Add list teams endpoint (#601)

This commit is contained in:
Zach Wasserman
2021-04-06 11:40:14 -07:00
committed by GitHub
parent 244983fd7a
commit 2d2ebaf634
6 changed files with 78 additions and 2 deletions
+19
View File
@@ -5,6 +5,8 @@ import (
"github.com/pkg/errors"
)
var teamSearchColumns = []string{"name"}
func (d *Datastore) NewTeam(team *kolide.Team) (*kolide.Team, error) {
query := `
INSERT INTO teams (
@@ -67,3 +69,20 @@ func (d *Datastore) SaveTeam(team *kolide.Team) (*kolide.Team, error) {
}
return team, nil
}
// ListTeams lists all teams with limit, sort and offset passed in with
// kolide.ListOptions
func (d *Datastore) ListTeams(opt kolide.ListOptions) ([]*kolide.Team, error) {
query := `
SELECT * FROM teams
WHERE TRUE
`
query, params := searchLike(query, nil, opt.MatchQuery, teamSearchColumns...)
query = appendListOptionsToSQL(query, opt)
teams := []*kolide.Team{}
if err := d.db.Select(&teams, query, params...); err != nil {
return nil, errors.Wrap(err, "list teams")
}
return teams, nil
}
+8
View File
@@ -14,11 +14,19 @@ type TeamStore interface {
TeamByName(name string) (*Team, error)
// SaveTeam saves any changes to the team.
SaveTeam(team *Team) (*Team, error)
// ListTeams lists teams with the ordering and filters in the provided
// options.
ListTeams(opt ListOptions) ([]*Team, error)
}
type TeamService interface {
// NewTeam creates a new team.
NewTeam(ctx context.Context, p TeamPayload) (*Team, error)
// ModifyTeam modifies an existing team.
ModifyTeam(ctx context.Context, id uint, payload TeamPayload) (*Team, error)
// ListTeams lists teams with the ordering and filters in the provided
// options.
ListTeams(ctx context.Context, opt ListOptions) ([]*Team, error)
}
type TeamPayload struct {
+31
View File
@@ -62,3 +62,34 @@ func makeModifyTeamEndpoint(svc kolide.Service) endpoint.Endpoint {
return modifyTeamResponse{Team: team}, err
}
}
////////////////////////////////////////////////////////////////////////////////
// List Teams
////////////////////////////////////////////////////////////////////////////////
type listTeamsRequest struct {
ListOptions kolide.ListOptions
}
type listTeamsResponse struct {
Teams []kolide.Team `json:"teams"`
Err error `json:"error,omitempty"`
}
func (r listTeamsResponse) error() error { return r.Err }
func makeListTeamsEndpoint(svc kolide.Service) endpoint.Endpoint {
return func(ctx context.Context, request interface{}) (interface{}, error) {
req := request.(listTeamsRequest)
teams, err := svc.ListTeams(ctx, req.ListOptions)
if err != nil {
return listTeamsResponse{Err: err}, nil
}
resp := listTeamsResponse{Teams: []kolide.Team{}}
for _, team := range teams {
resp.Teams = append(resp.Teams, *team)
}
return resp, nil
}
}
+8 -2
View File
@@ -112,6 +112,7 @@ type KolideEndpoints struct {
Version endpoint.Endpoint
CreateTeam endpoint.Endpoint
ModifyTeam endpoint.Endpoint
ListTeams endpoint.Endpoint
}
// MakeKolideServerEndpoints creates the Kolide API endpoints.
@@ -214,8 +215,10 @@ func MakeKolideServerEndpoints(svc kolide.Service, jwtKey, urlPrefix string, lim
GetCarve: authenticatedUser(jwtKey, svc, makeGetCarveEndpoint(svc)),
GetCarveBlock: authenticatedUser(jwtKey, svc, makeGetCarveBlockEndpoint(svc)),
Version: authenticatedUser(jwtKey, svc, makeVersionEndpoint(svc)),
CreateTeam: authenticatedUser(jwtKey, svc, makeCreateTeamEndpoint(svc)),
ModifyTeam: authenticatedUser(jwtKey, svc, makeModifyTeamEndpoint(svc)),
// TODO permissions for teams endpoints
CreateTeam: authenticatedUser(jwtKey, svc, makeCreateTeamEndpoint(svc)),
ModifyTeam: authenticatedUser(jwtKey, svc, makeModifyTeamEndpoint(svc)),
ListTeams: authenticatedUser(jwtKey, svc, makeListTeamsEndpoint(svc)),
// Authenticated status endpoints
StatusResultStore: authenticatedUser(jwtKey, svc, makeStatusResultStoreEndpoint(svc)),
@@ -327,6 +330,7 @@ type kolideHandlers struct {
Version http.Handler
CreateTeam http.Handler
ModifyTeam http.Handler
ListTeams http.Handler
}
func makeKolideKitHandlers(e KolideEndpoints, opts []kithttp.ServerOption) *kolideHandlers {
@@ -425,6 +429,7 @@ func makeKolideKitHandlers(e KolideEndpoints, opts []kithttp.ServerOption) *koli
Version: newServer(e.Version, decodeNoParamsRequest),
CreateTeam: newServer(e.CreateTeam, decodeCreateTeamRequest),
ModifyTeam: newServer(e.ModifyTeam, decodeModifyTeamRequest),
ListTeams: newServer(e.ListTeams, decodeListTeamsRequest),
}
}
@@ -638,6 +643,7 @@ func attachKolideAPIRoutes(r *mux.Router, h *kolideHandlers) {
r.Handle("/api/v1/fleet/carves/{id}/block/{block_id}", h.GetCarveBlock).Methods("GET").Name("get_carve_block")
r.Handle("/api/v1/fleet/teams", h.CreateTeam).Methods("POST").Name("create_team")
r.Handle("/api/v1/fleet/teams", h.ListTeams).Methods("GET").Name("list_teams")
r.Handle("/api/v1/fleet/teams/{id}", h.ModifyTeam).Methods("PATCH").Name("modify_team")
r.Handle("/api/v1/osquery/enroll", h.EnrollAgent).Methods("POST").Name("enroll_agent")
+4
View File
@@ -45,3 +45,7 @@ func (svc service) ModifyTeam(ctx context.Context, id uint, payload kolide.TeamP
return svc.ds.SaveTeam(team)
}
func (svc service) ListTeams(ctx context.Context, opt kolide.ListOptions) ([]*kolide.Team, error) {
return svc.ds.ListTeams(opt)
}
+8
View File
@@ -27,3 +27,11 @@ func decodeModifyTeamRequest(ctx context.Context, r *http.Request) (interface{},
resp.ID = id
return resp, nil
}
func decodeListTeamsRequest(ctx context.Context, r *http.Request) (interface{}, error) {
opt, err := listOptionsFromRequest(r)
if err != nil {
return nil, err
}
return listTeamsRequest{ListOptions: opt}, nil
}