mirror of
https://github.com/fleetdm/fleet
synced 2026-05-24 09:28:54 +00:00
Add pagination to List* endpoints (#309)
- Introduce kolide.ListOptions to store pagination params (in the future it can also store ordering/filtering params) - Refactor service/datastore methods to take kolide.ListOptions - Implement pagination
This commit is contained in:
parent
f9fa3e289f
commit
7f636aef4f
50 changed files with 478 additions and 100 deletions
|
|
@ -84,3 +84,15 @@ func openGORM(driver, conn string, maxAttempts int) (*gorm.DB, error) {
|
||||||
}
|
}
|
||||||
return db, nil
|
return db, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// applyLimitOffset applies the appropriate limit and offset parameters to the
|
||||||
|
// gorm.DB instance, returning a DB that can be chained as usual with *gorm.DB.
|
||||||
|
func (orm *gormDB) applyListOptions(opt kolide.ListOptions) *gorm.DB {
|
||||||
|
if opt.PerPage == 0 {
|
||||||
|
// PerPage value of 0 indicates unlimited
|
||||||
|
return orm.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
offset := opt.Page * opt.PerPage
|
||||||
|
return orm.DB.Limit(opt.PerPage).Offset(offset)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -100,9 +100,9 @@ func (orm gormDB) Host(id uint) (*kolide.Host, error) {
|
||||||
return host, nil
|
return host, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (orm gormDB) Hosts() ([]*kolide.Host, error) {
|
func (orm gormDB) Hosts(opt kolide.ListOptions) ([]*kolide.Host, error) {
|
||||||
var hosts []*kolide.Host
|
var hosts []*kolide.Host
|
||||||
err := orm.DB.Find(&hosts).Error
|
err := orm.applyListOptions(opt).Find(&hosts).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,9 +21,9 @@ func (orm gormDB) InviteByEmail(email string) (*kolide.Invite, error) {
|
||||||
return invite, nil
|
return invite, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (orm gormDB) Invites() ([]*kolide.Invite, error) {
|
func (orm gormDB) Invites(opt kolide.ListOptions) ([]*kolide.Invite, error) {
|
||||||
var invites []*kolide.Invite
|
var invites []*kolide.Invite
|
||||||
err := orm.DB.Find(&invites).Error
|
err := orm.applyListOptions(opt).Find(&invites).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -54,9 +54,9 @@ func (orm gormDB) Label(lid uint) (*kolide.Label, error) {
|
||||||
return label, nil
|
return label, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (orm gormDB) Labels() ([]*kolide.Label, error) {
|
func (orm gormDB) Labels(opt kolide.ListOptions) ([]*kolide.Label, error) {
|
||||||
var labels []*kolide.Label
|
var labels []*kolide.Label
|
||||||
err := orm.DB.Find(&labels).Error
|
err := orm.applyListOptions(opt).Find(&labels).Error
|
||||||
return labels, err
|
return labels, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -50,9 +50,9 @@ func (orm gormDB) Pack(pid uint) (*kolide.Pack, error) {
|
||||||
return pack, nil
|
return pack, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (orm gormDB) Packs() ([]*kolide.Pack, error) {
|
func (orm gormDB) Packs(opt kolide.ListOptions) ([]*kolide.Pack, error) {
|
||||||
var packs []*kolide.Pack
|
var packs []*kolide.Pack
|
||||||
err := orm.DB.Find(&packs).Error
|
err := orm.applyListOptions(opt).Find(&packs).Error
|
||||||
return packs, err
|
return packs, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -151,7 +151,7 @@ func (orm gormDB) ActivePacksForHost(hid uint) ([]*kolide.Pack, error) {
|
||||||
|
|
||||||
// we will need to give some subset of packs to this host based on the
|
// we will need to give some subset of packs to this host based on the
|
||||||
// labels which this host is known to belong to
|
// labels which this host is known to belong to
|
||||||
allPacks, err := orm.Packs()
|
allPacks, err := orm.Packs(kolide.ListOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -50,8 +50,8 @@ func (orm gormDB) Query(id uint) (*kolide.Query, error) {
|
||||||
return query, nil
|
return query, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (orm gormDB) Queries() ([]*kolide.Query, error) {
|
func (orm gormDB) Queries(opt kolide.ListOptions) ([]*kolide.Query, error) {
|
||||||
var queries []*kolide.Query
|
var queries []*kolide.Query
|
||||||
err := orm.DB.Find(&queries).Error
|
err := orm.applyListOptions(opt).Find(&queries).Error
|
||||||
return queries, err
|
return queries, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,9 @@ func (orm gormDB) User(username string) (*kolide.User, error) {
|
||||||
return user, nil
|
return user, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (orm gormDB) Users() ([]*kolide.User, error) {
|
func (orm gormDB) Users(opt kolide.ListOptions) ([]*kolide.User, error) {
|
||||||
var users []*kolide.User
|
var users []*kolide.User
|
||||||
err := orm.DB.Find(&users).Error
|
err := orm.applyListOptions(opt).Find(&users).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -44,3 +44,23 @@ func (orm *inmem) Migrate() error {
|
||||||
func (orm *inmem) Drop() error {
|
func (orm *inmem) Drop() error {
|
||||||
return orm.Migrate()
|
return orm.Migrate()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getLimitOffsetSliceBounds returns the bounds that should be used for
|
||||||
|
// re-slicing the results to comply with the requested ListOptions. Lack of
|
||||||
|
// generics forces us to do this rather than reslicing in this method.
|
||||||
|
func (orm *inmem) getLimitOffsetSliceBounds(opt kolide.ListOptions, length int) (low uint, high uint) {
|
||||||
|
if opt.PerPage == 0 {
|
||||||
|
// PerPage value of 0 indicates unlimited
|
||||||
|
return 0, uint(length)
|
||||||
|
}
|
||||||
|
|
||||||
|
offset := opt.Page * opt.PerPage
|
||||||
|
max := offset + opt.PerPage
|
||||||
|
if offset > uint(length) {
|
||||||
|
offset = uint(length)
|
||||||
|
}
|
||||||
|
if max > uint(length) {
|
||||||
|
max = uint(length)
|
||||||
|
}
|
||||||
|
return offset, max
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package datastore
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"sort"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/kolide/kolide-ose/server/kolide"
|
"github.com/kolide/kolide-ose/server/kolide"
|
||||||
|
|
@ -59,14 +60,25 @@ func (orm *inmem) Host(id uint) (*kolide.Host, error) {
|
||||||
return host, nil
|
return host, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (orm *inmem) Hosts() ([]*kolide.Host, error) {
|
func (orm *inmem) Hosts(opt kolide.ListOptions) ([]*kolide.Host, error) {
|
||||||
orm.mtx.Lock()
|
orm.mtx.Lock()
|
||||||
defer orm.mtx.Unlock()
|
defer orm.mtx.Unlock()
|
||||||
|
|
||||||
hosts := []*kolide.Host{}
|
// We need to sort by keys to provide reliable ordering
|
||||||
for _, host := range orm.hosts {
|
keys := []int{}
|
||||||
hosts = append(hosts, host)
|
for k, _ := range orm.hosts {
|
||||||
|
keys = append(keys, int(k))
|
||||||
}
|
}
|
||||||
|
sort.Ints(keys)
|
||||||
|
|
||||||
|
hosts := []*kolide.Host{}
|
||||||
|
for _, k := range keys {
|
||||||
|
hosts = append(hosts, orm.hosts[uint(k)])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply limit/offset
|
||||||
|
low, high := orm.getLimitOffsetSliceBounds(opt, len(hosts))
|
||||||
|
hosts = hosts[low:high]
|
||||||
|
|
||||||
return hosts, nil
|
return hosts, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,10 @@
|
||||||
package datastore
|
package datastore
|
||||||
|
|
||||||
import "github.com/kolide/kolide-ose/server/kolide"
|
import (
|
||||||
|
"sort"
|
||||||
|
|
||||||
|
"github.com/kolide/kolide-ose/server/kolide"
|
||||||
|
)
|
||||||
|
|
||||||
// NewInvite creates and stores a new invitation in a DB.
|
// NewInvite creates and stores a new invitation in a DB.
|
||||||
func (orm *inmem) NewInvite(invite *kolide.Invite) (*kolide.Invite, error) {
|
func (orm *inmem) NewInvite(invite *kolide.Invite) (*kolide.Invite, error) {
|
||||||
|
|
@ -19,14 +23,25 @@ func (orm *inmem) NewInvite(invite *kolide.Invite) (*kolide.Invite, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Invites lists all invites in the datastore.
|
// Invites lists all invites in the datastore.
|
||||||
func (orm *inmem) Invites() ([]*kolide.Invite, error) {
|
func (orm *inmem) Invites(opt kolide.ListOptions) ([]*kolide.Invite, error) {
|
||||||
orm.mtx.Lock()
|
orm.mtx.Lock()
|
||||||
defer orm.mtx.Unlock()
|
defer orm.mtx.Unlock()
|
||||||
|
|
||||||
var invites []*kolide.Invite
|
// We need to sort by keys to provide reliable ordering
|
||||||
for _, invite := range orm.invites {
|
keys := []int{}
|
||||||
invites = append(invites, invite)
|
for k, _ := range orm.invites {
|
||||||
|
keys = append(keys, int(k))
|
||||||
}
|
}
|
||||||
|
sort.Ints(keys)
|
||||||
|
|
||||||
|
invites := []*kolide.Invite{}
|
||||||
|
for _, k := range keys {
|
||||||
|
invites = append(invites, orm.invites[uint(k)])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply limit/offset
|
||||||
|
low, high := orm.getLimitOffsetSliceBounds(opt, len(invites))
|
||||||
|
invites = invites[low:high]
|
||||||
|
|
||||||
return invites, nil
|
return invites, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
package datastore
|
package datastore
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"sort"
|
||||||
|
|
||||||
"github.com/kolide/kolide-ose/server/kolide"
|
"github.com/kolide/kolide-ose/server/kolide"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -58,14 +60,25 @@ func (orm *inmem) Pack(id uint) (*kolide.Pack, error) {
|
||||||
return pack, nil
|
return pack, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (orm *inmem) Packs() ([]*kolide.Pack, error) {
|
func (orm *inmem) Packs(opt kolide.ListOptions) ([]*kolide.Pack, error) {
|
||||||
orm.mtx.Lock()
|
orm.mtx.Lock()
|
||||||
defer orm.mtx.Unlock()
|
defer orm.mtx.Unlock()
|
||||||
|
|
||||||
packs := []*kolide.Pack{}
|
// We need to sort by keys to provide reliable ordering
|
||||||
for _, pack := range orm.packs {
|
keys := []int{}
|
||||||
packs = append(packs, pack)
|
for k, _ := range orm.packs {
|
||||||
|
keys = append(keys, int(k))
|
||||||
}
|
}
|
||||||
|
sort.Ints(keys)
|
||||||
|
|
||||||
|
packs := []*kolide.Pack{}
|
||||||
|
for _, k := range keys {
|
||||||
|
packs = append(packs, orm.packs[uint(k)])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply limit/offset
|
||||||
|
low, high := orm.getLimitOffsetSliceBounds(opt, len(packs))
|
||||||
|
packs = packs[low:high]
|
||||||
|
|
||||||
return packs, nil
|
return packs, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
package datastore
|
package datastore
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"sort"
|
||||||
|
|
||||||
"github.com/kolide/kolide-ose/server/kolide"
|
"github.com/kolide/kolide-ose/server/kolide"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -58,14 +60,25 @@ func (orm *inmem) Query(id uint) (*kolide.Query, error) {
|
||||||
return query, nil
|
return query, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (orm *inmem) Queries() ([]*kolide.Query, error) {
|
func (orm *inmem) Queries(opt kolide.ListOptions) ([]*kolide.Query, error) {
|
||||||
orm.mtx.Lock()
|
orm.mtx.Lock()
|
||||||
defer orm.mtx.Unlock()
|
defer orm.mtx.Unlock()
|
||||||
|
|
||||||
queries := []*kolide.Query{}
|
// We need to sort by keys to provide reliable ordering
|
||||||
for _, query := range orm.queries {
|
keys := []int{}
|
||||||
queries = append(queries, query)
|
for k, _ := range orm.queries {
|
||||||
|
keys = append(keys, int(k))
|
||||||
}
|
}
|
||||||
|
sort.Ints(keys)
|
||||||
|
|
||||||
|
queries := []*kolide.Query{}
|
||||||
|
for _, k := range keys {
|
||||||
|
queries = append(queries, orm.queries[uint(k)])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply limit/offset
|
||||||
|
low, high := orm.getLimitOffsetSliceBounds(opt, len(queries))
|
||||||
|
queries = queries[low:high]
|
||||||
|
|
||||||
return queries, nil
|
return queries, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
68
server/datastore/inmem_test.go
Normal file
68
server/datastore/inmem_test.go
Normal file
|
|
@ -0,0 +1,68 @@
|
||||||
|
package datastore
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/kolide/kolide-ose/server/kolide"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestApplyLimitOffset(t *testing.T) {
|
||||||
|
im := inmem{}
|
||||||
|
data := []int{}
|
||||||
|
|
||||||
|
// should work with empty
|
||||||
|
low, high := im.getLimitOffsetSliceBounds(kolide.ListOptions{}, len(data))
|
||||||
|
result := data[low:high]
|
||||||
|
assert.Len(t, result, 0)
|
||||||
|
low, high = im.getLimitOffsetSliceBounds(kolide.ListOptions{Page: 1, PerPage: 20}, len(data))
|
||||||
|
result = data[low:high]
|
||||||
|
assert.Len(t, result, 0)
|
||||||
|
|
||||||
|
// insert some data
|
||||||
|
for i := 0; i < 100; i++ {
|
||||||
|
data = append(data, i)
|
||||||
|
}
|
||||||
|
|
||||||
|
// unlimited
|
||||||
|
low, high = im.getLimitOffsetSliceBounds(kolide.ListOptions{}, len(data))
|
||||||
|
result = data[low:high]
|
||||||
|
assert.Len(t, result, 100)
|
||||||
|
assert.Equal(t, data, result)
|
||||||
|
|
||||||
|
// reasonable limit page 0
|
||||||
|
low, high = im.getLimitOffsetSliceBounds(kolide.ListOptions{PerPage: 20}, len(data))
|
||||||
|
result = data[low:high]
|
||||||
|
assert.Len(t, result, 20)
|
||||||
|
assert.Equal(t, data[:20], result)
|
||||||
|
|
||||||
|
// too many per page
|
||||||
|
low, high = im.getLimitOffsetSliceBounds(kolide.ListOptions{PerPage: 200}, len(data))
|
||||||
|
result = data[low:high]
|
||||||
|
assert.Len(t, result, 100)
|
||||||
|
assert.Equal(t, data, result)
|
||||||
|
|
||||||
|
// offset should be past end (zero results)
|
||||||
|
low, high = im.getLimitOffsetSliceBounds(kolide.ListOptions{Page: 1, PerPage: 200}, len(data))
|
||||||
|
result = data[low:high]
|
||||||
|
assert.Len(t, result, 0)
|
||||||
|
|
||||||
|
// all pages appended should equal the original data
|
||||||
|
result = []int{}
|
||||||
|
for i := 0; i < 5; i++ { // 5 used intentionally
|
||||||
|
low, high = im.getLimitOffsetSliceBounds(kolide.ListOptions{Page: uint(i), PerPage: 25}, len(data))
|
||||||
|
result = append(result, data[low:high]...)
|
||||||
|
}
|
||||||
|
assert.Len(t, result, 100)
|
||||||
|
assert.Equal(t, data, result)
|
||||||
|
|
||||||
|
// again with different params
|
||||||
|
result = []int{}
|
||||||
|
for i := 0; i < 100; i++ { // 5 used intentionally
|
||||||
|
low, high = im.getLimitOffsetSliceBounds(kolide.ListOptions{Page: uint(i), PerPage: 1}, len(data))
|
||||||
|
result = append(result, data[low:high]...)
|
||||||
|
}
|
||||||
|
assert.Len(t, result, 100)
|
||||||
|
assert.Equal(t, data, result)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,10 @@
|
||||||
package datastore
|
package datastore
|
||||||
|
|
||||||
import "github.com/kolide/kolide-ose/server/kolide"
|
import (
|
||||||
|
"sort"
|
||||||
|
|
||||||
|
"github.com/kolide/kolide-ose/server/kolide"
|
||||||
|
)
|
||||||
|
|
||||||
func (orm *inmem) NewUser(user *kolide.User) (*kolide.User, error) {
|
func (orm *inmem) NewUser(user *kolide.User) (*kolide.User, error) {
|
||||||
orm.mtx.Lock()
|
orm.mtx.Lock()
|
||||||
|
|
@ -31,14 +35,25 @@ func (orm *inmem) User(username string) (*kolide.User, error) {
|
||||||
return nil, ErrNotFound
|
return nil, ErrNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
func (orm *inmem) Users() ([]*kolide.User, error) {
|
func (orm *inmem) Users(opt kolide.ListOptions) ([]*kolide.User, error) {
|
||||||
orm.mtx.Lock()
|
orm.mtx.Lock()
|
||||||
defer orm.mtx.Unlock()
|
defer orm.mtx.Unlock()
|
||||||
|
|
||||||
var users []*kolide.User
|
// We need to sort by keys to provide reliable ordering
|
||||||
for _, user := range orm.users {
|
keys := []int{}
|
||||||
users = append(users, user)
|
for k, _ := range orm.users {
|
||||||
|
keys = append(keys, int(k))
|
||||||
}
|
}
|
||||||
|
sort.Ints(keys)
|
||||||
|
|
||||||
|
users := []*kolide.User{}
|
||||||
|
for _, k := range keys {
|
||||||
|
users = append(users, orm.users[uint(k)])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply limit/offset
|
||||||
|
low, high := orm.getLimitOffsetSliceBounds(opt, len(users))
|
||||||
|
users = users[low:high]
|
||||||
|
|
||||||
return users, nil
|
return users, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,3 +32,13 @@ type OrgInfoPayload struct {
|
||||||
OrgName *string `json:"org_name"`
|
OrgName *string `json:"org_name"`
|
||||||
OrgLogoURL *string `json:"org_logo_url"`
|
OrgLogoURL *string `json:"org_logo_url"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ListOptions defines options related to paging and ordering to be used when
|
||||||
|
// listing objects
|
||||||
|
type ListOptions struct {
|
||||||
|
// Which page to return (must be positive integer)
|
||||||
|
Page uint
|
||||||
|
// How many results per page (must be positive integer, 0 indicates
|
||||||
|
// unlimited)
|
||||||
|
PerPage uint
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,14 +11,14 @@ type HostStore interface {
|
||||||
SaveHost(host *Host) error
|
SaveHost(host *Host) error
|
||||||
DeleteHost(host *Host) error
|
DeleteHost(host *Host) error
|
||||||
Host(id uint) (*Host, error)
|
Host(id uint) (*Host, error)
|
||||||
Hosts() ([]*Host, error)
|
Hosts(opt ListOptions) ([]*Host, error)
|
||||||
EnrollHost(uuid, hostname, ip, platform string, nodeKeySize int) (*Host, error)
|
EnrollHost(uuid, hostname, ip, platform string, nodeKeySize int) (*Host, error)
|
||||||
AuthenticateHost(nodeKey string) (*Host, error)
|
AuthenticateHost(nodeKey string) (*Host, error)
|
||||||
MarkHostSeen(host *Host, t time.Time) error
|
MarkHostSeen(host *Host, t time.Time) error
|
||||||
}
|
}
|
||||||
|
|
||||||
type HostService interface {
|
type HostService interface {
|
||||||
ListHosts(ctx context.Context) ([]*Host, error)
|
ListHosts(ctx context.Context, opt ListOptions) ([]*Host, error)
|
||||||
GetHost(ctx context.Context, id uint) (*Host, error)
|
GetHost(ctx context.Context, id uint) (*Host, error)
|
||||||
HostStatus(ctx context.Context, host Host) string
|
HostStatus(ctx context.Context, host Host) string
|
||||||
DeleteHost(ctx context.Context, id uint) error
|
DeleteHost(ctx context.Context, id uint) error
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ type InviteStore interface {
|
||||||
NewInvite(i *Invite) (*Invite, error)
|
NewInvite(i *Invite) (*Invite, error)
|
||||||
|
|
||||||
// Invites lists all invites in the datastore.
|
// Invites lists all invites in the datastore.
|
||||||
Invites() ([]*Invite, error)
|
Invites(opt ListOptions) ([]*Invite, error)
|
||||||
|
|
||||||
// Invite retrieves an invite by it's ID.
|
// Invite retrieves an invite by it's ID.
|
||||||
Invite(id uint) (*Invite, error)
|
Invite(id uint) (*Invite, error)
|
||||||
|
|
@ -40,7 +40,7 @@ type InviteService interface {
|
||||||
DeleteInvite(ctx context.Context, id uint) (err error)
|
DeleteInvite(ctx context.Context, id uint) (err error)
|
||||||
|
|
||||||
// Invites returns a list of all invites.
|
// Invites returns a list of all invites.
|
||||||
Invites(ctx context.Context) (invites []*Invite, err error)
|
ListInvites(ctx context.Context, opt ListOptions) (invites []*Invite, err error)
|
||||||
|
|
||||||
// VerifyInvite verifies that an invite exists and that it matches the
|
// VerifyInvite verifies that an invite exists and that it matches the
|
||||||
// invite token.
|
// invite token.
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ type LabelStore interface {
|
||||||
SaveLabel(Label *Label) error
|
SaveLabel(Label *Label) error
|
||||||
DeleteLabel(lid uint) error
|
DeleteLabel(lid uint) error
|
||||||
Label(lid uint) (*Label, error)
|
Label(lid uint) (*Label, error)
|
||||||
Labels() ([]*Label, error)
|
Labels(opt ListOptions) ([]*Label, error)
|
||||||
|
|
||||||
// LabelQueriesForHost returns the label queries that should be executed
|
// LabelQueriesForHost returns the label queries that should be executed
|
||||||
// for the given host. The cutoff is the minimum timestamp a query
|
// for the given host. The cutoff is the minimum timestamp a query
|
||||||
|
|
@ -32,7 +32,7 @@ type LabelStore interface {
|
||||||
}
|
}
|
||||||
|
|
||||||
type LabelService interface {
|
type LabelService interface {
|
||||||
ListLabels(ctx context.Context) ([]*Label, error)
|
ListLabels(ctx context.Context, opt ListOptions) ([]*Label, error)
|
||||||
GetLabel(ctx context.Context, id uint) (*Label, error)
|
GetLabel(ctx context.Context, id uint) (*Label, error)
|
||||||
NewLabel(ctx context.Context, p LabelPayload) (*Label, error)
|
NewLabel(ctx context.Context, p LabelPayload) (*Label, error)
|
||||||
ModifyLabel(ctx context.Context, id uint, p LabelPayload) (*Label, error)
|
ModifyLabel(ctx context.Context, id uint, p LabelPayload) (*Label, error)
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ type PackStore interface {
|
||||||
SavePack(pack *Pack) error
|
SavePack(pack *Pack) error
|
||||||
DeletePack(pid uint) error
|
DeletePack(pid uint) error
|
||||||
Pack(pid uint) (*Pack, error)
|
Pack(pid uint) (*Pack, error)
|
||||||
Packs() ([]*Pack, error)
|
Packs(opt ListOptions) ([]*Pack, error)
|
||||||
|
|
||||||
// Modifying the queries in packs
|
// Modifying the queries in packs
|
||||||
AddQueryToPack(qid uint, pid uint) error
|
AddQueryToPack(qid uint, pid uint) error
|
||||||
|
|
@ -29,7 +29,7 @@ type PackStore interface {
|
||||||
}
|
}
|
||||||
|
|
||||||
type PackService interface {
|
type PackService interface {
|
||||||
ListPacks(ctx context.Context) ([]*Pack, error)
|
ListPacks(ctx context.Context, opt ListOptions) ([]*Pack, error)
|
||||||
GetPack(ctx context.Context, id uint) (*Pack, error)
|
GetPack(ctx context.Context, id uint) (*Pack, error)
|
||||||
NewPack(ctx context.Context, p PackPayload) (*Pack, error)
|
NewPack(ctx context.Context, p PackPayload) (*Pack, error)
|
||||||
ModifyPack(ctx context.Context, id uint, p PackPayload) (*Pack, error)
|
ModifyPack(ctx context.Context, id uint, p PackPayload) (*Pack, error)
|
||||||
|
|
|
||||||
|
|
@ -12,11 +12,11 @@ type QueryStore interface {
|
||||||
SaveQuery(query *Query) error
|
SaveQuery(query *Query) error
|
||||||
DeleteQuery(query *Query) error
|
DeleteQuery(query *Query) error
|
||||||
Query(id uint) (*Query, error)
|
Query(id uint) (*Query, error)
|
||||||
Queries() ([]*Query, error)
|
Queries(opt ListOptions) ([]*Query, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type QueryService interface {
|
type QueryService interface {
|
||||||
ListQueries(ctx context.Context) ([]*Query, error)
|
ListQueries(ctx context.Context, opt ListOptions) ([]*Query, error)
|
||||||
GetQuery(ctx context.Context, id uint) (*Query, error)
|
GetQuery(ctx context.Context, id uint) (*Query, error)
|
||||||
NewQuery(ctx context.Context, p QueryPayload) (*Query, error)
|
NewQuery(ctx context.Context, p QueryPayload) (*Query, error)
|
||||||
ModifyQuery(ctx context.Context, id uint, p QueryPayload) (*Query, error)
|
ModifyQuery(ctx context.Context, id uint, p QueryPayload) (*Query, error)
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ import (
|
||||||
type UserStore interface {
|
type UserStore interface {
|
||||||
NewUser(user *User) (*User, error)
|
NewUser(user *User) (*User, error)
|
||||||
User(username string) (*User, error)
|
User(username string) (*User, error)
|
||||||
Users() ([]*User, error)
|
Users(opt ListOptions) ([]*User, error)
|
||||||
UserByEmail(email string) (*User, error)
|
UserByEmail(email string) (*User, error)
|
||||||
UserByID(id uint) (*User, error)
|
UserByID(id uint) (*User, error)
|
||||||
SaveUser(user *User) error
|
SaveUser(user *User) error
|
||||||
|
|
@ -33,7 +33,7 @@ type UserService interface {
|
||||||
AuthenticatedUser(ctx context.Context) (user *User, err error)
|
AuthenticatedUser(ctx context.Context) (user *User, err error)
|
||||||
|
|
||||||
// Users returns all users
|
// Users returns all users
|
||||||
Users(ctx context.Context) (users []*User, err error)
|
ListUsers(ctx context.Context, opt ListOptions) (users []*User, err error)
|
||||||
|
|
||||||
// RequestPasswordReset generates a password reset request for
|
// RequestPasswordReset generates a password reset request for
|
||||||
// a user. The request results in a token emailed to the user.
|
// a user. The request results in a token emailed to the user.
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,10 @@ func makeGetHostEndpoint(svc kolide.Service) endpoint.Endpoint {
|
||||||
// List Hosts
|
// List Hosts
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
type listHostsRequest struct {
|
||||||
|
ListOptions kolide.ListOptions
|
||||||
|
}
|
||||||
|
|
||||||
type listHostsResponse struct {
|
type listHostsResponse struct {
|
||||||
Hosts []hostResponse `json:"hosts"`
|
Hosts []hostResponse `json:"hosts"`
|
||||||
Err error `json:"error,omitempty"`
|
Err error `json:"error,omitempty"`
|
||||||
|
|
@ -50,7 +54,8 @@ func (r listHostsResponse) error() error { return r.Err }
|
||||||
|
|
||||||
func makeListHostsEndpoint(svc kolide.Service) endpoint.Endpoint {
|
func makeListHostsEndpoint(svc kolide.Service) endpoint.Endpoint {
|
||||||
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
||||||
hosts, err := svc.ListHosts(ctx)
|
req := request.(listHostsRequest)
|
||||||
|
hosts, err := svc.ListHosts(ctx, req.ListOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return listHostsResponse{Err: err}, nil
|
return listHostsResponse{Err: err}, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,10 @@ func makeCreateInviteEndpoint(svc kolide.Service) endpoint.Endpoint {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type listInvitesRequest struct {
|
||||||
|
ListOptions kolide.ListOptions
|
||||||
|
}
|
||||||
|
|
||||||
type listInvitesResponse struct {
|
type listInvitesResponse struct {
|
||||||
Invites []kolide.Invite `json:"invites"`
|
Invites []kolide.Invite `json:"invites"`
|
||||||
Err error `json:"error,omitempty"`
|
Err error `json:"error,omitempty"`
|
||||||
|
|
@ -37,7 +41,8 @@ func (r listInvitesResponse) error() error { return r.Err }
|
||||||
|
|
||||||
func makeListInvitesEndpoint(svc kolide.Service) endpoint.Endpoint {
|
func makeListInvitesEndpoint(svc kolide.Service) endpoint.Endpoint {
|
||||||
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
||||||
invites, err := svc.Invites(ctx)
|
req := request.(listInvitesRequest)
|
||||||
|
invites, err := svc.ListInvites(ctx, req.ListOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return listInvitesResponse{Err: err}, nil
|
return listInvitesResponse{Err: err}, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,10 @@ func makeGetLabelEndpoint(svc kolide.Service) endpoint.Endpoint {
|
||||||
// List Labels
|
// List Labels
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
type listLabelsRequest struct {
|
||||||
|
ListOptions kolide.ListOptions
|
||||||
|
}
|
||||||
|
|
||||||
type listLabelsResponse struct {
|
type listLabelsResponse struct {
|
||||||
Labels []kolide.Label `json:"labels"`
|
Labels []kolide.Label `json:"labels"`
|
||||||
Err error `json:"error,omitempty"`
|
Err error `json:"error,omitempty"`
|
||||||
|
|
@ -45,7 +49,8 @@ func (r listLabelsResponse) error() error { return r.Err }
|
||||||
|
|
||||||
func makeListLabelsEndpoint(svc kolide.Service) endpoint.Endpoint {
|
func makeListLabelsEndpoint(svc kolide.Service) endpoint.Endpoint {
|
||||||
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
||||||
labels, err := svc.ListLabels(ctx)
|
req := request.(listLabelsRequest)
|
||||||
|
labels, err := svc.ListLabels(ctx, req.ListOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return listLabelsResponse{Err: err}, nil
|
return listLabelsResponse{Err: err}, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,10 @@ func makeGetPackEndpoint(svc kolide.Service) endpoint.Endpoint {
|
||||||
// List Packs
|
// List Packs
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
type listPacksRequest struct {
|
||||||
|
ListOptions kolide.ListOptions
|
||||||
|
}
|
||||||
|
|
||||||
type listPacksResponse struct {
|
type listPacksResponse struct {
|
||||||
Packs []kolide.Pack `json:"packs"`
|
Packs []kolide.Pack `json:"packs"`
|
||||||
Err error `json:"error,omitempty"`
|
Err error `json:"error,omitempty"`
|
||||||
|
|
@ -45,7 +49,8 @@ func (r listPacksResponse) error() error { return r.Err }
|
||||||
|
|
||||||
func makeListPacksEndpoint(svc kolide.Service) endpoint.Endpoint {
|
func makeListPacksEndpoint(svc kolide.Service) endpoint.Endpoint {
|
||||||
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
||||||
packs, err := svc.ListPacks(ctx)
|
req := request.(listPacksRequest)
|
||||||
|
packs, err := svc.ListPacks(ctx, req.ListOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return getPackResponse{Err: err}, nil
|
return getPackResponse{Err: err}, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,9 @@ func makeGetQueryEndpoint(svc kolide.Service) endpoint.Endpoint {
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// List Queries
|
// List Queries
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
type listQueriesRequest struct {
|
||||||
|
ListOptions kolide.ListOptions
|
||||||
|
}
|
||||||
|
|
||||||
type listQueriesResponse struct {
|
type listQueriesResponse struct {
|
||||||
Queries []kolide.Query `json:"queries"`
|
Queries []kolide.Query `json:"queries"`
|
||||||
|
|
@ -45,7 +48,8 @@ func (r listQueriesResponse) error() error { return r.Err }
|
||||||
|
|
||||||
func makeListQueriesEndpoint(svc kolide.Service) endpoint.Endpoint {
|
func makeListQueriesEndpoint(svc kolide.Service) endpoint.Endpoint {
|
||||||
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
||||||
queries, err := svc.ListQueries(ctx)
|
req := request.(listQueriesRequest)
|
||||||
|
queries, err := svc.ListQueries(ctx, req.ListOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return listQueriesResponse{Err: err}, nil
|
return listQueriesResponse{Err: err}, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -74,6 +74,10 @@ func makeGetSessionUserEndpoint(svc kolide.Service) endpoint.Endpoint {
|
||||||
// List Users
|
// List Users
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
type listUsersRequest struct {
|
||||||
|
ListOptions kolide.ListOptions
|
||||||
|
}
|
||||||
|
|
||||||
type listUsersResponse struct {
|
type listUsersResponse struct {
|
||||||
Users []kolide.User `json:"users"`
|
Users []kolide.User `json:"users"`
|
||||||
Err error `json:"error,omitempty"`
|
Err error `json:"error,omitempty"`
|
||||||
|
|
@ -83,7 +87,8 @@ func (r listUsersResponse) error() error { return r.Err }
|
||||||
|
|
||||||
func makeListUsersEndpoint(svc kolide.Service) endpoint.Endpoint {
|
func makeListUsersEndpoint(svc kolide.Service) endpoint.Endpoint {
|
||||||
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
return func(ctx context.Context, request interface{}) (interface{}, error) {
|
||||||
users, err := svc.Users(ctx)
|
req := request.(listUsersRequest)
|
||||||
|
users, err := svc.ListUsers(ctx, req.ListOptions)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return listUsersResponse{Err: err}, nil
|
return listUsersResponse{Err: err}, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -181,7 +181,7 @@ func makeKolideKitHandlers(ctx context.Context, e KolideEndpoints, opts []kithtt
|
||||||
Me: newServer(e.Me, decodeNoParamsRequest),
|
Me: newServer(e.Me, decodeNoParamsRequest),
|
||||||
CreateUser: newServer(e.CreateUser, decodeCreateUserRequest),
|
CreateUser: newServer(e.CreateUser, decodeCreateUserRequest),
|
||||||
GetUser: newServer(e.GetUser, decodeGetUserRequest),
|
GetUser: newServer(e.GetUser, decodeGetUserRequest),
|
||||||
ListUsers: newServer(e.ListUsers, decodeNoParamsRequest),
|
ListUsers: newServer(e.ListUsers, decodeListUsersRequest),
|
||||||
ModifyUser: newServer(e.ModifyUser, decodeModifyUserRequest),
|
ModifyUser: newServer(e.ModifyUser, decodeModifyUserRequest),
|
||||||
GetSessionsForUserInfo: newServer(e.GetSessionsForUserInfo, decodeGetInfoAboutSessionsForUserRequest),
|
GetSessionsForUserInfo: newServer(e.GetSessionsForUserInfo, decodeGetInfoAboutSessionsForUserRequest),
|
||||||
DeleteSessionsForUser: newServer(e.DeleteSessionsForUser, decodeDeleteSessionsForUserRequest),
|
DeleteSessionsForUser: newServer(e.DeleteSessionsForUser, decodeDeleteSessionsForUserRequest),
|
||||||
|
|
@ -190,15 +190,15 @@ func makeKolideKitHandlers(ctx context.Context, e KolideEndpoints, opts []kithtt
|
||||||
GetAppConfig: newServer(e.GetAppConfig, decodeNoParamsRequest),
|
GetAppConfig: newServer(e.GetAppConfig, decodeNoParamsRequest),
|
||||||
ModifyAppConfig: newServer(e.ModifyAppConfig, decodeModifyAppConfigRequest),
|
ModifyAppConfig: newServer(e.ModifyAppConfig, decodeModifyAppConfigRequest),
|
||||||
CreateInvite: newServer(e.CreateInvite, decodeCreateInviteRequest),
|
CreateInvite: newServer(e.CreateInvite, decodeCreateInviteRequest),
|
||||||
ListInvites: newServer(e.ListInvites, decodeNoParamsRequest),
|
ListInvites: newServer(e.ListInvites, decodeListInvitesRequest),
|
||||||
DeleteInvite: newServer(e.DeleteInvite, decodeDeleteInviteRequest),
|
DeleteInvite: newServer(e.DeleteInvite, decodeDeleteInviteRequest),
|
||||||
GetQuery: newServer(e.GetQuery, decodeGetQueryRequest),
|
GetQuery: newServer(e.GetQuery, decodeGetQueryRequest),
|
||||||
ListQueries: newServer(e.ListQueries, decodeNoParamsRequest),
|
ListQueries: newServer(e.ListQueries, decodeListQueriesRequest),
|
||||||
CreateQuery: newServer(e.CreateQuery, decodeCreateQueryRequest),
|
CreateQuery: newServer(e.CreateQuery, decodeCreateQueryRequest),
|
||||||
ModifyQuery: newServer(e.ModifyQuery, decodeModifyQueryRequest),
|
ModifyQuery: newServer(e.ModifyQuery, decodeModifyQueryRequest),
|
||||||
DeleteQuery: newServer(e.DeleteQuery, decodeDeleteQueryRequest),
|
DeleteQuery: newServer(e.DeleteQuery, decodeDeleteQueryRequest),
|
||||||
GetPack: newServer(e.GetPack, decodeGetPackRequest),
|
GetPack: newServer(e.GetPack, decodeGetPackRequest),
|
||||||
ListPacks: newServer(e.ListPacks, decodeNoParamsRequest),
|
ListPacks: newServer(e.ListPacks, decodeListPacksRequest),
|
||||||
CreatePack: newServer(e.CreatePack, decodeCreatePackRequest),
|
CreatePack: newServer(e.CreatePack, decodeCreatePackRequest),
|
||||||
ModifyPack: newServer(e.ModifyPack, decodeModifyPackRequest),
|
ModifyPack: newServer(e.ModifyPack, decodeModifyPackRequest),
|
||||||
DeletePack: newServer(e.DeletePack, decodeDeletePackRequest),
|
DeletePack: newServer(e.DeletePack, decodeDeletePackRequest),
|
||||||
|
|
@ -211,7 +211,7 @@ func makeKolideKitHandlers(ctx context.Context, e KolideEndpoints, opts []kithtt
|
||||||
SubmitDistributedQueryResults: newServer(e.SubmitDistributedQueryResults, decodeSubmitDistributedQueryResultsRequest),
|
SubmitDistributedQueryResults: newServer(e.SubmitDistributedQueryResults, decodeSubmitDistributedQueryResultsRequest),
|
||||||
SubmitLogs: newServer(e.SubmitLogs, decodeSubmitLogsRequest),
|
SubmitLogs: newServer(e.SubmitLogs, decodeSubmitLogsRequest),
|
||||||
GetLabel: newServer(e.GetLabel, decodeGetLabelRequest),
|
GetLabel: newServer(e.GetLabel, decodeGetLabelRequest),
|
||||||
ListLabels: newServer(e.ListLabels, decodeNoParamsRequest),
|
ListLabels: newServer(e.ListLabels, decodeListLabelsRequest),
|
||||||
CreateLabel: newServer(e.CreateLabel, decodeCreateLabelRequest),
|
CreateLabel: newServer(e.CreateLabel, decodeCreateLabelRequest),
|
||||||
ModifyLabel: newServer(e.ModifyLabel, decodeModifyLabelRequest),
|
ModifyLabel: newServer(e.ModifyLabel, decodeModifyLabelRequest),
|
||||||
DeleteLabel: newServer(e.DeleteLabel, decodeDeleteLabelRequest),
|
DeleteLabel: newServer(e.DeleteLabel, decodeDeleteLabelRequest),
|
||||||
|
|
@ -220,7 +220,7 @@ func makeKolideKitHandlers(ctx context.Context, e KolideEndpoints, opts []kithtt
|
||||||
DeleteLabelFromPack: newServer(e.DeleteLabelFromPack, decodeDeleteLabelFromPackRequest),
|
DeleteLabelFromPack: newServer(e.DeleteLabelFromPack, decodeDeleteLabelFromPackRequest),
|
||||||
GetHost: newServer(e.GetHost, decodeGetHostRequest),
|
GetHost: newServer(e.GetHost, decodeGetHostRequest),
|
||||||
DeleteHost: newServer(e.DeleteHost, decodeDeleteHostRequest),
|
DeleteHost: newServer(e.DeleteHost, decodeDeleteHostRequest),
|
||||||
ListHosts: newServer(e.ListHosts, decodeNoParamsRequest),
|
ListHosts: newServer(e.ListHosts, decodeListHostsRequest),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ func (mw loggingMiddleware) Invites(ctx context.Context) ([]*kolide.Invite, erro
|
||||||
"took", time.Since(begin),
|
"took", time.Since(begin),
|
||||||
)
|
)
|
||||||
}(time.Now())
|
}(time.Now())
|
||||||
invites, err = mw.Service.Invites(ctx)
|
invites, err = mw.Service.ListInvites(ctx, kolide.ListOptions{})
|
||||||
return invites, err
|
return invites, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ func (mw metricsMiddleware) DeleteInvite(ctx context.Context, id uint) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mw metricsMiddleware) Invites(ctx context.Context) ([]*kolide.Invite, error) {
|
func (mw metricsMiddleware) ListInvites(ctx context.Context, opt kolide.ListOptions) ([]*kolide.Invite, error) {
|
||||||
var (
|
var (
|
||||||
invites []*kolide.Invite
|
invites []*kolide.Invite
|
||||||
err error
|
err error
|
||||||
|
|
@ -45,7 +45,7 @@ func (mw metricsMiddleware) Invites(ctx context.Context) ([]*kolide.Invite, erro
|
||||||
mw.requestCount.With(lvs...).Add(1)
|
mw.requestCount.With(lvs...).Add(1)
|
||||||
mw.requestLatency.With(lvs...).Observe(time.Since(begin).Seconds())
|
mw.requestLatency.With(lvs...).Observe(time.Since(begin).Seconds())
|
||||||
}(time.Now())
|
}(time.Now())
|
||||||
invites, err = mw.Service.Invites(ctx)
|
invites, err = mw.Service.ListInvites(ctx, opt)
|
||||||
return invites, err
|
return invites, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ func (mw metricsMiddleware) User(ctx context.Context, id uint) (*kolide.User, er
|
||||||
return user, err
|
return user, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mw metricsMiddleware) Users(ctx context.Context) ([]*kolide.User, error) {
|
func (mw metricsMiddleware) ListUsers(ctx context.Context, opt kolide.ListOptions) ([]*kolide.User, error) {
|
||||||
|
|
||||||
var (
|
var (
|
||||||
users []*kolide.User
|
users []*kolide.User
|
||||||
|
|
@ -67,7 +67,7 @@ func (mw metricsMiddleware) Users(ctx context.Context) ([]*kolide.User, error) {
|
||||||
mw.requestLatency.With(lvs...).Observe(time.Since(begin).Seconds())
|
mw.requestLatency.With(lvs...).Observe(time.Since(begin).Seconds())
|
||||||
}(time.Now())
|
}(time.Now())
|
||||||
|
|
||||||
users, err = mw.Service.Users(ctx)
|
users, err = mw.Service.ListUsers(ctx, opt)
|
||||||
return users, err
|
return users, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,8 @@ import (
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (svc service) ListHosts(ctx context.Context) ([]*kolide.Host, error) {
|
func (svc service) ListHosts(ctx context.Context, opt kolide.ListOptions) ([]*kolide.Host, error) {
|
||||||
return svc.ds.Hosts()
|
return svc.ds.Hosts(opt)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc service) GetHost(ctx context.Context, id uint) (*kolide.Host, error) {
|
func (svc service) GetHost(ctx context.Context, id uint) (*kolide.Host, error) {
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ func TestListHosts(t *testing.T) {
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
hosts, err := svc.ListHosts(ctx)
|
hosts, err := svc.ListHosts(ctx, kolide.ListOptions{})
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Len(t, hosts, 0)
|
assert.Len(t, hosts, 0)
|
||||||
|
|
||||||
|
|
@ -27,7 +27,7 @@ func TestListHosts(t *testing.T) {
|
||||||
})
|
})
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
hosts, err = svc.ListHosts(ctx)
|
hosts, err = svc.ListHosts(ctx, kolide.ListOptions{})
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Len(t, hosts, 1)
|
assert.Len(t, hosts, 1)
|
||||||
}
|
}
|
||||||
|
|
@ -71,7 +71,7 @@ func TestDeleteHost(t *testing.T) {
|
||||||
err = svc.DeleteHost(ctx, host.ID)
|
err = svc.DeleteHost(ctx, host.ID)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
hosts, err := ds.Hosts()
|
hosts, err := ds.Hosts(kolide.ListOptions{})
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Len(t, hosts, 0)
|
assert.Len(t, hosts, 0)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -61,8 +61,8 @@ func (svc service) InviteNewUser(ctx context.Context, payload kolide.InvitePaylo
|
||||||
return invite, nil
|
return invite, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc service) Invites(ctx context.Context) ([]*kolide.Invite, error) {
|
func (svc service) ListInvites(ctx context.Context, opt kolide.ListOptions) ([]*kolide.Invite, error) {
|
||||||
return svc.ds.Invites()
|
return svc.ds.Invites(opt)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc service) VerifyInvite(ctx context.Context, email, token string) error {
|
func (svc service) VerifyInvite(ctx context.Context, email, token string) error {
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@ import (
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (svc service) ListLabels(ctx context.Context) ([]*kolide.Label, error) {
|
func (svc service) ListLabels(ctx context.Context, opt kolide.ListOptions) ([]*kolide.Label, error) {
|
||||||
return svc.ds.Labels()
|
return svc.ds.Labels(opt)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc service) GetLabel(ctx context.Context, id uint) (*kolide.Label, error) {
|
func (svc service) GetLabel(ctx context.Context, id uint) (*kolide.Label, error) {
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ func TestListLabels(t *testing.T) {
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
labels, err := svc.ListLabels(ctx)
|
labels, err := svc.ListLabels(ctx, kolide.ListOptions{})
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Len(t, labels, 0)
|
assert.Len(t, labels, 0)
|
||||||
|
|
||||||
|
|
@ -28,7 +28,7 @@ func TestListLabels(t *testing.T) {
|
||||||
})
|
})
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
labels, err = svc.ListLabels(ctx)
|
labels, err = svc.ListLabels(ctx, kolide.ListOptions{})
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Len(t, labels, 1)
|
assert.Len(t, labels, 1)
|
||||||
assert.Equal(t, "foo", labels[0].Name)
|
assert.Equal(t, "foo", labels[0].Name)
|
||||||
|
|
@ -75,7 +75,7 @@ func TestNewLabel(t *testing.T) {
|
||||||
|
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
labels, err := ds.Labels()
|
labels, err := ds.Labels(kolide.ListOptions{})
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Len(t, labels, 1)
|
assert.Len(t, labels, 1)
|
||||||
assert.Equal(t, "foo", labels[0].Name)
|
assert.Equal(t, "foo", labels[0].Name)
|
||||||
|
|
@ -127,7 +127,7 @@ func TestDeleteLabel(t *testing.T) {
|
||||||
err = svc.DeleteLabel(ctx, label.ID)
|
err = svc.DeleteLabel(ctx, label.ID)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
labels, err := ds.Labels()
|
labels, err := ds.Labels(kolide.ListOptions{})
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Len(t, labels, 0)
|
assert.Len(t, labels, 0)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ func TestEnrollAgent(t *testing.T) {
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
hosts, err := ds.Hosts()
|
hosts, err := ds.Hosts(kolide.ListOptions{})
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Len(t, hosts, 0)
|
assert.Len(t, hosts, 0)
|
||||||
|
|
||||||
|
|
@ -34,7 +34,7 @@ func TestEnrollAgent(t *testing.T) {
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.NotEmpty(t, nodeKey)
|
assert.NotEmpty(t, nodeKey)
|
||||||
|
|
||||||
hosts, err = ds.Hosts()
|
hosts, err = ds.Hosts(kolide.ListOptions{})
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Len(t, hosts, 1)
|
assert.Len(t, hosts, 1)
|
||||||
}
|
}
|
||||||
|
|
@ -48,7 +48,7 @@ func TestEnrollAgentIncorrectEnrollSecret(t *testing.T) {
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
hosts, err := ds.Hosts()
|
hosts, err := ds.Hosts(kolide.ListOptions{})
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Len(t, hosts, 0)
|
assert.Len(t, hosts, 0)
|
||||||
|
|
||||||
|
|
@ -56,7 +56,7 @@ func TestEnrollAgentIncorrectEnrollSecret(t *testing.T) {
|
||||||
assert.NotNil(t, err)
|
assert.NotNil(t, err)
|
||||||
assert.Empty(t, nodeKey)
|
assert.Empty(t, nodeKey)
|
||||||
|
|
||||||
hosts, err = ds.Hosts()
|
hosts, err = ds.Hosts(kolide.ListOptions{})
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Len(t, hosts, 0)
|
assert.Len(t, hosts, 0)
|
||||||
}
|
}
|
||||||
|
|
@ -75,7 +75,7 @@ func TestSubmitStatusLogs(t *testing.T) {
|
||||||
_, err = svc.EnrollAgent(ctx, "", "host123")
|
_, err = svc.EnrollAgent(ctx, "", "host123")
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
hosts, err := ds.Hosts()
|
hosts, err := ds.Hosts(kolide.ListOptions{})
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
require.Len(t, hosts, 1)
|
require.Len(t, hosts, 1)
|
||||||
host := hosts[0]
|
host := hosts[0]
|
||||||
|
|
@ -147,7 +147,7 @@ func TestSubmitResultLogs(t *testing.T) {
|
||||||
_, err = svc.EnrollAgent(ctx, "", "host123")
|
_, err = svc.EnrollAgent(ctx, "", "host123")
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
hosts, err := ds.Hosts()
|
hosts, err := ds.Hosts(kolide.ListOptions{})
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
require.Len(t, hosts, 1)
|
require.Len(t, hosts, 1)
|
||||||
host := hosts[0]
|
host := hosts[0]
|
||||||
|
|
@ -248,7 +248,7 @@ func TestLabelQueries(t *testing.T) {
|
||||||
_, err = svc.EnrollAgent(ctx, "", "host123")
|
_, err = svc.EnrollAgent(ctx, "", "host123")
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
hosts, err := ds.Hosts()
|
hosts, err := ds.Hosts(kolide.ListOptions{})
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
require.Len(t, hosts, 1)
|
require.Len(t, hosts, 1)
|
||||||
host := hosts[0]
|
host := hosts[0]
|
||||||
|
|
@ -410,14 +410,14 @@ func TestGetClientConfig(t *testing.T) {
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
hosts, err := ds.Hosts()
|
hosts, err := ds.Hosts(kolide.ListOptions{})
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
require.Len(t, hosts, 0)
|
require.Len(t, hosts, 0)
|
||||||
|
|
||||||
_, err = svc.EnrollAgent(ctx, "", "user.local")
|
_, err = svc.EnrollAgent(ctx, "", "user.local")
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
hosts, err = ds.Hosts()
|
hosts, err = ds.Hosts(kolide.ListOptions{})
|
||||||
require.Nil(t, err)
|
require.Nil(t, err)
|
||||||
require.Len(t, hosts, 1)
|
require.Len(t, hosts, 1)
|
||||||
host := hosts[0]
|
host := hosts[0]
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@ import (
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (svc service) ListPacks(ctx context.Context) ([]*kolide.Pack, error) {
|
func (svc service) ListPacks(ctx context.Context, opt kolide.ListOptions) ([]*kolide.Pack, error) {
|
||||||
return svc.ds.Packs()
|
return svc.ds.Packs(opt)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc service) GetPack(ctx context.Context, id uint) (*kolide.Pack, error) {
|
func (svc service) GetPack(ctx context.Context, id uint) (*kolide.Pack, error) {
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ func TestListPacks(t *testing.T) {
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
queries, err := svc.ListPacks(ctx)
|
queries, err := svc.ListPacks(ctx, kolide.ListOptions{})
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Len(t, queries, 0)
|
assert.Len(t, queries, 0)
|
||||||
|
|
||||||
|
|
@ -27,7 +27,7 @@ func TestListPacks(t *testing.T) {
|
||||||
})
|
})
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
queries, err = svc.ListPacks(ctx)
|
queries, err = svc.ListPacks(ctx, kolide.ListOptions{})
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Len(t, queries, 1)
|
assert.Len(t, queries, 1)
|
||||||
}
|
}
|
||||||
|
|
@ -70,7 +70,7 @@ func TestNewPack(t *testing.T) {
|
||||||
|
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
queries, err := ds.Packs()
|
queries, err := ds.Packs(kolide.ListOptions{})
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Len(t, queries, 1)
|
assert.Len(t, queries, 1)
|
||||||
}
|
}
|
||||||
|
|
@ -120,7 +120,7 @@ func TestDeletePack(t *testing.T) {
|
||||||
err = svc.DeletePack(ctx, pack.ID)
|
err = svc.DeletePack(ctx, pack.ID)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
queries, err := ds.Packs()
|
queries, err := ds.Packs(kolide.ListOptions{})
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Len(t, queries, 0)
|
assert.Len(t, queries, 0)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@ import (
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (svc service) ListQueries(ctx context.Context) ([]*kolide.Query, error) {
|
func (svc service) ListQueries(ctx context.Context, opt kolide.ListOptions) ([]*kolide.Query, error) {
|
||||||
return svc.ds.Queries()
|
return svc.ds.Queries(opt)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc service) GetQuery(ctx context.Context, id uint) (*kolide.Query, error) {
|
func (svc service) GetQuery(ctx context.Context, id uint) (*kolide.Query, error) {
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ func TestListQueries(t *testing.T) {
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
queries, err := svc.ListQueries(ctx)
|
queries, err := svc.ListQueries(ctx, kolide.ListOptions{})
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Len(t, queries, 0)
|
assert.Len(t, queries, 0)
|
||||||
|
|
||||||
|
|
@ -28,7 +28,7 @@ func TestListQueries(t *testing.T) {
|
||||||
})
|
})
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
queries, err = svc.ListQueries(ctx)
|
queries, err = svc.ListQueries(ctx, kolide.ListOptions{})
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Len(t, queries, 1)
|
assert.Len(t, queries, 1)
|
||||||
}
|
}
|
||||||
|
|
@ -74,7 +74,7 @@ func TestNewQuery(t *testing.T) {
|
||||||
|
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
queries, err := ds.Queries()
|
queries, err := ds.Queries(kolide.ListOptions{})
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Len(t, queries, 1)
|
assert.Len(t, queries, 1)
|
||||||
}
|
}
|
||||||
|
|
@ -126,7 +126,7 @@ func TestDeleteQuery(t *testing.T) {
|
||||||
err = svc.DeleteQuery(ctx, query.ID)
|
err = svc.DeleteQuery(ctx, query.ID)
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
|
|
||||||
queries, err := ds.Queries()
|
queries, err := ds.Queries(kolide.ListOptions{})
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Len(t, queries, 0)
|
assert.Len(t, queries, 0)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -115,8 +115,8 @@ func (svc service) AuthenticatedUser(ctx context.Context) (*kolide.User, error)
|
||||||
return vc.User, nil
|
return vc.User, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc service) Users(ctx context.Context) ([]*kolide.User, error) {
|
func (svc service) ListUsers(ctx context.Context, opt kolide.ListOptions) ([]*kolide.User, error) {
|
||||||
return svc.ds.Users()
|
return svc.ds.Users(opt)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (svc service) ResetPassword(ctx context.Context, token, password string) error {
|
func (svc service) ResetPassword(ctx context.Context, token, password string) error {
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
|
"github.com/kolide/kolide-ose/server/kolide"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -52,6 +53,50 @@ func idFromRequest(r *http.Request, name string) (uint, error) {
|
||||||
return uint(uid), nil
|
return uint(uid), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// default number of items to include per page
|
||||||
|
const defaultPerPage = 20
|
||||||
|
|
||||||
|
// listOptionsFromRequest parses the list options from the request parameters
|
||||||
|
func listOptionsFromRequest(r *http.Request) (kolide.ListOptions, error) {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
pageString := r.URL.Query().Get("page")
|
||||||
|
perPageString := r.URL.Query().Get("per_page")
|
||||||
|
|
||||||
|
var page int = 0
|
||||||
|
if pageString != "" {
|
||||||
|
page, err = strconv.Atoi(pageString)
|
||||||
|
if err != nil {
|
||||||
|
return kolide.ListOptions{}, errors.New("non-int page value")
|
||||||
|
}
|
||||||
|
if page < 0 {
|
||||||
|
return kolide.ListOptions{}, errors.New("negative page value")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// We default to 0 for per_page so that not specifying any paging
|
||||||
|
// information gets all results
|
||||||
|
var perPage int = 0
|
||||||
|
if perPageString != "" {
|
||||||
|
perPage, err = strconv.Atoi(perPageString)
|
||||||
|
if err != nil {
|
||||||
|
return kolide.ListOptions{}, errors.New("non-int per_page value")
|
||||||
|
}
|
||||||
|
if perPage <= 0 {
|
||||||
|
return kolide.ListOptions{}, errors.New("invalid per_page value")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if perPage == 0 && pageString != "" {
|
||||||
|
// We explicitly set a non-zero default if a page is specified
|
||||||
|
// (because the client probably intended for paging, and
|
||||||
|
// leaving the 0 would turn that off)
|
||||||
|
perPage = defaultPerPage
|
||||||
|
}
|
||||||
|
|
||||||
|
return kolide.ListOptions{Page: uint(page), PerPage: uint(perPage)}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func decodeNoParamsRequest(ctx context.Context, r *http.Request) (interface{}, error) {
|
func decodeNoParamsRequest(ctx context.Context, r *http.Request) (interface{}, error) {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,3 +21,11 @@ func decodeDeleteHostRequest(ctx context.Context, r *http.Request) (interface{},
|
||||||
}
|
}
|
||||||
return deleteHostRequest{ID: id}, nil
|
return deleteHostRequest{ID: id}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func decodeListHostsRequest(ctx context.Context, r *http.Request) (interface{}, error) {
|
||||||
|
opt, err := listOptionsFromRequest(r)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return listHostsRequest{ListOptions: opt}, nil
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,3 +32,11 @@ func decodeDeleteInviteRequest(ctx context.Context, r *http.Request) (interface{
|
||||||
req.ID = id
|
req.ID = id
|
||||||
return req, nil
|
return req, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func decodeListInvitesRequest(ctx context.Context, r *http.Request) (interface{}, error) {
|
||||||
|
opt, err := listOptionsFromRequest(r)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return listInvitesRequest{ListOptions: opt}, nil
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -47,3 +47,11 @@ func decodeGetLabelRequest(ctx context.Context, r *http.Request) (interface{}, e
|
||||||
req.ID = id
|
req.ID = id
|
||||||
return req, nil
|
return req, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func decodeListLabelsRequest(ctx context.Context, r *http.Request) (interface{}, error) {
|
||||||
|
opt, err := listOptionsFromRequest(r)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return listLabelsRequest{ListOptions: opt}, nil
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,14 @@ func decodeGetPackRequest(ctx context.Context, r *http.Request) (interface{}, er
|
||||||
return req, nil
|
return req, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func decodeListPacksRequest(ctx context.Context, r *http.Request) (interface{}, error) {
|
||||||
|
opt, err := listOptionsFromRequest(r)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return listPacksRequest{ListOptions: opt}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func decodeAddQueryToPackRequest(ctx context.Context, r *http.Request) (interface{}, error) {
|
func decodeAddQueryToPackRequest(ctx context.Context, r *http.Request) (interface{}, error) {
|
||||||
qid, err := idFromRequest(r, "qid")
|
qid, err := idFromRequest(r, "qid")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -47,3 +47,11 @@ func decodeGetQueryRequest(ctx context.Context, r *http.Request) (interface{}, e
|
||||||
req.ID = id
|
req.ID = id
|
||||||
return req, nil
|
return req, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func decodeListQueriesRequest(ctx context.Context, r *http.Request) (interface{}, error) {
|
||||||
|
opt, err := listOptionsFromRequest(r)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return listQueriesRequest{ListOptions: opt}, nil
|
||||||
|
}
|
||||||
|
|
|
||||||
78
server/service/transport_test.go
Normal file
78
server/service/transport_test.go
Normal file
|
|
@ -0,0 +1,78 @@
|
||||||
|
package service
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/kolide/kolide-ose/server/kolide"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestListOptionsFromRequest(t *testing.T) {
|
||||||
|
var listOptionsTests = []struct {
|
||||||
|
// url string to parse
|
||||||
|
url string
|
||||||
|
// expected list options
|
||||||
|
listOptions kolide.ListOptions
|
||||||
|
// should cause an error
|
||||||
|
shouldErr bool
|
||||||
|
}{
|
||||||
|
// both params provided
|
||||||
|
{
|
||||||
|
url: "/foo?page=1&per_page=10",
|
||||||
|
listOptions: kolide.ListOptions{Page: 1, PerPage: 10},
|
||||||
|
},
|
||||||
|
// only per_page (page should default to 0)
|
||||||
|
{
|
||||||
|
url: "/foo?per_page=10",
|
||||||
|
listOptions: kolide.ListOptions{Page: 0, PerPage: 10},
|
||||||
|
},
|
||||||
|
// only page (per_page should default to defaultPerPage
|
||||||
|
{
|
||||||
|
url: "/foo?page=10",
|
||||||
|
listOptions: kolide.ListOptions{Page: 10, PerPage: defaultPerPage},
|
||||||
|
},
|
||||||
|
// no params provided (defaults to empty ListOptions indicating
|
||||||
|
// unlimited)
|
||||||
|
{
|
||||||
|
url: "/foo?unrelated=foo",
|
||||||
|
listOptions: kolide.ListOptions{},
|
||||||
|
},
|
||||||
|
|
||||||
|
// various error cases
|
||||||
|
{
|
||||||
|
url: "/foo?page=foo&per_page=10",
|
||||||
|
shouldErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: "/foo?page=1&per_page=foo",
|
||||||
|
shouldErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: "/foo?page=-1",
|
||||||
|
shouldErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
url: "/foo?page=-1&per_page=-10",
|
||||||
|
shouldErr: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range listOptionsTests {
|
||||||
|
t.Run(tt.url, func(t *testing.T) {
|
||||||
|
url, _ := url.Parse(tt.url)
|
||||||
|
req := &http.Request{URL: url}
|
||||||
|
opt, err := listOptionsFromRequest(req)
|
||||||
|
|
||||||
|
if tt.shouldErr {
|
||||||
|
assert.NotNil(t, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.Nil(t, err)
|
||||||
|
assert.Equal(t, tt.listOptions, opt)
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -24,6 +24,14 @@ func decodeGetUserRequest(ctx context.Context, r *http.Request) (interface{}, er
|
||||||
return getUserRequest{ID: id}, nil
|
return getUserRequest{ID: id}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func decodeListUsersRequest(ctx context.Context, r *http.Request) (interface{}, error) {
|
||||||
|
opt, err := listOptionsFromRequest(r)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return listUsersRequest{ListOptions: opt}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func decodeChangePasswordRequest(ctx context.Context, r *http.Request) (interface{}, error) {
|
func decodeChangePasswordRequest(ctx context.Context, r *http.Request) (interface{}, error) {
|
||||||
var req resetPasswordRequest
|
var req resetPasswordRequest
|
||||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue