Skip to content

Commit

Permalink
Add pagination params
Browse files Browse the repository at this point in the history
  • Loading branch information
domenipavec committed Apr 7, 2022
1 parent 7e2387d commit d425557
Show file tree
Hide file tree
Showing 10 changed files with 88 additions and 11 deletions.
4 changes: 3 additions & 1 deletion cmd/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"os"

"github.com/cloudradar-monitoring/rportcli/internal/pkg/api"
"github.com/cloudradar-monitoring/rportcli/internal/pkg/client"

"github.com/cloudradar-monitoring/rportcli/internal/pkg/config"
Expand All @@ -17,6 +18,7 @@ import (
)

func init() {
addPaginationFlags(clientsListCmd, api.ClientsLimitDefault)
clientsCmd.AddCommand(clientsListCmd)
clientCmd.Flags().StringP(controllers.ClientNameFlag, "n", "", "Get client by name")
clientCmd.Flags().BoolP("all", "a", false, "Show client info with additional details")
Expand Down Expand Up @@ -57,7 +59,7 @@ var clientsListCmd = &cobra.Command{
ctx, cancel := buildContext(context.Background())
defer cancel()

return clientsController.Clients(ctx)
return clientsController.Clients(ctx, params)
},
}

Expand Down
11 changes: 11 additions & 0 deletions cmd/pagination.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package cmd

import (
"github.com/cloudradar-monitoring/rportcli/internal/pkg/api"
"github.com/spf13/cobra"
)

func addPaginationFlags(cmd *cobra.Command, defaultLimit int) {
cmd.Flags().IntP(api.PaginationLimit, "", defaultLimit, "Number of items to fetch")
cmd.Flags().IntP(api.PaginationOffset, "", 0, "Offset for fetch")
}
2 changes: 2 additions & 0 deletions cmd/tunnel.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"os/signal"
"syscall"

"github.com/cloudradar-monitoring/rportcli/internal/pkg/api"
"github.com/cloudradar-monitoring/rportcli/internal/pkg/rdp"

"github.com/cloudradar-monitoring/rportcli/internal/pkg/client"
Expand All @@ -31,6 +32,7 @@ func init() {
config.DefineCommandInputs(tunnelCreateCmd, getCreateTunnelRequirements())
tunnelsCmd.AddCommand(tunnelCreateCmd)

addPaginationFlags(tunnelListCmd, api.ClientsLimitDefault)
tunnelListCmd.Flags().StringP(controllers.ClientNameFlag, "n", "", "Get tunnels of a client by name")
tunnelListCmd.Flags().StringP(controllers.ClientID, "c", "", "Get tunnels of a client by client id")

Expand Down
9 changes: 6 additions & 3 deletions internal/pkg/api/clients.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,24 @@ import (
)

const (
ClientsURL = "/api/v1/clients"
ClientsURL = "/api/v1/clients"
ClientsLimitDefault = 50
ClientsLimitMax = 500
)

type ClientsResponse struct {
Data []*models.Client
}

func (rp *Rport) Clients(ctx context.Context) (cr *ClientsResponse, err error) {
func (rp *Rport) Clients(ctx context.Context, pagination Pagination) (cr *ClientsResponse, err error) {
var req *http.Request
u, err := url2.Parse(url.JoinURL(rp.BaseURL, ClientsURL))
if err != nil {
return nil, err
}
q := u.Query()
q.Set("fields[clients]", "id,name,timezone,tunnels,address,hostname,os_kernel,connection_state")
pagination.Apply(q)
u.RawQuery = q.Encode()

req, err = http.NewRequestWithContext(
Expand All @@ -46,7 +49,7 @@ func (rp *Rport) Clients(ctx context.Context) (cr *ClientsResponse, err error) {

func (rp *Rport) GetClients(ctx context.Context) (cls []*models.Client, err error) {
var cr *ClientsResponse
cr, err = rp.Clients(ctx)
cr, err = rp.Clients(ctx, NewPaginationWithLimit(ClientsLimitMax))

if err != nil {
return
Expand Down
4 changes: 2 additions & 2 deletions internal/pkg/api/clients_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ func TestClientsList(t *testing.T) {
authHeader := r.Header.Get("Authorization")
assert.Equal(t, "Basic bG9nMTE2Njo1NjQzMjI=", authHeader)

assert.Equal(t, ClientsURL+"?fields%5Bclients%5D=id%2Cname%2Ctimezone%2Ctunnels%2Caddress%2Chostname%2Cos_kernel%2Cconnection_state", r.URL.String())
assert.Equal(t, ClientsURL+"?fields%5Bclients%5D=id%2Cname%2Ctimezone%2Ctunnels%2Caddress%2Chostname%2Cos_kernel%2Cconnection_state&page%5Blimit%5D=500&page%5Boffset%5D=0", r.URL.String())
jsonEnc := json.NewEncoder(rw)
e := jsonEnc.Encode(ClientsResponse{Data: clientsStub})
assert.NoError(t, e)
Expand All @@ -98,7 +98,7 @@ func TestClientsList(t *testing.T) {
},
})

clientsResp, err := cl.Clients(context.Background())
clientsResp, err := cl.Clients(context.Background(), NewPaginationWithLimit(ClientsLimitMax))
assert.NoError(t, err)
if err != nil {
return
Expand Down
37 changes: 37 additions & 0 deletions internal/pkg/api/pagination.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package api

import (
"net/url"
"strconv"

options "github.com/breathbath/go_utils/v2/pkg/config"
)

const (
PaginationOffset = "offset"
PaginationLimit = "limit"
)

type Pagination struct {
Limit int
Offset int
}

func NewPaginationFromParams(params *options.ParameterBag) Pagination {
return Pagination{
Offset: params.ReadInt(PaginationOffset, 0),
Limit: params.ReadInt(PaginationLimit, -1),
}
}

func NewPaginationWithLimit(max int) Pagination {
return Pagination{
Offset: 0,
Limit: max,
}
}

func (p Pagination) Apply(q url.Values) {
q.Set("page[offset]", strconv.Itoa(p.Offset))
q.Set("page[limit]", strconv.Itoa(p.Limit))
}
22 changes: 22 additions & 0 deletions internal/pkg/api/pagination_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package api

import (
"net/url"
"testing"

options "github.com/breathbath/go_utils/v2/pkg/config"
"github.com/stretchr/testify/assert"
)

func TestPaginationFromParams(t *testing.T) {
pagination := NewPaginationFromParams(options.New(options.NewMapValuesProvider(map[string]interface{}{
"limit": 30,
"offset": 90,
})))

q := url.Values{}
pagination.Apply(q)

assert.Equal(t, q.Get("page[limit]"), "30")
assert.Equal(t, q.Get("page[offset]"), "90")
}
6 changes: 3 additions & 3 deletions internal/pkg/controllers/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ type ClientController struct {
ClientRenderer ClientRenderer
}

func (cc *ClientController) Clients(ctx context.Context) error {
clResp, err := cc.Rport.Clients(ctx)
func (cc *ClientController) Clients(ctx context.Context, params *options.ParameterBag) error {
clResp, err := cc.Rport.Clients(ctx, api.NewPaginationFromParams(params))
if err != nil {
return err
}
Expand All @@ -42,7 +42,7 @@ func (cc *ClientController) Client(ctx context.Context, params *options.Paramete
renderDetails := params.ReadBool("all", false)

if id != "" {
clResp, err := cc.Rport.Clients(ctx)
clResp, err := cc.Rport.Clients(ctx, api.NewPaginationWithLimit(api.ClientsLimitMax))
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion internal/pkg/controllers/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func TestClientsController(t *testing.T) {
ClientRenderer: &ClientRendererMock{Writer: &buf},
}

err := clController.Clients(context.Background())
err := clController.Clients(context.Background(), options.New(nil))
assert.NoError(t, err)
if err != nil {
return
Expand Down
2 changes: 1 addition & 1 deletion internal/pkg/controllers/tunnel.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ func (tc *TunnelController) Tunnels(ctx context.Context, params *options.Paramet
}
} else {
var clResp *api.ClientsResponse
clResp, err = tc.Rport.Clients(ctx)
clResp, err = tc.Rport.Clients(ctx, api.NewPaginationFromParams(params))
if err != nil {
return err
}
Expand Down

0 comments on commit d425557

Please sign in to comment.