From f3dd446c1d9f833f0e1b0aa1c11b129c9cf65bfc Mon Sep 17 00:00:00 2001 From: jakedoublev Date: Mon, 16 Sep 2024 09:08:47 -0700 Subject: [PATCH 1/3] fix list table visibility --- cmd/policy-resourceMappings.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/policy-resourceMappings.go b/cmd/policy-resourceMappings.go index 731fefde..54c176be 100644 --- a/cmd/policy-resourceMappings.go +++ b/cmd/policy-resourceMappings.go @@ -100,7 +100,7 @@ func policy_listResourceMappings(cmd *cobra.Command, args []string) { "updated_at": metadata["Updated At"], })) } - t.WithRows(rows) + t = t.WithRows(rows) HandleSuccess(cmd, "", t, rmList) } From bd5662585f59e6c2db658e4a8a51801138e4d28b Mon Sep 17 00:00:00 2001 From: jakedoublev Date: Mon, 16 Sep 2024 09:19:40 -0700 Subject: [PATCH 2/3] add force delete flag and e2e tests --- cmd/dev.go | 2 +- cmd/policy-resourceMappings.go | 10 +- docs/man/policy/resource-mappings/create.md | 4 +- docs/man/policy/resource-mappings/delete.md | 4 +- docs/man/policy/resource-mappings/get.md | 2 +- docs/man/policy/resource-mappings/update.md | 6 +- e2e/resource-mapping.bats | 120 +++++++++++++++++++- 7 files changed, 133 insertions(+), 15 deletions(-) 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 From 071461ed508b1c08261859c14c8f5c8f4d7a3655 Mon Sep 17 00:00:00 2001 From: jakedoublev Date: Mon, 16 Sep 2024 12:27:39 -0700 Subject: [PATCH 3/3] cleanup --- e2e/encrypt-decrypt.bats | 4 ++++ e2e/kas-grants.bats | 3 +++ e2e/namespaces.bats | 4 ++++ 3 files changed, 11 insertions(+) diff --git a/e2e/encrypt-decrypt.bats b/e2e/encrypt-decrypt.bats index 10e7140e..c9f494d4 100755 --- a/e2e/encrypt-decrypt.bats +++ b/e2e/encrypt-decrypt.bats @@ -31,6 +31,10 @@ teardown() { rm -f $OUTFILE_GO_MOD $RESULTFILE_GO_MOD $OUTFILE_TXT } +teardown_file(){ + ./otdfctl --host "$HOST" $WITH_CREDS policy attributes namespaces unsafe delete --id "$NS_ID" --force +} + @test "roundtrip TDF3, no attributes, file" { ./otdfctl encrypt -o $OUTFILE_GO_MOD --host $HOST --tls-no-verify $DEBUG_LEVEL $WITH_CREDS --tdf-type tdf3 $INFILE_GO_MOD ./otdfctl decrypt -o $RESULTFILE_GO_MOD --host $HOST --tls-no-verify $DEBUG_LEVEL $WITH_CREDS --tdf-type tdf3 $OUTFILE_GO_MOD diff --git a/e2e/kas-grants.bats b/e2e/kas-grants.bats index 4869d069..7e3c24ea 100755 --- a/e2e/kas-grants.bats +++ b/e2e/kas-grants.bats @@ -28,6 +28,9 @@ setup() { } teardown_file() { + ./otdfctl $HOST $WITH_CREDS policy attributes namespaces unsafe delete --id "$NS_ID" --force + ./otdfctl $HOST $WITH_CREDS policy kas-registry delete --id "$KAS_ID" --force + # clear out all test env vars unset HOST WITH_CREDS KAS_ID KAS_ID_FLAG KAS_URI NS_ID NS_ID_FLAG ATTR_ID ATTR_ID_FLAG VAL_ID VAL_ID_FLAG } diff --git a/e2e/namespaces.bats b/e2e/namespaces.bats index b9af3e62..310f7ac6 100755 --- a/e2e/namespaces.bats +++ b/e2e/namespaces.bats @@ -37,6 +37,10 @@ teardown_file() { assert_output --partial "Id" assert_output --partial "Created At" assert_output --regexp "Updated At" + + # cleanup + created_id=$(echo "$output" | grep Id | awk -F'│' '{print $3}' | xargs) + run_otdfctl_ns unsafe delete --id $created_id --force } @test "Create a namespace - Bad" {