From faf7ebce85b75d6073a55fb32a902c4e27e51518 Mon Sep 17 00:00:00 2001 From: Johan Brandhorst-Satzkorn Date: Mon, 30 Oct 2023 14:40:00 -0700 Subject: [PATCH] internal/host: add pagination options Add options to support pagination of hosts, host sets and host catalogs. --- internal/host/plugin/options.go | 14 +++++++++++++- internal/host/plugin/options_test.go | 24 ++++++++++++++++++++++++ internal/host/static/options.go | 21 ++++++++++++++++----- internal/host/static/options_test.go | 24 ++++++++++++++++++++++++ 4 files changed, 77 insertions(+), 6 deletions(-) diff --git a/internal/host/plugin/options.go b/internal/host/plugin/options.go index 885f535745..5c11066861 100644 --- a/internal/host/plugin/options.go +++ b/internal/host/plugin/options.go @@ -3,7 +3,10 @@ package plugin -import "google.golang.org/protobuf/types/known/structpb" +import ( + "github.com/hashicorp/boundary/internal/pagination" + "google.golang.org/protobuf/types/known/structpb" +) // getOpts - iterate the inbound Options and return a struct func getOpts(opt ...Option) options { @@ -33,6 +36,7 @@ type options struct { withLimit int withSetIds []string withSecretsHmac []byte + withStartPageAfterItem pagination.Item } func getDefaultOptions() options { @@ -141,3 +145,11 @@ func WithSecretsHmac(secretsHmac []byte) Option { o.withSecretsHmac = secretsHmac } } + +// WithStartPageAfterItem is used to paginate over the results. +// The next page will start after the provided item. +func WithStartPageAfterItem(item pagination.Item) Option { + return func(o *options) { + o.withStartPageAfterItem = item + } +} diff --git a/internal/host/plugin/options_test.go b/internal/host/plugin/options_test.go index 6d8f464bec..7aac424262 100644 --- a/internal/host/plugin/options_test.go +++ b/internal/host/plugin/options_test.go @@ -5,10 +5,27 @@ package plugin import ( "testing" + "time" + "github.com/hashicorp/boundary/internal/db/timestamp" + "github.com/hashicorp/boundary/internal/pagination" "github.com/stretchr/testify/assert" ) +type fakeItem struct { + pagination.Item + publicId string + updateTime time.Time +} + +func (p *fakeItem) GetPublicId() string { + return p.publicId +} + +func (p *fakeItem) GetUpdateTime() *timestamp.Timestamp { + return timestamp.New(p.updateTime) +} + func Test_GetOpts(t *testing.T) { t.Parallel() t.Run("WithPublicId", func(t *testing.T) { @@ -83,4 +100,11 @@ func Test_GetOpts(t *testing.T) { testOpts.withExternalName = "external-name" assert.Equal(t, opts, testOpts) }) + t.Run("WithStartPageAfterItem", func(t *testing.T) { + assert := assert.New(t) + updateTime := time.Now() + opts := getOpts(WithStartPageAfterItem(&fakeItem{nil, "s_1", updateTime})) + assert.Equal(opts.withStartPageAfterItem.GetPublicId(), "s_1") + assert.Equal(opts.withStartPageAfterItem.GetUpdateTime(), timestamp.New(updateTime)) + }) } diff --git a/internal/host/static/options.go b/internal/host/static/options.go index a00f2bb408..e1d92df20f 100644 --- a/internal/host/static/options.go +++ b/internal/host/static/options.go @@ -3,6 +3,8 @@ package static +import "github.com/hashicorp/boundary/internal/pagination" + // getOpts - iterate the inbound Options and return a struct func getOpts(opt ...Option) options { opts := getDefaultOptions() @@ -17,11 +19,12 @@ type Option func(*options) // options = how options are represented type options struct { - withName string - withDescription string - withLimit int - withAddress string - withPublicId string + withName string + withDescription string + withLimit int + withAddress string + withPublicId string + withStartPageAfterItem pagination.Item } func getDefaultOptions() options { @@ -68,3 +71,11 @@ func WithPublicId(id string) Option { o.withPublicId = id } } + +// WithStartPageAfterItem is used to paginate over the results. +// The next page will start after the provided item. +func WithStartPageAfterItem(item pagination.Item) Option { + return func(o *options) { + o.withStartPageAfterItem = item + } +} diff --git a/internal/host/static/options_test.go b/internal/host/static/options_test.go index f837ddb313..579b8d04aa 100644 --- a/internal/host/static/options_test.go +++ b/internal/host/static/options_test.go @@ -5,10 +5,27 @@ package static import ( "testing" + "time" + "github.com/hashicorp/boundary/internal/db/timestamp" + "github.com/hashicorp/boundary/internal/pagination" "github.com/stretchr/testify/assert" ) +type fakeItem struct { + pagination.Item + publicId string + updateTime time.Time +} + +func (p *fakeItem) GetPublicId() string { + return p.publicId +} + +func (p *fakeItem) GetUpdateTime() *timestamp.Timestamp { + return timestamp.New(p.updateTime) +} + func Test_GetOpts(t *testing.T) { t.Parallel() t.Run("WithName", func(t *testing.T) { @@ -41,4 +58,11 @@ func Test_GetOpts(t *testing.T) { testOpts.withPublicId = "test" assert.Equal(t, opts, testOpts) }) + t.Run("WithStartPageAfterItem", func(t *testing.T) { + assert := assert.New(t) + updateTime := time.Now() + opts := getOpts(WithStartPageAfterItem(&fakeItem{nil, "s_1", updateTime})) + assert.Equal(opts.withStartPageAfterItem.GetPublicId(), "s_1") + assert.Equal(opts.withStartPageAfterItem.GetUpdateTime(), timestamp.New(updateTime)) + }) }