Skip to content
225 changes: 225 additions & 0 deletions cmd/policy-resourceMappingGroups.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
package cmd

import (
"fmt"

"github.com/evertras/bubble-table/table"
"github.com/opentdf/otdfctl/pkg/cli"
"github.com/opentdf/otdfctl/pkg/man"
"github.com/spf13/cobra"
)

var (
policyResourceMappingGroupsCmd *cobra.Command
)

func policyCreateResourceMappingGroup(cmd *cobra.Command, args []string) {
c := cli.New(cmd, args)
h := NewHandler(c)
defer h.Close()

nsID := c.Flags.GetRequiredID("namespace-id")
name := c.Flags.GetRequiredString("name")
metadataLabels = c.Flags.GetStringSlice("label", metadataLabels, cli.FlagsStringSliceOptions{Min: 0})

resourceMappingGroup, err := h.CreateResourceMappingGroup(nsID, name, getMetadataMutable(metadataLabels))
if err != nil {
cli.ExitWithError("Failed to create resource mapping group", err)
}
rows := [][]string{
{"Id", resourceMappingGroup.GetId()},
{"Namespace Id", resourceMappingGroup.GetNamespaceId()},
{"Group Name", resourceMappingGroup.GetName()},
}
if mdRows := getMetadataRows(resourceMappingGroup.GetMetadata()); mdRows != nil {
rows = append(rows, mdRows...)
}
t := cli.NewTabular(rows...)
HandleSuccess(cmd, resourceMappingGroup.GetId(), t, resourceMappingGroup)
}

func policyGetResourceMappingGroup(cmd *cobra.Command, args []string) {
c := cli.New(cmd, args)
h := NewHandler(c)
defer h.Close()

id := c.Flags.GetRequiredID("id")

resourceMappingGroup, err := h.GetResourceMappingGroup(id)
if err != nil {
cli.ExitWithError(fmt.Sprintf("Failed to get resource mapping group (%s)", id), err)
}
rows := [][]string{
{"Id", resourceMappingGroup.GetId()},
{"Namespace Id", resourceMappingGroup.GetNamespaceId()},
{"Group Name", resourceMappingGroup.GetName()},
}
if mdRows := getMetadataRows(resourceMappingGroup.GetMetadata()); mdRows != nil {
rows = append(rows, mdRows...)
}
t := cli.NewTabular(rows...)
HandleSuccess(cmd, resourceMappingGroup.GetId(), t, resourceMappingGroup)
}

func policyListResourceMappingGroups(cmd *cobra.Command, args []string) {
c := cli.New(cmd, args)
h := NewHandler(c)
defer h.Close()

limit := c.Flags.GetRequiredInt32("limit")
offset := c.Flags.GetRequiredInt32("offset")

rmgList, page, err := h.ListResourceMappingGroups(cmd.Context(), limit, offset)
if err != nil {
cli.ExitWithError("Failed to list resource mapping groups", err)
}

t := cli.NewTable(
cli.NewUUIDColumn(),
table.NewFlexColumn("ns_id", "Namespace ID", cli.FlexColumnWidthFour),
table.NewFlexColumn("name", "Name", cli.FlexColumnWidthFour),
table.NewFlexColumn("labels", "Labels", cli.FlexColumnWidthOne),
table.NewFlexColumn("created_at", "Created At", cli.FlexColumnWidthOne),
table.NewFlexColumn("updated_at", "Updated At", cli.FlexColumnWidthOne),
)
rows := []table.Row{}
for _, rmg := range rmgList {
metadata := cli.ConstructMetadata(rmg.GetMetadata())
rows = append(rows, table.NewRow(table.RowData{
"id": rmg.GetId(),
"ns_id": rmg.GetNamespaceId(),
"name": rmg.GetName(),
"labels": metadata["Labels"],
"created_at": metadata["Created At"],
"updated_at": metadata["Updated At"],
}))
}
t = t.WithRows(rows)
t = cli.WithListPaginationFooter(t, page)
HandleSuccess(cmd, "", t, rmgList)
}

func policyUpdateResourceMappingGroup(cmd *cobra.Command, args []string) {
c := cli.New(cmd, args)
h := NewHandler(c)
defer h.Close()

id := c.Flags.GetRequiredID("id")
nsID := c.Flags.GetOptionalID("namespace-id")
name := c.Flags.GetOptionalString("name")
metadataLabels = c.Flags.GetStringSlice("label", metadataLabels, cli.FlagsStringSliceOptions{Min: 0})

resourceMappingGroup, err := h.UpdateResourceMappingGroup(id, nsID, name, getMetadataMutable(metadataLabels), getMetadataUpdateBehavior())
if err != nil {
cli.ExitWithError(fmt.Sprintf("Failed to update resource mapping group (%s)", id), err)
}
rows := [][]string{
{"Id", resourceMappingGroup.GetId()},
{"Namespace Id", resourceMappingGroup.GetNamespaceId()},
{"Group Name", resourceMappingGroup.GetName()},
}
if mdRows := getMetadataRows(resourceMappingGroup.GetMetadata()); mdRows != nil {
rows = append(rows, mdRows...)
}
t := cli.NewTabular(rows...)
HandleSuccess(cmd, resourceMappingGroup.GetId(), t, resourceMappingGroup)
}

func policyDeleteResourceMappingGroup(cmd *cobra.Command, args []string) {
c := cli.New(cmd, args)
h := NewHandler(c)
defer h.Close()

id := c.Flags.GetRequiredID("id")
force := c.Flags.GetOptionalBool("force")

cli.ConfirmAction(cli.ActionDelete, "resource-mapping-group", id, force)

resourceMappingGroup, err := h.GetResourceMappingGroup(id)
if err != nil {
cli.ExitWithError(fmt.Sprintf("Failed to get resource mapping group for delete (%s)", id), err)
}

_, err = h.DeleteResourceMappingGroup(id)
if err != nil {
cli.ExitWithError(fmt.Sprintf("Failed to delete resource mapping group (%s)", id), err)
}
rows := [][]string{
{"Id", resourceMappingGroup.GetId()},
{"Namespace Id", resourceMappingGroup.GetNamespaceId()},
{"Group Name", resourceMappingGroup.GetName()},
}
t := cli.NewTabular(rows...)
HandleSuccess(cmd, resourceMappingGroup.GetId(), t, resourceMappingGroup)
}

func init() {
createDoc := man.Docs.GetCommand("policy/resource-mapping-groups/create",
man.WithRun(policyCreateResourceMappingGroup),
)
createDoc.Flags().String(
createDoc.GetDocFlag("namespace-id").Name,
createDoc.GetDocFlag("namespace-id").Default,
createDoc.GetDocFlag("namespace-id").Description,
)
createDoc.Flags().String(
createDoc.GetDocFlag("name").Name,
createDoc.GetDocFlag("name").Default,
createDoc.GetDocFlag("name").Description,
)
injectLabelFlags(&createDoc.Command, false)

getDoc := man.Docs.GetCommand("policy/resource-mapping-groups/get",
man.WithRun(policyGetResourceMappingGroup),
)
getDoc.Flags().String(
getDoc.GetDocFlag("id").Name,
getDoc.GetDocFlag("id").Default,
getDoc.GetDocFlag("id").Description,
)

listDoc := man.Docs.GetCommand("policy/resource-mapping-groups/list",
man.WithRun(policyListResourceMappingGroups),
)
injectListPaginationFlags(listDoc)

updateDoc := man.Docs.GetCommand("policy/resource-mapping-groups/update",
man.WithRun(policyUpdateResourceMappingGroup),
)
updateDoc.Flags().String(
updateDoc.GetDocFlag("id").Name,
updateDoc.GetDocFlag("id").Default,
updateDoc.GetDocFlag("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("name").Name,
updateDoc.GetDocFlag("name").Default,
updateDoc.GetDocFlag("name").Description,
)
injectLabelFlags(&updateDoc.Command, true)

deleteDoc := man.Docs.GetCommand("policy/resource-mapping-groups/delete",
man.WithRun(policyDeleteResourceMappingGroup),
)
deleteDoc.Flags().String(
deleteDoc.GetDocFlag("id").Name,
deleteDoc.GetDocFlag("id").Default,
deleteDoc.GetDocFlag("id").Description,
)
deleteDoc.Flags().Bool(
deleteDoc.GetDocFlag("force").Name,
false,
deleteDoc.GetDocFlag("force").Description,
)

doc := man.Docs.GetCommand("policy/resource-mapping-groups",
man.WithSubcommands(createDoc, getDoc, listDoc, updateDoc, deleteDoc),
)
policyResourceMappingGroupsCmd = &doc.Command
policyCmd.AddCommand(policyResourceMappingGroupsCmd)
}
34 changes: 29 additions & 5 deletions cmd/policy-resourceMappings.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,13 @@ func policy_createResourceMapping(cmd *cobra.Command, args []string) {
defer h.Close()

attrId := c.Flags.GetRequiredID("attribute-value-id")
grpID := c.Flags.GetOptionalID("group-id")
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, getMetadataMutable(metadataLabels))
resourceMapping, err := h.CreateResourceMapping(attrId, terms, grpID, getMetadataMutable(metadataLabels))
if err != nil {
cli.ExitWithError("Failed to create resource mapping", err)
}
Expand All @@ -36,6 +37,8 @@ func policy_createResourceMapping(cmd *cobra.Command, args []string) {
{"Attribute Value Id", resourceMapping.GetAttributeValue().GetId()},
{"Attribute Value", resourceMapping.GetAttributeValue().GetValue()},
{"Terms", strings.Join(resourceMapping.GetTerms(), ", ")},
{"Group Id", resourceMapping.GetGroup().GetId()},
{"Group Name", resourceMapping.GetGroup().GetName()},
}
if mdRows := getMetadataRows(resourceMapping.GetMetadata()); mdRows != nil {
rows = append(rows, mdRows...)
Expand All @@ -60,6 +63,8 @@ func policy_getResourceMapping(cmd *cobra.Command, args []string) {
{"Attribute Value Id", resourceMapping.GetAttributeValue().GetId()},
{"Attribute Value", resourceMapping.GetAttributeValue().GetValue()},
{"Terms", strings.Join(resourceMapping.GetTerms(), ", ")},
{"Group Id", resourceMapping.GetGroup().GetId()},
{"Group Name", resourceMapping.GetGroup().GetName()},
}
if mdRows := getMetadataRows(resourceMapping.GetMetadata()); mdRows != nil {
rows = append(rows, mdRows...)
Expand All @@ -83,9 +88,11 @@ func policy_listResourceMappings(cmd *cobra.Command, args []string) {

t := cli.NewTable(
cli.NewUUIDColumn(),
table.NewFlexColumn("attr_value_id", "Attribute Value Id", cli.FlexColumnWidthFour),
table.NewFlexColumn("attr_value", "Attribute Value", cli.FlexColumnWidthFour),
table.NewFlexColumn("terms", "Terms", cli.FlexColumnWidthThree),
table.NewFlexColumn("attr_value_id", "Attribute Value Id", cli.FlexColumnWidthFive),
table.NewFlexColumn("attr_value", "Attribute Value", cli.FlexColumnWidthTwo),
table.NewFlexColumn("terms", "Terms", cli.FlexColumnWidthFour),
table.NewFlexColumn("group_id", "Group Id", cli.FlexColumnWidthFive),
table.NewFlexColumn("group_name", "Group Name", cli.FlexColumnWidthTwo),
table.NewFlexColumn("labels", "Labels", cli.FlexColumnWidthOne),
table.NewFlexColumn("created_at", "Created At", cli.FlexColumnWidthOne),
table.NewFlexColumn("updated_at", "Updated At", cli.FlexColumnWidthOne),
Expand All @@ -97,6 +104,8 @@ func policy_listResourceMappings(cmd *cobra.Command, args []string) {
"id": resourceMapping.GetId(),
"attr_value_id": resourceMapping.GetAttributeValue().GetId(),
"attr_value": resourceMapping.GetAttributeValue().GetValue(),
"group_id": resourceMapping.GetGroup().GetId(),
"group_name": resourceMapping.GetGroup().GetName(),
"terms": strings.Join(resourceMapping.GetTerms(), ", "),
"labels": metadata["Labels"],
"created_at": metadata["Created At"],
Expand All @@ -115,10 +124,11 @@ func policy_updateResourceMapping(cmd *cobra.Command, args []string) {

id := c.Flags.GetRequiredID("id")
attrValueId := c.Flags.GetOptionalID("attribute-value-id")
grpID := c.Flags.GetOptionalID("group-id")
terms = c.Flags.GetStringSlice("terms", terms, cli.FlagsStringSliceOptions{})
metadataLabels = c.Flags.GetStringSlice("label", metadataLabels, cli.FlagsStringSliceOptions{Min: 0})

resourceMapping, err := h.UpdateResourceMapping(id, attrValueId, terms, getMetadataMutable(metadataLabels), getMetadataUpdateBehavior())
resourceMapping, err := h.UpdateResourceMapping(id, attrValueId, grpID, terms, getMetadataMutable(metadataLabels), getMetadataUpdateBehavior())
if err != nil {
cli.ExitWithError(fmt.Sprintf("Failed to update resource mapping (%s)", id), err)
}
Expand All @@ -127,6 +137,8 @@ func policy_updateResourceMapping(cmd *cobra.Command, args []string) {
{"Attribute Value Id", resourceMapping.GetAttributeValue().GetId()},
{"Attribute Value", resourceMapping.GetAttributeValue().GetValue()},
{"Terms", strings.Join(resourceMapping.GetTerms(), ", ")},
{"Group Id", resourceMapping.GetGroup().GetId()},
{"Group Name", resourceMapping.GetGroup().GetName()},
}
if mdRows := getMetadataRows(resourceMapping.GetMetadata()); mdRows != nil {
rows = append(rows, mdRows...)
Expand Down Expand Up @@ -159,6 +171,8 @@ func policy_deleteResourceMapping(cmd *cobra.Command, args []string) {
{"Attribute Value Id", resourceMapping.GetAttributeValue().GetId()},
{"Attribute Value", resourceMapping.GetAttributeValue().GetValue()},
{"Terms", strings.Join(resourceMapping.GetTerms(), ", ")},
{"Group Id", resourceMapping.GetGroup().GetId()},
{"Group Name", resourceMapping.GetGroup().GetName()},
}
t := cli.NewTabular(rows...)
HandleSuccess(cmd, resourceMapping.GetId(), t, resourceMapping)
Expand All @@ -179,6 +193,11 @@ func init() {
[]string{},
createDoc.GetDocFlag("terms").Description,
)
createDoc.Flags().String(
createDoc.GetDocFlag("group-id").Name,
createDoc.GetDocFlag("group-id").Default,
createDoc.GetDocFlag("group-id").Description,
)
injectLabelFlags(&createDoc.Command, false)

getDoc := man.Docs.GetCommand("policy/resource-mappings/get",
Expand Down Expand Up @@ -214,6 +233,11 @@ func init() {
[]string{},
updateDoc.GetDocFlag("terms").Description,
)
updateDoc.Flags().String(
updateDoc.GetDocFlag("group-id").Name,
updateDoc.GetDocFlag("group-id").Default,
updateDoc.GetDocFlag("group-id").Description,
)
injectLabelFlags(&updateDoc.Command, true)

deleteDoc := man.Docs.GetCommand("policy/resource-mappings/delete",
Expand Down
11 changes: 11 additions & 0 deletions docs/man/policy/resource-mapping-groups/_index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
title: Manage resource mapping groups
command:
name: resource-mapping-groups
aliases:
- resmg
- remapgrp
- resource-mapping-group
---

Resource mapping groups allow you to organize multiple resource mappings into logical collections. By grouping related resource mappings, you can manage sets of resources more efficiently. This is useful for scenarios where resources share common access controls or need to be managed together as a unit.
30 changes: 30 additions & 0 deletions docs/man/policy/resource-mapping-groups/create.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
---
title: Create a resource mapping group
command:
name: create
aliases:
- add
- new
- c
flags:
- name: namespace-id
description: The ID of the namespace of the group
default: ''
- name: name
description: The name of the group
default: ''
- name: label
description: "Optional metadata 'labels' in the format: key=value"
shorthand: l
default: ''
---

Create a new group to organize resource mappings. Resource mapping groups belong to a namespace and are identified by a name.

For more information about resource mapping groups, see the `resource-mapping-groups` subcommand.

## Examples

```shell
otdfctl policy resource-mapping-groups create --namespace-id 891cfe85-b381-4f85-9699-5f7dbfe2a9ab --name my-group
```
Loading
Loading