diff --git a/cmd/dev.go b/cmd/dev.go index ff79d882..8dff64e7 100644 --- a/cmd/dev.go +++ b/cmd/dev.go @@ -18,7 +18,11 @@ import ( // devCmd is the command for playground-style development var devCmd = man.Docs.GetCommand("dev") -var metadataLabels []string +var ( + metadataLabels []string + defaultListFlagLimit int32 = 300 + defaultListFlagOffset int32 = 0 +) func dev_designSystem(cmd *cobra.Command, args []string) { fmt.Print("Design system\n=============\n\n") @@ -116,6 +120,22 @@ func injectLabelFlags(cmd *cobra.Command, isUpdate bool) { } } +// Adds reusable limit/offset flags to a Policy LIST command +func injectListPaginationFlags(listDoc *man.Doc) { + listDoc.Flags().Int32P( + listDoc.GetDocFlag("limit").Name, + listDoc.GetDocFlag("limit").Shorthand, + defaultListFlagLimit, + listDoc.GetDocFlag("limit").Description, + ) + listDoc.Flags().Int32P( + listDoc.GetDocFlag("offset").Name, + listDoc.GetDocFlag("offset").Shorthand, + defaultListFlagOffset, + listDoc.GetDocFlag("offset").Description, + ) +} + // Read bytes from stdin without blocking by checking size first func readPipedStdin() []byte { stat, err := os.Stdin.Stat() diff --git a/cmd/kas-grants.go b/cmd/kas-grants.go index 9c60bc95..b0bd6037 100644 --- a/cmd/kas-grants.go +++ b/cmd/kas-grants.go @@ -162,6 +162,8 @@ func policy_listKasGrants(cmd *cobra.Command, args []string) { h := NewHandler(c) defer h.Close() kasF := c.Flags.GetOptionalString("kas") + limit := c.Flags.GetRequiredInt32("limit") + offset := c.Flags.GetRequiredInt32("offset") var ( kasID string kasURI string @@ -177,7 +179,7 @@ func policy_listKasGrants(cmd *cobra.Command, args []string) { } } - grants, err := h.ListKasGrants(cmd.Context(), kasID, kasURI) + grants, page, err := h.ListKasGrants(cmd.Context(), kasID, kasURI, limit, offset) if err != nil { cli.ExitWithError("Failed to list assigned KAS Grants", err) } @@ -224,6 +226,7 @@ func policy_listKasGrants(cmd *cobra.Command, args []string) { } } t = t.WithRows(rows) + t = cli.WithListPaginationFooter(t, page) // Do not supporting printing the 'get --id=...' helper message as grants are atypical // with no individual ID. @@ -304,6 +307,8 @@ func init() { listCmd.GetDocFlag("kas").Default, listCmd.GetDocFlag("kas").Description, ) + injectListPaginationFlags(listCmd) + cmd := man.Docs.GetCommand("policy/kas-grants", man.WithSubcommands(assignCmd, unassignCmd, listCmd), ) diff --git a/cmd/kas-registry.go b/cmd/kas-registry.go index 44d4175b..ee67e46d 100644 --- a/cmd/kas-registry.go +++ b/cmd/kas-registry.go @@ -57,7 +57,10 @@ func policy_listKeyAccessRegistries(cmd *cobra.Command, args []string) { h := NewHandler(c) defer h.Close() - list, err := h.ListKasRegistryEntries() + limit := c.Flags.GetRequiredInt32("limit") + offset := c.Flags.GetRequiredInt32("offset") + + list, page, err := h.ListKasRegistryEntries(limit, offset) if err != nil { cli.ExitWithError("Failed to list Registered KAS entries", err) } @@ -84,6 +87,7 @@ func policy_listKeyAccessRegistries(cmd *cobra.Command, args []string) { })) } t = t.WithRows(rows) + t = cli.WithListPaginationFooter(t, page) HandleSuccess(cmd, "", t, list) } @@ -268,6 +272,7 @@ func init() { listDoc := man.Docs.GetCommand("policy/kas-registry/list", man.WithRun(policy_listKeyAccessRegistries), ) + injectListPaginationFlags(listDoc) createDoc := man.Docs.GetCommand("policy/kas-registry/create", man.WithRun(policy_createKeyAccessRegistry), diff --git a/cmd/policy-attributeNamespaces.go b/cmd/policy-attributeNamespaces.go index ed3db7df..16dfde76 100644 --- a/cmd/policy-attributeNamespaces.go +++ b/cmd/policy-attributeNamespaces.go @@ -45,7 +45,10 @@ func policy_listAttributeNamespaces(cmd *cobra.Command, args []string) { defer h.Close() state := cli.GetState(cmd) - list, err := h.ListNamespaces(state) + limit := c.Flags.GetRequiredInt32("limit") + offset := c.Flags.GetRequiredInt32("offset") + + list, page, err := h.ListNamespaces(state, limit, offset) if err != nil { cli.ExitWithError("Failed to list namespaces", err) } @@ -72,6 +75,7 @@ func policy_listAttributeNamespaces(cmd *cobra.Command, args []string) { ) } t = t.WithRows(rows) + t = cli.WithListPaginationFooter(t, page) HandleSuccess(cmd, "", t, list) } @@ -281,6 +285,7 @@ func init() { listCmd.GetDocFlag("state").Default, listCmd.GetDocFlag("state").Description, ) + injectListPaginationFlags(listCmd) createDoc := man.Docs.GetCommand("policy/attributes/namespaces/create", man.WithRun(policy_createAttributeNamespace), diff --git a/cmd/policy-attributeValues.go b/cmd/policy-attributeValues.go index d3ddac34..633ede4c 100644 --- a/cmd/policy-attributeValues.go +++ b/cmd/policy-attributeValues.go @@ -53,9 +53,13 @@ func policy_listAttributeValue(cmd *cobra.Command, args []string) { c := cli.New(cmd, args) h := NewHandler(c) defer h.Close() + attrId := c.FlagHelper.GetRequiredID("attribute-id") state := cli.GetState(cmd) - vals, err := h.ListAttributeValues(attrId, state) + limit := c.Flags.GetRequiredInt32("limit") + offset := c.Flags.GetRequiredInt32("offset") + + vals, page, err := h.ListAttributeValues(attrId, state, limit, offset) if err != nil { cli.ExitWithError("Failed to list attribute values", err) } @@ -80,6 +84,7 @@ func policy_listAttributeValue(cmd *cobra.Command, args []string) { })) } t = t.WithRows(rows) + t = cli.WithListPaginationFooter(t, page) HandleSuccess(cmd, "", t, vals) } @@ -264,6 +269,7 @@ func init() { listCmd.GetDocFlag("state").Default, listCmd.GetDocFlag("state").Description, ) + injectListPaginationFlags(listCmd) updateCmd := man.Docs.GetCommand("policy/attributes/values/update", man.WithRun(policy_updateAttributeValue), diff --git a/cmd/policy-attributes.go b/cmd/policy-attributes.go index 9a855f4f..8a3dfc74 100644 --- a/cmd/policy-attributes.go +++ b/cmd/policy-attributes.go @@ -91,7 +91,10 @@ func policy_listAttributes(cmd *cobra.Command, args []string) { defer h.Close() state := cli.GetState(cmd) - attrs, err := h.ListAttributes(state) + limit := c.Flags.GetRequiredInt32("limit") + offset := c.Flags.GetRequiredInt32("offset") + + attrs, page, err := h.ListAttributes(state, limit, offset) if err != nil { cli.ExitWithError("Failed to list attributes", err) } @@ -123,6 +126,7 @@ func policy_listAttributes(cmd *cobra.Command, args []string) { })) } t = t.WithRows(rows) + t = cli.WithListPaginationFooter(t, page) HandleSuccess(cmd, "", t, attrs) } @@ -349,6 +353,7 @@ func init() { listDoc.GetDocFlag("state").Default, listDoc.GetDocFlag("state").Description, ) + injectListPaginationFlags(listDoc) // Update an attribute updateDoc := man.Docs.GetCommand("policy/attributes/update", diff --git a/cmd/policy-resourceMappings.go b/cmd/policy-resourceMappings.go index 52a0ce4b..180d99c1 100644 --- a/cmd/policy-resourceMappings.go +++ b/cmd/policy-resourceMappings.go @@ -73,7 +73,10 @@ func policy_listResourceMappings(cmd *cobra.Command, args []string) { h := NewHandler(c) defer h.Close() - rmList, err := h.ListResourceMappings() + limit := c.Flags.GetRequiredInt32("limit") + offset := c.Flags.GetRequiredInt32("offset") + + rmList, page, err := h.ListResourceMappings(cmd.Context(), limit, offset) if err != nil { cli.ExitWithError("Failed to list resource mappings", err) } @@ -101,6 +104,7 @@ func policy_listResourceMappings(cmd *cobra.Command, args []string) { })) } t = t.WithRows(rows) + t = cli.WithListPaginationFooter(t, page) HandleSuccess(cmd, "", t, rmList) } @@ -189,6 +193,7 @@ func init() { listDoc := man.Docs.GetCommand("policy/resource-mappings/list", man.WithRun(policy_listResourceMappings), ) + injectListPaginationFlags(listDoc) updateDoc := man.Docs.GetCommand("policy/resource-mappings/update", man.WithRun(policy_updateResourceMapping), diff --git a/cmd/policy-subjectConditionSets.go b/cmd/policy-subjectConditionSets.go index 10e5b77e..f41f96c8 100644 --- a/cmd/policy-subjectConditionSets.go +++ b/cmd/policy-subjectConditionSets.go @@ -143,7 +143,10 @@ func policy_listSubjectConditionSets(cmd *cobra.Command, args []string) { h := NewHandler(c) defer h.Close() - scsList, err := h.ListSubjectConditionSets() + limit := c.Flags.GetRequiredInt32("limit") + offset := c.Flags.GetRequiredInt32("offset") + + scsList, page, err := h.ListSubjectConditionSets(limit, offset) if err != nil { cli.ExitWithError("Error listing subject condition sets", err) } @@ -171,6 +174,7 @@ func policy_listSubjectConditionSets(cmd *cobra.Command, args []string) { })) } t = t.WithRows(rows) + t = cli.WithListPaginationFooter(t, page) HandleSuccess(cmd, "", t, scsList) } @@ -340,6 +344,7 @@ func init() { listDoc := man.Docs.GetCommand("policy/subject-condition-sets/list", man.WithRun(policy_listSubjectConditionSets), ) + injectListPaginationFlags(listDoc) updateDoc := man.Docs.GetCommand("policy/subject-condition-sets/update", man.WithRun(policy_updateSubjectConditionSet), diff --git a/cmd/policy-subjectMappings.go b/cmd/policy-subjectMappings.go index be0f7b49..8230a89c 100644 --- a/cmd/policy-subjectMappings.go +++ b/cmd/policy-subjectMappings.go @@ -64,7 +64,10 @@ func policy_listSubjectMappings(cmd *cobra.Command, args []string) { h := NewHandler(c) defer h.Close() - list, err := h.ListSubjectMappings() + limit := c.Flags.GetRequiredInt32("limit") + offset := c.Flags.GetRequiredInt32("offset") + + list, page, err := h.ListSubjectMappings(limit, offset) if err != nil { cli.ExitWithError("Failed to get subject mappings", err) } @@ -98,6 +101,7 @@ func policy_listSubjectMappings(cmd *cobra.Command, args []string) { })) } t = t.WithRows(rows) + t = cli.WithListPaginationFooter(t, page) HandleSuccess(cmd, "", t, list) } @@ -353,6 +357,7 @@ func init() { listDoc := man.Docs.GetCommand("policy/subject-mappings/list", man.WithRun(policy_listSubjectMappings), ) + injectListPaginationFlags(listDoc) createDoc := man.Docs.GetCommand("policy/subject-mappings/create", man.WithRun(policy_createSubjectMapping), diff --git a/docs/man/policy/attributes/list.md b/docs/man/policy/attributes/list.md index e7a19908..ef8e3440 100644 --- a/docs/man/policy/attributes/list.md +++ b/docs/man/policy/attributes/list.md @@ -13,6 +13,12 @@ command: - inactive - any default: active + - name: limit + shorthand: l + description: Limit retrieved count + - name: offset + shorthand: o + description: Offset (page) quantity from start of the list --- By default, the list will only provide `active` attributes if unspecified, but the filter can be controlled with the `--state` flag. diff --git a/docs/man/policy/attributes/namespaces/list.md b/docs/man/policy/attributes/namespaces/list.md index 3f58d76e..4fcc1295 100644 --- a/docs/man/policy/attributes/namespaces/list.md +++ b/docs/man/policy/attributes/namespaces/list.md @@ -9,6 +9,12 @@ command: - name: state shorthand: s description: Filter by state [active, inactive, any] + - name: limit + shorthand: l + description: Limit retrieved count + - name: offset + shorthand: o + description: Offset (page) quantity from start of the list --- For more general information, see the `namespaces` subcommand. diff --git a/docs/man/policy/attributes/values/list.md b/docs/man/policy/attributes/values/list.md index 95484e88..7e7a142c 100644 --- a/docs/man/policy/attributes/values/list.md +++ b/docs/man/policy/attributes/values/list.md @@ -17,6 +17,12 @@ command: - inactive - any default: active + - name: limit + shorthand: l + description: Limit retrieved count + - name: offset + shorthand: o + description: Offset (page) quantity from start of the list --- By default, the list will only provide `active` values if unspecified, but the filter can be controlled with the `--state` flag. diff --git a/docs/man/policy/kas-grants/list.md b/docs/man/policy/kas-grants/list.md index dba055e0..e3c27db7 100644 --- a/docs/man/policy/kas-grants/list.md +++ b/docs/man/policy/kas-grants/list.md @@ -10,6 +10,12 @@ command: - name: kas shorthand: k description: The optional ID or URI of a KAS to filter the list + - name: limit + shorthand: l + description: Limit retrieved count + - name: offset + shorthand: o + description: Offset (page) quantity from start of the list --- List the Grants of Registered Key Access Servers (KASes) to attribute namespaces, definitions, diff --git a/docs/man/policy/kas-registry/list.md b/docs/man/policy/kas-registry/list.md index c7b2ce44..9d2101fd 100644 --- a/docs/man/policy/kas-registry/list.md +++ b/docs/man/policy/kas-registry/list.md @@ -4,6 +4,13 @@ command: name: list aliases: - l + flags: + - name: limit + shorthand: l + description: Limit retrieved count + - name: offset + shorthand: o + description: Offset (page) quantity from start of the list --- For more information about registration of Key Access Servers, see the manual for `kas-registry`. diff --git a/docs/man/policy/resource-mappings/list.md b/docs/man/policy/resource-mappings/list.md index 57a1186c..6dbd6d92 100644 --- a/docs/man/policy/resource-mappings/list.md +++ b/docs/man/policy/resource-mappings/list.md @@ -4,6 +4,13 @@ command: name: list aliases: - l + flags: + - name: limit + shorthand: l + description: Limit retrieved count + - name: offset + shorthand: o + description: Offset (page) quantity from start of the list --- For more information about resource mappings, see the `resource-mappings` subcommand. diff --git a/docs/man/policy/subject-condition-sets/list.md b/docs/man/policy/subject-condition-sets/list.md index 4ab11705..77b9bc26 100644 --- a/docs/man/policy/subject-condition-sets/list.md +++ b/docs/man/policy/subject-condition-sets/list.md @@ -5,6 +5,13 @@ command: name: list aliases: - l + flags: + - name: limit + shorthand: l + description: Limit retrieved count + - name: offset + shorthand: o + description: Offset (page) quantity from start of the list --- For more information about subject condition sets, see the `subject-condition-sets` subcommand. diff --git a/docs/man/policy/subject-mappings/list.md b/docs/man/policy/subject-mappings/list.md index e433bb6b..1e13e6af 100644 --- a/docs/man/policy/subject-mappings/list.md +++ b/docs/man/policy/subject-mappings/list.md @@ -4,6 +4,13 @@ command: name: list aliases: - l + flags: + - name: limit + shorthand: l + description: Limit retrieved count + - name: offset + shorthand: o + description: Offset (page) quantity from start of the list --- For more information about subject mappings, see the `subject-mappings` subcommand. diff --git a/e2e/attributes.bats b/e2e/attributes.bats index c7ee214a..7ad3fbc7 100755 --- a/e2e/attributes.bats +++ b/e2e/attributes.bats @@ -67,10 +67,10 @@ teardown_file() { run_otdfctl_attr get --id "$ATTR_ID" assert_success - assert_output --regexp "Id.*$ATTR_ID" - assert_output --regexp "Name.*$LOWERED" + assert_line --regexp "Id.*$ATTR_ID" + assert_line --regexp "Name.*$LOWERED" assert_output --partial "ANY_OF" - assert_output --regexp "Namespace.*$NS_NAME" + assert_line --regexp "Namespace.*$NS_NAME" run_otdfctl_attr get --id "$ATTR_ID" --json assert_success @@ -111,14 +111,47 @@ teardown_file() { run_otdfctl_attr list assert_success assert_output --partial "$ATTR_ID" + assert_output --partial "Total" + assert_line --regexp "Current Offset.*0" run_otdfctl_attr list --state active assert_success assert_output --partial "$ATTR_ID" + assert_output --partial "Total" + assert_line --regexp "Current Offset.*0" run_otdfctl_attr list --state inactive assert_success refute_output --partial "$ATTR_ID" + assert_output --partial "Total" + assert_line --regexp "Current Offset.*0" +} + +@test "List - comprehensive pagination tests" { + # create 10 random attributes so we have confidence there are >= 10 attribute definitions + for i in {1..10}; do + random_name=$(LC_ALL=C tr -dc 'A-Za-z0-9' 0 { + info = append(info, fmt.Sprintf("Next Offset: %d", p.GetNextOffset())) + } + + content := strings.Join(info, " | ") + + leftAligned := lipgloss.NewStyle().Align(lipgloss.Left) + return t.WithStaticFooter(content).WithBaseStyle(leftAligned) +} diff --git a/pkg/handlers/attribute.go b/pkg/handlers/attribute.go index 81ca4ec4..3596bef1 100644 --- a/pkg/handlers/attribute.go +++ b/pkg/handlers/attribute.go @@ -42,12 +42,18 @@ func (h Handler) GetAttribute(id string) (*policy.Attribute, error) { return resp.GetAttribute(), nil } -func (h Handler) ListAttributes(state common.ActiveStateEnum) ([]*policy.Attribute, error) { - resp, err := h.sdk.Attributes.ListAttributes(h.ctx, &attributes.ListAttributesRequest{State: state}) +func (h Handler) ListAttributes(state common.ActiveStateEnum, limit, offset int32) ([]*policy.Attribute, *policy.PageResponse, error) { + resp, err := h.sdk.Attributes.ListAttributes(h.ctx, &attributes.ListAttributesRequest{ + State: state, + Pagination: &policy.PageRequest{ + Limit: limit, + Offset: offset, + }, + }) if err != nil { - return nil, err + return nil, nil, err } - return resp.GetAttributes(), err + return resp.GetAttributes(), resp.GetPagination(), nil } // Creates and returns the created attribute diff --git a/pkg/handlers/attributeValues.go b/pkg/handlers/attributeValues.go index 9b4f1dc2..a62ff7d6 100644 --- a/pkg/handlers/attributeValues.go +++ b/pkg/handlers/attributeValues.go @@ -7,12 +7,19 @@ import ( "github.com/opentdf/platform/protocol/go/policy/unsafe" ) -func (h *Handler) ListAttributeValues(attributeId string, state common.ActiveStateEnum) ([]*policy.Value, error) { - resp, err := h.sdk.Attributes.ListAttributeValues(h.ctx, &attributes.ListAttributeValuesRequest{AttributeId: attributeId, State: state}) +func (h *Handler) ListAttributeValues(attributeId string, state common.ActiveStateEnum, limit, offset int32) ([]*policy.Value, *policy.PageResponse, error) { + resp, err := h.sdk.Attributes.ListAttributeValues(h.ctx, &attributes.ListAttributeValuesRequest{ + AttributeId: attributeId, + State: state, + Pagination: &policy.PageRequest{ + Limit: limit, + Offset: offset, + }, + }) if err != nil { - return nil, err + return nil, nil, err } - return resp.GetValues(), err + return resp.GetValues(), resp.GetPagination(), err } // Creates and returns the created value diff --git a/pkg/handlers/kas-grants.go b/pkg/handlers/kas-grants.go index a32dd0fb..256e36ed 100644 --- a/pkg/handlers/kas-grants.go +++ b/pkg/handlers/kas-grants.go @@ -3,6 +3,7 @@ package handlers import ( "context" + "github.com/opentdf/platform/protocol/go/policy" "github.com/opentdf/platform/protocol/go/policy/attributes" "github.com/opentdf/platform/protocol/go/policy/kasregistry" "github.com/opentdf/platform/protocol/go/policy/namespaces" @@ -98,13 +99,17 @@ func (h Handler) DeleteKasGrantFromNamespace(ctx context.Context, ns_id string, return resp.GetNamespaceKeyAccessServer(), nil } -func (h Handler) ListKasGrants(ctx context.Context, kas_id, kas_uri string) ([]*kasregistry.KeyAccessServerGrants, error) { +func (h Handler) ListKasGrants(ctx context.Context, kas_id, kas_uri string, limit, offset int32) ([]*kasregistry.KeyAccessServerGrants, *policy.PageResponse, error) { resp, err := h.sdk.KeyAccessServerRegistry.ListKeyAccessServerGrants(ctx, &kasregistry.ListKeyAccessServerGrantsRequest{ KasId: kas_id, KasUri: kas_uri, + Pagination: &policy.PageRequest{ + Limit: limit, + Offset: offset, + }, }) if err != nil { - return nil, err + return nil, nil, err } - return resp.GetGrants(), nil + return resp.GetGrants(), resp.GetPagination(), nil } diff --git a/pkg/handlers/kas-registry.go b/pkg/handlers/kas-registry.go index 5249c5d1..7c0fbe0d 100644 --- a/pkg/handlers/kas-registry.go +++ b/pkg/handlers/kas-registry.go @@ -17,13 +17,18 @@ func (h Handler) GetKasRegistryEntry(id string) (*policy.KeyAccessServer, error) return resp.GetKeyAccessServer(), nil } -func (h Handler) ListKasRegistryEntries() ([]*policy.KeyAccessServer, error) { - resp, err := h.sdk.KeyAccessServerRegistry.ListKeyAccessServers(h.ctx, &kasregistry.ListKeyAccessServersRequest{}) +func (h Handler) ListKasRegistryEntries(limit, offset int32) ([]*policy.KeyAccessServer, *policy.PageResponse, error) { + resp, err := h.sdk.KeyAccessServerRegistry.ListKeyAccessServers(h.ctx, &kasregistry.ListKeyAccessServersRequest{ + Pagination: &policy.PageRequest{ + Limit: limit, + Offset: offset, + }, + }) if err != nil { - return nil, err + return nil, nil, err } - return resp.GetKeyAccessServers(), nil + return resp.GetKeyAccessServers(), resp.GetPagination(), nil } // Creates the KAS registry and then returns the KAS diff --git a/pkg/handlers/namespaces.go b/pkg/handlers/namespaces.go index 232c4ba2..fe773472 100644 --- a/pkg/handlers/namespaces.go +++ b/pkg/handlers/namespaces.go @@ -18,13 +18,19 @@ func (h Handler) GetNamespace(id string) (*policy.Namespace, error) { return resp.GetNamespace(), nil } -func (h Handler) ListNamespaces(state common.ActiveStateEnum) ([]*policy.Namespace, error) { - resp, err := h.sdk.Namespaces.ListNamespaces(h.ctx, &namespaces.ListNamespacesRequest{State: state}) +func (h Handler) ListNamespaces(state common.ActiveStateEnum, limit, offset int32) ([]*policy.Namespace, *policy.PageResponse, error) { + resp, err := h.sdk.Namespaces.ListNamespaces(h.ctx, &namespaces.ListNamespacesRequest{ + State: state, + Pagination: &policy.PageRequest{ + Limit: limit, + Offset: offset, + }, + }) if err != nil { - return nil, err + return nil, nil, err } - return resp.GetNamespaces(), nil + return resp.GetNamespaces(), resp.GetPagination(), nil } // Creates and returns the created n diff --git a/pkg/handlers/resourceMappings.go b/pkg/handlers/resourceMappings.go index 28ba0436..563b3f16 100644 --- a/pkg/handlers/resourceMappings.go +++ b/pkg/handlers/resourceMappings.go @@ -39,13 +39,18 @@ func (h *Handler) GetResourceMapping(id string) (*policy.ResourceMapping, error) return res.GetResourceMapping(), nil } -func (h *Handler) ListResourceMappings() ([]*policy.ResourceMapping, error) { - res, err := h.sdk.ResourceMapping.ListResourceMappings(context.Background(), &resourcemapping.ListResourceMappingsRequest{}) +func (h *Handler) ListResourceMappings(ctx context.Context, limit, offset int32) ([]*policy.ResourceMapping, *policy.PageResponse, error) { + res, err := h.sdk.ResourceMapping.ListResourceMappings(ctx, &resourcemapping.ListResourceMappingsRequest{ + Pagination: &policy.PageRequest{ + Limit: limit, + Offset: offset, + }, + }) if err != nil { - return nil, err + return nil, nil, err } - return res.GetResourceMappings(), nil + return res.GetResourceMappings(), res.GetPagination(), nil } // TODO: verify updation behavior diff --git a/pkg/handlers/subjectConditionSets.go b/pkg/handlers/subjectConditionSets.go index ea8dbd8d..d702a683 100644 --- a/pkg/handlers/subjectConditionSets.go +++ b/pkg/handlers/subjectConditionSets.go @@ -17,12 +17,17 @@ func (h Handler) GetSubjectConditionSet(id string) (*policy.SubjectConditionSet, return resp.GetSubjectConditionSet(), nil } -func (h Handler) ListSubjectConditionSets() ([]*policy.SubjectConditionSet, error) { - resp, err := h.sdk.SubjectMapping.ListSubjectConditionSets(h.ctx, &subjectmapping.ListSubjectConditionSetsRequest{}) +func (h Handler) ListSubjectConditionSets(limit, offset int32) ([]*policy.SubjectConditionSet, *policy.PageResponse, error) { + resp, err := h.sdk.SubjectMapping.ListSubjectConditionSets(h.ctx, &subjectmapping.ListSubjectConditionSetsRequest{ + Pagination: &policy.PageRequest{ + Limit: limit, + Offset: offset, + }, + }) if err != nil { - return nil, err + return nil, nil, err } - return resp.GetSubjectConditionSets(), err + return resp.GetSubjectConditionSets(), resp.GetPagination(), err } // Creates and returns the created subject condition set diff --git a/pkg/handlers/subjectmappings.go b/pkg/handlers/subjectmappings.go index 82b98098..06043d37 100644 --- a/pkg/handlers/subjectmappings.go +++ b/pkg/handlers/subjectmappings.go @@ -22,10 +22,17 @@ func (h Handler) GetSubjectMapping(id string) (*policy.SubjectMapping, error) { return resp.GetSubjectMapping(), err } -func (h Handler) ListSubjectMappings() ([]*policy.SubjectMapping, error) { - resp, err := h.sdk.SubjectMapping.ListSubjectMappings(h.ctx, &subjectmapping.ListSubjectMappingsRequest{}) - - return resp.GetSubjectMappings(), err +func (h Handler) ListSubjectMappings(limit, offset int32) ([]*policy.SubjectMapping, *policy.PageResponse, error) { + resp, err := h.sdk.SubjectMapping.ListSubjectMappings(h.ctx, &subjectmapping.ListSubjectMappingsRequest{ + Pagination: &policy.PageRequest{ + Limit: limit, + Offset: offset, + }, + }) + if err != nil { + return nil, nil, err + } + return resp.GetSubjectMappings(), resp.GetPagination(), err } // Creates and returns the created subject mapping diff --git a/tui/attributeList.go b/tui/attributeList.go index ee54c9b5..b4997950 100644 --- a/tui/attributeList.go +++ b/tui/attributeList.go @@ -11,7 +11,7 @@ import ( type AttributeList struct { list list.Model - sdk handlers.Handler + h handlers.Handler } type AttributeItem struct { @@ -31,10 +31,14 @@ func (m AttributeItem) Description() string { return m.id } -func InitAttributeList(id string, sdk handlers.Handler) (tea.Model, tea.Cmd) { +func InitAttributeList(id string, h handlers.Handler) (tea.Model, tea.Cmd) { l := list.New([]list.Item{}, list.NewDefaultDelegate(), constants.WindowSize.Width, constants.WindowSize.Height) - // TODO: handle and return error view - res, _ := sdk.ListAttributes(common.ActiveStateEnum_ACTIVE_STATE_ENUM_ANY) + // TODO: handle and return error view and use real command flags limit/offset + var ( + limit int32 = 100 + offset int32 = 0 + ) + res, _, _ := h.ListAttributes(common.ActiveStateEnum_ACTIVE_STATE_ENUM_ANY, limit, offset) var attrs []list.Item selectIdx := 0 for i, attr := range res { @@ -56,7 +60,7 @@ func InitAttributeList(id string, sdk handlers.Handler) (tea.Model, tea.Cmd) { l.Title = "Attributes" l.SetItems(attrs) l.Select(selectIdx) - m := AttributeList{sdk: sdk, list: l} + m := AttributeList{h: h, list: l} return m.Update(WindowMsg()) } @@ -89,7 +93,7 @@ func (m AttributeList) Update(msg tea.Msg) (tea.Model, tea.Cmd) { case "ctrl+c", "q": return m, tea.Quit case "ctrl+[", "backspace": - am, _ := InitAppMenu(m.sdk) + am, _ := InitAppMenu(m.h) // make enum for Attributes idx in AppMenu am.list.Select(0) return am.Update(WindowMsg()) @@ -97,7 +101,7 @@ func (m AttributeList) Update(msg tea.Msg) (tea.Model, tea.Cmd) { // create new attribute // return InitAttributeView(m.list.Items(), len(m.list.Items())) case "enter", "e": - return InitAttributeView(m.list.Items()[m.list.Index()].(AttributeItem).id, m.sdk) + return InitAttributeView(m.list.Items()[m.list.Index()].(AttributeItem).id, m.h) // case "ctrl+d": // m.list.RemoveItem(m.list.Index()) // newIndex := m.list.Index() - 1