diff --git a/cmd/dev.go b/cmd/dev.go index 7a76155e..75238aba 100644 --- a/cmd/dev.go +++ b/cmd/dev.go @@ -124,7 +124,7 @@ func HandleSuccess(command *cobra.Command, id string, t table.Model, policyObjec func injectLabelFlags(cmd *cobra.Command, isUpdate bool) { cmd.Flags().StringSliceVarP(&metadataLabels, "label", "l", []string{}, "Optional metadata 'labels' in the format: key=value") if isUpdate { - cmd.Flags().BoolVar(&forceReplaceMetadataLabels, "force-replace-labels", false, "Destructively replace entire set of existing metadata 'labels' with any provided to this command.") + cmd.Flags().BoolVar(&forceReplaceMetadataLabels, "force-replace-labels", false, "Destructively replace entire set of existing metadata 'labels' with any provided to this command") } } diff --git a/cmd/policy-resourceMappings.go b/cmd/policy-resourceMappings.go index 54c176be..4d822bb6 100644 --- a/cmd/policy-resourceMappings.go +++ b/cmd/policy-resourceMappings.go @@ -137,8 +137,11 @@ func policy_deleteResourceMapping(cmd *cobra.Command, args []string) { defer h.Close() id := c.Flags.GetRequiredID("id") + force := c.Flags.GetOptionalBool("force") - cli.ConfirmAction(cli.ActionDelete, "resource-mapping", id, false) + if !force { + cli.ConfirmAction(cli.ActionDelete, "resource-mapping", id, false) + } resourceMapping, err := h.DeleteResourceMapping(id) if err != nil { @@ -213,6 +216,11 @@ func init() { 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-mappings", man.WithSubcommands(createDoc, getDoc, listDoc, updateDoc, deleteDoc), diff --git a/docs/man/policy/resource-mappings/create.md b/docs/man/policy/resource-mappings/create.md index f56ee210..8f3a8fe6 100644 --- a/docs/man/policy/resource-mappings/create.md +++ b/docs/man/policy/resource-mappings/create.md @@ -8,10 +8,10 @@ command: - c flags: - name: attribute-value-id - description: The ID of the attribute value to map to the resource. + description: The ID of the attribute value to map to the resource default: "" - name: terms - description: The synonym terms to match for the resource mapping. + description: The synonym terms to match for the resource mapping default: "" - name: label description: "Optional metadata 'labels' in the format: key=value" diff --git a/docs/man/policy/resource-mappings/delete.md b/docs/man/policy/resource-mappings/delete.md index f27b1c38..6a9bbb29 100644 --- a/docs/man/policy/resource-mappings/delete.md +++ b/docs/man/policy/resource-mappings/delete.md @@ -4,8 +4,10 @@ command: name: delete flags: - name: id - description: The ID of the resource mapping to delete. + description: The ID of the resource mapping to delete default: '' + - name: force + description: Force deletion without interactive confirmation (dangerous) --- # Delete a resource mapping diff --git a/docs/man/policy/resource-mappings/get.md b/docs/man/policy/resource-mappings/get.md index d2afa3a1..43257a15 100644 --- a/docs/man/policy/resource-mappings/get.md +++ b/docs/man/policy/resource-mappings/get.md @@ -6,7 +6,7 @@ command: - g flags: - name: id - description: The ID of the resource mapping to get. + description: The ID of the resource mapping to get default: "" --- diff --git a/docs/man/policy/resource-mappings/update.md b/docs/man/policy/resource-mappings/update.md index fb1e1f8d..555808b5 100644 --- a/docs/man/policy/resource-mappings/update.md +++ b/docs/man/policy/resource-mappings/update.md @@ -6,13 +6,13 @@ command: - u flags: - name: id - description: The ID of the resource mapping to update. + description: The ID of the resource mapping to update default: "" - name: attribute-value-id - description: The ID of the attribute value to map to the resource. + description: The ID of the attribute value to map to the resource default: "" - name: terms - description: The synonym terms to match for the resource mapping. + description: The synonym terms to match for the resource mapping default: "" - name: label description: "Optional metadata 'labels' in the format: key=value" diff --git a/e2e/resource-mapping.bats b/e2e/resource-mapping.bats index dc6accca..110aed16 100755 --- a/e2e/resource-mapping.bats +++ b/e2e/resource-mapping.bats @@ -2,14 +2,122 @@ # Tests for resource mappings -# Create resource mapping +setup_file() { + echo -n '{"clientId":"opentdf","clientSecret":"secret"}' > creds.json + export WITH_CREDS='--with-client-creds-file ./creds.json' + export HOST='--host http://localhost:8080' -# Get resource mapping + # Create two namespaced values to be used in other tests + NS_NAME="resource-mappings.io" + export NS_ID=$(./otdfctl $HOST $WITH_CREDS policy attributes namespaces create -n "$NS_NAME" --json | jq -r '.id') + ATTR_ID=$(./otdfctl $HOST $WITH_CREDS policy attributes create --namespace "$NS_ID" --name attr1 --rule ANY_OF --json | jq -r '.id') + export VAL1_ID=$(./otdfctl $HOST $WITH_CREDS policy attributes values create --attribute-id "$ATTR_ID" --value val1 --json | jq -r '.id') + export VAL2_ID=$(./otdfctl $HOST $WITH_CREDS policy attributes values create --attribute-id "$ATTR_ID" --value val2 --json | jq -r '.id') -# Update resource mapping + # Create a single resource mapping to val1 - comma separated + export RM1_TERMS="valueone,valuefirst,first,one" + export RM1_ID=$(./otdfctl $HOST $WITH_CREDS policy resource-mappings create --attribute-value-id "$VAL1_ID" --terms "$RM1_TERMS" --json | jq -r '.id') +} -# List resource mappings +setup() { + load "${BATS_LIB_PATH}/bats-support/load.bash" + load "${BATS_LIB_PATH}/bats-assert/load.bash" -# Delete resource mapping + # invoke binary with credentials + run_otdfctl_rm () { + run sh -c "./otdfctl $HOST $WITH_CREDS policy resource-mappings $*" + } -# Cleanup - delete everything \ No newline at end of file +} + +teardown_file() { + # remove the created namespace with all underneath upon test suite completion + ./otdfctl $HOST $WITH_CREDS policy attributes namespaces unsafe delete --force --id "$NS_ID" + + unset HOST WITH_CREDS VAL1_ID VAL2_ID NS_ID RM1_TERMS RM1_ID +} + +@test "Create resource mapping" { + # create with multiple terms flags instead of comma-separated + run_otdfctl_rm create --attribute-value-id "$VAL2_ID" --terms "second" --terms "TWO" + assert_success + assert_output --partial "second" + assert_output --partial "TWO" + assert_output --regexp "Attribute Value Id.*$VAL2_ID" + + # value id flag must be uuid + run_otdfctl_rm create --attribute-value-id "val2" --terms "testing" + assert_failure + assert_output --partial "must be a valid UUID" + + # terms are required + run_otdfctl_rm create --attribute-value-id $VAL2_ID + assert_failure + assert_output --partial "must have at least 1 non-empty values" +} + +@test "Get resource mapping" { + spaced_terms=$(echo $RM1_TERMS | sed 's/,/, /g') + # table + run_otdfctl_rm get --id "$RM1_ID" + assert_success + assert_output --regexp "Id.*$RM1_ID" + assert_output --regexp "Attribute Value Id.*$VAL1_ID" + assert_output --regexp "Terms.*$spaced_terms" + + # json + run_otdfctl_rm get --id "$RM1_ID" --json + assert_success + [ $(echo $output | jq -r '.id') = "$RM1_ID" ] + [ $(echo $output | jq -r '.attribute_value.id') = "$VAL1_ID" ] + [ $(echo $output | jq -r '.terms | join (",")') = "$RM1_TERMS" ] + + # id required + run_otdfctl_rm get + assert_failure + assert_output --partial "is required" + run_otdfctl_rm get --id "test" + assert_failure + assert_output --partial "must be a valid UUID" +} + +@test "Update a resource mapping" { + NEW_RM_ID=$(./otdfctl $HOST $WITH_CREDS policy resource-mappings create --attribute-value-id "$VAL2_ID" --terms test --terms found --json | jq -r '.id') + + # replace the terms + run_otdfctl_rm update --id "$NEW_RM_ID" --terms replaced,new + assert_success + refute_output --partial "test" + refute_output --partial "found" + assert_output --partial "replaced" + assert_output --partial "new" + assert_output --partial "$VAL2_ID" + + # reassign the attribute value being mapped + run_otdfctl_rm update --id "$NEW_RM_ID" --attribute-value-id "$VAL1_ID" + assert_success + refute_output --partial "test" + refute_output --partial "found" + assert_output --partial "replaced" + assert_output --partial "new" + refute_output --partial "$VAL2_ID" + assert_output --partial "$VAL1_ID" +} + +@test "List resource mappings" { + run_otdfctl_rm list + assert_success + assert_output --partial "$RM1_ID" + assert_output --partial "$VAL1_ID" + assert_output --partial "valueone, valuefirst, first" +} + +@test "Delete resource mapping" { + spaced_terms=$(echo $RM1_TERMS | sed 's/,/, /g') + # --force to avoid indefinite hang waiting for confirmation + run_otdfctl_rm delete --id "$RM1_ID" --force + assert_success + assert_output --regexp "Id.*$RM1_ID" + assert_output --regexp "Attribute Value Id.*$VAL1_ID" + assert_output --regexp "Terms.*$spaced_terms" +} \ No newline at end of file