From 3927e2bddaedc9a39836c75c9135651dfc6a7a44 Mon Sep 17 00:00:00 2001 From: Krish Suchak Date: Thu, 4 Jun 2026 16:05:32 -0400 Subject: [PATCH] feat(cli): DSPX-2998 add namespace flags to resource mapping commands - Add --namespace-id and --namespace-fqn to resource-mappings create and update, and as filters on resource-mappings list. - Add --namespace-id and --namespace-fqn filters to resource-mapping-groups list. - Surface the owning namespace in command output. Stacked on the service PR (#3567). Signed-off-by: Krish Suchak --- otdfctl/cmd/policy/resourceMappingGroups.go | 14 ++++- otdfctl/cmd/policy/resourceMappings.go | 52 +++++++++++++++++-- .../policy/resource-mapping-groups/list.md | 6 +++ .../man/policy/resource-mappings/create.md | 6 +++ .../docs/man/policy/resource-mappings/list.md | 6 +++ .../man/policy/resource-mappings/update.md | 6 +++ otdfctl/pkg/handlers/resourceMappingGroups.go | 4 +- otdfctl/pkg/handlers/resourceMappings.go | 12 +++-- 8 files changed, 98 insertions(+), 8 deletions(-) diff --git a/otdfctl/cmd/policy/resourceMappingGroups.go b/otdfctl/cmd/policy/resourceMappingGroups.go index 1df8815da2..4bb83c4147 100644 --- a/otdfctl/cmd/policy/resourceMappingGroups.go +++ b/otdfctl/cmd/policy/resourceMappingGroups.go @@ -67,8 +67,10 @@ func policyListResourceMappingGroups(cmd *cobra.Command, args []string) { limit := c.Flags.GetRequiredInt32("limit") offset := c.Flags.GetRequiredInt32("offset") + nsID := c.Flags.GetOptionalID("namespace-id") + nsFqn := c.Flags.GetOptionalString("namespace-fqn") - resp, err := h.ListResourceMappingGroups(cmd.Context(), limit, offset) + resp, err := h.ListResourceMappingGroups(cmd.Context(), nsID, nsFqn, limit, offset) if err != nil { cli.ExitWithError("Failed to list resource mapping groups", err) } @@ -180,6 +182,16 @@ func initResourceMappingGroupsCommands() { listDoc := man.Docs.GetCommand("policy/resource-mapping-groups/list", man.WithRun(policyListResourceMappingGroups), ) + listDoc.Flags().String( + listDoc.GetDocFlag("namespace-id").Name, + listDoc.GetDocFlag("namespace-id").Default, + listDoc.GetDocFlag("namespace-id").Description, + ) + listDoc.Flags().String( + listDoc.GetDocFlag("namespace-fqn").Name, + listDoc.GetDocFlag("namespace-fqn").Default, + listDoc.GetDocFlag("namespace-fqn").Description, + ) injectListPaginationFlags(listDoc) updateDoc := man.Docs.GetCommand("policy/resource-mapping-groups/update", diff --git a/otdfctl/cmd/policy/resourceMappings.go b/otdfctl/cmd/policy/resourceMappings.go index 57a0ba2fde..42d4cd54cf 100644 --- a/otdfctl/cmd/policy/resourceMappings.go +++ b/otdfctl/cmd/policy/resourceMappings.go @@ -24,12 +24,14 @@ func createResourceMapping(cmd *cobra.Command, args []string) { attrID := c.Flags.GetRequiredID("attribute-value-id") grpID := c.Flags.GetOptionalID("group-id") + nsID := c.Flags.GetOptionalID("namespace-id") + nsFqn := c.Flags.GetOptionalString("namespace-fqn") terms = c.Flags.GetStringSlice("terms", terms, cli.FlagsStringSliceOptions{ Min: 1, }) metadataLabels = c.Flags.GetStringSlice("label", metadataLabels, cli.FlagsStringSliceOptions{Min: 0}) - resourceMapping, err := h.CreateResourceMapping(attrID, terms, grpID, getMetadataMutable(metadataLabels)) + resourceMapping, err := h.CreateResourceMapping(attrID, terms, grpID, nsID, nsFqn, getMetadataMutable(metadataLabels)) if err != nil { cli.ExitWithError("Failed to create resource mapping", err) } @@ -40,6 +42,8 @@ func createResourceMapping(cmd *cobra.Command, args []string) { {"Terms", strings.Join(resourceMapping.GetTerms(), ", ")}, {"Group Id", resourceMapping.GetGroup().GetId()}, {"Group Name", resourceMapping.GetGroup().GetName()}, + {"Namespace Id", resourceMapping.GetNamespace().GetId()}, + {"Namespace", resourceMapping.GetNamespace().GetFqn()}, } if mdRows := getMetadataRows(resourceMapping.GetMetadata()); mdRows != nil { rows = append(rows, mdRows...) @@ -66,6 +70,8 @@ func getResourceMapping(cmd *cobra.Command, args []string) { {"Terms", strings.Join(resourceMapping.GetTerms(), ", ")}, {"Group Id", resourceMapping.GetGroup().GetId()}, {"Group Name", resourceMapping.GetGroup().GetName()}, + {"Namespace Id", resourceMapping.GetNamespace().GetId()}, + {"Namespace", resourceMapping.GetNamespace().GetFqn()}, } if mdRows := getMetadataRows(resourceMapping.GetMetadata()); mdRows != nil { rows = append(rows, mdRows...) @@ -81,8 +87,10 @@ func listResourceMappings(cmd *cobra.Command, args []string) { limit := c.Flags.GetRequiredInt32("limit") offset := c.Flags.GetRequiredInt32("offset") + nsID := c.Flags.GetOptionalID("namespace-id") + nsFqn := c.Flags.GetOptionalString("namespace-fqn") - resp, err := h.ListResourceMappings(cmd.Context(), limit, offset) + resp, err := h.ListResourceMappings(cmd.Context(), nsID, nsFqn, limit, offset) if err != nil { cli.ExitWithError("Failed to list resource mappings", err) } @@ -94,6 +102,7 @@ func listResourceMappings(cmd *cobra.Command, args []string) { table.NewFlexColumn("terms", "Terms", cli.FlexColumnWidthFour), table.NewFlexColumn("group_id", "Group Id", cli.FlexColumnWidthFive), table.NewFlexColumn("group_name", "Group Name", cli.FlexColumnWidthTwo), + table.NewFlexColumn("namespace", "Namespace", cli.FlexColumnWidthTwo), table.NewFlexColumn("labels", "Labels", cli.FlexColumnWidthOne), table.NewFlexColumn("created_at", "Created At", cli.FlexColumnWidthOne), table.NewFlexColumn("updated_at", "Updated At", cli.FlexColumnWidthOne), @@ -107,6 +116,7 @@ func listResourceMappings(cmd *cobra.Command, args []string) { "attr_value": resourceMapping.GetAttributeValue().GetValue(), "group_id": resourceMapping.GetGroup().GetId(), "group_name": resourceMapping.GetGroup().GetName(), + "namespace": resourceMapping.GetNamespace().GetFqn(), "terms": strings.Join(resourceMapping.GetTerms(), ", "), "labels": metadata["Labels"], "created_at": metadata["Created At"], @@ -126,10 +136,12 @@ func updateResourceMapping(cmd *cobra.Command, args []string) { id := c.Flags.GetRequiredID("id") attrValueID := c.Flags.GetOptionalID("attribute-value-id") grpID := c.Flags.GetOptionalID("group-id") + nsID := c.Flags.GetOptionalID("namespace-id") + nsFqn := c.Flags.GetOptionalString("namespace-fqn") terms = c.Flags.GetStringSlice("terms", terms, cli.FlagsStringSliceOptions{}) metadataLabels = c.Flags.GetStringSlice("label", metadataLabels, cli.FlagsStringSliceOptions{Min: 0}) - resourceMapping, err := h.UpdateResourceMapping(id, attrValueID, grpID, terms, getMetadataMutable(metadataLabels), getMetadataUpdateBehavior()) + resourceMapping, err := h.UpdateResourceMapping(id, attrValueID, grpID, nsID, nsFqn, terms, getMetadataMutable(metadataLabels), getMetadataUpdateBehavior()) if err != nil { cli.ExitWithError(fmt.Sprintf("Failed to update resource mapping (%s)", id), err) } @@ -140,6 +152,8 @@ func updateResourceMapping(cmd *cobra.Command, args []string) { {"Terms", strings.Join(resourceMapping.GetTerms(), ", ")}, {"Group Id", resourceMapping.GetGroup().GetId()}, {"Group Name", resourceMapping.GetGroup().GetName()}, + {"Namespace Id", resourceMapping.GetNamespace().GetId()}, + {"Namespace", resourceMapping.GetNamespace().GetFqn()}, } if mdRows := getMetadataRows(resourceMapping.GetMetadata()); mdRows != nil { rows = append(rows, mdRows...) @@ -174,6 +188,8 @@ func deleteResourceMapping(cmd *cobra.Command, args []string) { {"Terms", strings.Join(resourceMapping.GetTerms(), ", ")}, {"Group Id", resourceMapping.GetGroup().GetId()}, {"Group Name", resourceMapping.GetGroup().GetName()}, + {"Namespace Id", resourceMapping.GetNamespace().GetId()}, + {"Namespace", resourceMapping.GetNamespace().GetFqn()}, } t := cli.NewTabular(rows...) common.HandleSuccess(cmd, resourceMapping.GetId(), t, resourceMapping) @@ -199,6 +215,16 @@ func initResourceMappingsCommands() { createDoc.GetDocFlag("group-id").Default, createDoc.GetDocFlag("group-id").Description, ) + createDoc.Flags().String( + createDoc.GetDocFlag("namespace-id").Name, + createDoc.GetDocFlag("namespace-id").Default, + createDoc.GetDocFlag("namespace-id").Description, + ) + createDoc.Flags().String( + createDoc.GetDocFlag("namespace-fqn").Name, + createDoc.GetDocFlag("namespace-fqn").Default, + createDoc.GetDocFlag("namespace-fqn").Description, + ) injectLabelFlags(&createDoc.Command, false) getDoc := man.Docs.GetCommand("policy/resource-mappings/get", @@ -213,6 +239,16 @@ func initResourceMappingsCommands() { listDoc := man.Docs.GetCommand("policy/resource-mappings/list", man.WithRun(listResourceMappings), ) + listDoc.Flags().String( + listDoc.GetDocFlag("namespace-id").Name, + listDoc.GetDocFlag("namespace-id").Default, + listDoc.GetDocFlag("namespace-id").Description, + ) + listDoc.Flags().String( + listDoc.GetDocFlag("namespace-fqn").Name, + listDoc.GetDocFlag("namespace-fqn").Default, + listDoc.GetDocFlag("namespace-fqn").Description, + ) injectListPaginationFlags(listDoc) updateDoc := man.Docs.GetCommand("policy/resource-mappings/update", @@ -239,6 +275,16 @@ func initResourceMappingsCommands() { updateDoc.GetDocFlag("group-id").Default, updateDoc.GetDocFlag("group-id").Description, ) + updateDoc.Flags().String( + updateDoc.GetDocFlag("namespace-id").Name, + updateDoc.GetDocFlag("namespace-id").Default, + updateDoc.GetDocFlag("namespace-id").Description, + ) + updateDoc.Flags().String( + updateDoc.GetDocFlag("namespace-fqn").Name, + updateDoc.GetDocFlag("namespace-fqn").Default, + updateDoc.GetDocFlag("namespace-fqn").Description, + ) injectLabelFlags(&updateDoc.Command, true) deleteDoc := man.Docs.GetCommand("policy/resource-mappings/delete", diff --git a/otdfctl/docs/man/policy/resource-mapping-groups/list.md b/otdfctl/docs/man/policy/resource-mapping-groups/list.md index 1e4d15833f..b82a5dea38 100644 --- a/otdfctl/docs/man/policy/resource-mapping-groups/list.md +++ b/otdfctl/docs/man/policy/resource-mapping-groups/list.md @@ -5,6 +5,12 @@ command: aliases: - l flags: + - name: namespace-id + description: Filter the list to resource mapping groups owned by this namespace ID. + default: '' + - name: namespace-fqn + description: Filter the list to resource mapping groups owned by this namespace FQN. + default: '' - name: limit shorthand: l description: Limit retrieved count diff --git a/otdfctl/docs/man/policy/resource-mappings/create.md b/otdfctl/docs/man/policy/resource-mappings/create.md index f64563446c..4e9caa1c65 100644 --- a/otdfctl/docs/man/policy/resource-mappings/create.md +++ b/otdfctl/docs/man/policy/resource-mappings/create.md @@ -16,6 +16,12 @@ command: - name: group-id description: The ID of the resource mapping group to assign this mapping to default: '' + - name: namespace-id + description: Optional ID of the namespace that owns this resource mapping. If a group is provided, it must match the group's namespace. + default: '' + - name: namespace-fqn + description: Optional FQN of the namespace that owns this resource mapping (alternative to namespace-id). + default: '' - name: label description: "Optional metadata 'labels' in the format: key=value" shorthand: l diff --git a/otdfctl/docs/man/policy/resource-mappings/list.md b/otdfctl/docs/man/policy/resource-mappings/list.md index 402865bad6..b97cea89dd 100644 --- a/otdfctl/docs/man/policy/resource-mappings/list.md +++ b/otdfctl/docs/man/policy/resource-mappings/list.md @@ -5,6 +5,12 @@ command: aliases: - l flags: + - name: namespace-id + description: Filter the list to resource mappings owned by this namespace ID. + default: '' + - name: namespace-fqn + description: Filter the list to resource mappings owned by this namespace FQN. + default: '' - name: limit shorthand: l description: Limit retrieved count diff --git a/otdfctl/docs/man/policy/resource-mappings/update.md b/otdfctl/docs/man/policy/resource-mappings/update.md index 9d38812a10..bf219e32b7 100644 --- a/otdfctl/docs/man/policy/resource-mappings/update.md +++ b/otdfctl/docs/man/policy/resource-mappings/update.md @@ -17,6 +17,12 @@ command: - name: group-id description: The ID of the resource mapping group to assign this mapping to default: '' + - name: namespace-id + description: Optional ID of the namespace that owns this resource mapping. If the mapping belongs to a group, it must match the group's namespace. + default: '' + - name: namespace-fqn + description: Optional FQN of the namespace that owns this resource mapping (alternative to namespace-id). + default: '' - name: label description: "Optional metadata 'labels' in the format: key=value" shorthand: l diff --git a/otdfctl/pkg/handlers/resourceMappingGroups.go b/otdfctl/pkg/handlers/resourceMappingGroups.go index 499df96a00..bdd3846eb8 100644 --- a/otdfctl/pkg/handlers/resourceMappingGroups.go +++ b/otdfctl/pkg/handlers/resourceMappingGroups.go @@ -33,8 +33,10 @@ func (h *Handler) GetResourceMappingGroup(ctx context.Context, id string) (*poli return res.GetResourceMappingGroup(), nil } -func (h *Handler) ListResourceMappingGroups(ctx context.Context, limit, offset int32) (*resourcemapping.ListResourceMappingGroupsResponse, error) { +func (h *Handler) ListResourceMappingGroups(ctx context.Context, namespaceID, namespaceFqn string, limit, offset int32) (*resourcemapping.ListResourceMappingGroupsResponse, error) { return h.sdk.ResourceMapping.ListResourceMappingGroups(ctx, &resourcemapping.ListResourceMappingGroupsRequest{ + NamespaceId: namespaceID, + NamespaceFqn: namespaceFqn, Pagination: &policy.PageRequest{ Limit: limit, Offset: offset, diff --git a/otdfctl/pkg/handlers/resourceMappings.go b/otdfctl/pkg/handlers/resourceMappings.go index ccb80d72bf..1372892eda 100644 --- a/otdfctl/pkg/handlers/resourceMappings.go +++ b/otdfctl/pkg/handlers/resourceMappings.go @@ -9,10 +9,12 @@ import ( ) // Creates and returns the created resource mapping -func (h *Handler) CreateResourceMapping(attributeID string, terms []string, grpID string, metadata *common.MetadataMutable) (*policy.ResourceMapping, error) { +func (h *Handler) CreateResourceMapping(attributeID string, terms []string, grpID, namespaceID, namespaceFqn string, metadata *common.MetadataMutable) (*policy.ResourceMapping, error) { res, err := h.sdk.ResourceMapping.CreateResourceMapping(context.Background(), &resourcemapping.CreateResourceMappingRequest{ AttributeValueId: attributeID, GroupId: grpID, + NamespaceId: namespaceID, + NamespaceFqn: namespaceFqn, Terms: terms, Metadata: metadata, }) @@ -34,8 +36,10 @@ func (h *Handler) GetResourceMapping(id string) (*policy.ResourceMapping, error) return res.GetResourceMapping(), nil } -func (h *Handler) ListResourceMappings(ctx context.Context, limit, offset int32) (*resourcemapping.ListResourceMappingsResponse, error) { +func (h *Handler) ListResourceMappings(ctx context.Context, namespaceID, namespaceFqn string, limit, offset int32) (*resourcemapping.ListResourceMappingsResponse, error) { return h.sdk.ResourceMapping.ListResourceMappings(ctx, &resourcemapping.ListResourceMappingsRequest{ + NamespaceId: namespaceID, + NamespaceFqn: namespaceFqn, Pagination: &policy.PageRequest{ Limit: limit, Offset: offset, @@ -45,12 +49,14 @@ func (h *Handler) ListResourceMappings(ctx context.Context, limit, offset int32) // TODO: verify updation behavior // Updates and returns the updated resource mapping -func (h *Handler) UpdateResourceMapping(id string, attrValueID string, grpID string, terms []string, metadata *common.MetadataMutable, behavior common.MetadataUpdateEnum) (*policy.ResourceMapping, error) { +func (h *Handler) UpdateResourceMapping(id, attrValueID, grpID, namespaceID, namespaceFqn string, terms []string, metadata *common.MetadataMutable, behavior common.MetadataUpdateEnum) (*policy.ResourceMapping, error) { _, err := h.sdk.ResourceMapping.UpdateResourceMapping(context.Background(), &resourcemapping.UpdateResourceMappingRequest{ Id: id, AttributeValueId: attrValueID, Terms: terms, GroupId: grpID, + NamespaceId: namespaceID, + NamespaceFqn: namespaceFqn, Metadata: metadata, MetadataUpdateBehavior: behavior, })