-
Notifications
You must be signed in to change notification settings - Fork 45
Expand file tree
/
Copy pathdelete.go
More file actions
154 lines (130 loc) · 4.94 KB
/
Copy pathdelete.go
File metadata and controls
154 lines (130 loc) · 4.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
/*
Copyright © 2023 OpenFGA
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package tuple
import (
"context"
"fmt"
"time"
"github.com/openfga/go-sdk/client"
"github.com/spf13/cobra"
"github.com/openfga/cli/internal/cmdutils"
"github.com/openfga/cli/internal/output"
"github.com/openfga/cli/internal/tuple"
"github.com/openfga/cli/internal/tuplefile"
)
// deleteCmd represents the delete command.
var deleteCmd = &cobra.Command{
Use: "delete",
Short: "Delete Relationship Tuples",
Args: ExactArgsOrFlag(3, "file"), //nolint:mnd
Long: "Delete relationship tuples from the store.",
Example: "fga tuple delete --store-id=01H0H015178Y2V4CX10C2KGHF4 user:anne can_view document:roadmap",
RunE: func(cmd *cobra.Command, args []string) error {
clientConfig := cmdutils.GetClientConfig(cmd)
fgaClient, err := clientConfig.GetFgaClient()
if err != nil {
return fmt.Errorf("failed to initialize FGA Client due to %w", err)
}
fileName, err := cmd.Flags().GetString("file")
if err != nil {
return fmt.Errorf("failed to parse file name due to %w", err)
}
if fileName != "" {
startTime := time.Now()
successPath, _ := cmd.Flags().GetString("success-log")
failurePath, _ := cmd.Flags().GetString("failure-log")
var successLogger, failureLogger *tuple.TupleLogger
if successPath != "" {
successLogger, err = tuple.NewTupleLogger(successPath)
if err != nil {
return err
}
defer successLogger.Close()
}
if failurePath != "" {
failureLogger, err = tuple.NewTupleLogger(failurePath)
if err != nil {
return err
}
defer failureLogger.Close()
}
clientTupleKeys, err := tuplefile.ReadTupleFile(fileName)
if err != nil {
return fmt.Errorf("failed to read file %s due to %w", fileName, err)
}
clientTupleKeyWithoutCondition := tuple.TupleKeysToTupleKeysWithoutCondition(clientTupleKeys...)
maxTuplesPerWrite, err := cmd.Flags().GetInt("max-tuples-per-write")
if err != nil {
return fmt.Errorf("failed to parse max-tuples-per-write due to %w", err)
}
maxParallelRequests, err := cmd.Flags().GetInt("max-parallel-requests")
if err != nil {
return fmt.Errorf("failed to parse max-parallel-requests due to %w", err)
}
writeRequest := client.ClientWriteRequest{
Deletes: clientTupleKeyWithoutCondition,
}
newCtx := tuple.WithSuccessLogger(cmd.Context(), successLogger)
newCtx = tuple.WithFailureLogger(newCtx, failureLogger)
response, err := tuple.ImportTuplesWithoutRampUp(
newCtx, fgaClient,
maxTuplesPerWrite, maxParallelRequests,
writeRequest)
if err != nil {
return err //nolint:wrapcheck
}
duration := time.Since(startTime)
timeSpent := duration.String()
outputResponse := make(map[string]interface{})
if !hideImportedTuples && successPath == "" && len(response.Successful) > 0 {
outputResponse["successful"] = response.Successful
}
if failurePath == "" && len(response.Failed) > 0 {
outputResponse["failed"] = response.Failed
}
outputResponse["total_count"] = len(clientTupleKeyWithoutCondition)
outputResponse["successful_count"] = len(response.Successful)
outputResponse["failed_count"] = len(response.Failed)
outputResponse["time_spent"] = timeSpent
return output.Display(outputResponse)
}
body := &client.ClientDeleteTuplesBody{
client.ClientTupleKeyWithoutCondition{
User: args[0],
Relation: args[1],
Object: args[2],
},
}
options := &client.ClientWriteOptions{}
_, err = fgaClient.DeleteTuples(context.Background()).Body(*body).Options(*options).Execute()
if err != nil {
return fmt.Errorf("failed to delete tuples due to %w", err)
}
return output.Display(output.EmptyStruct{})
},
}
func init() {
deleteCmd.Flags().String("file", "", "Tuples file")
deleteCmd.Flags().String("model-id", "", "Model ID")
deleteCmd.Flags().Int("max-tuples-per-write", tuple.MaxTuplesPerWrite, "Max tuples per write chunk.")
deleteCmd.Flags().Int("max-parallel-requests", tuple.MaxParallelRequests, "Max number of requests to issue to the server in parallel.") //nolint:lll
deleteCmd.Flags().BoolVar(&hideImportedTuples, "hide-imported-tuples", false, "Hide successfully imported tuples from output") //nolint:lll
}
func ExactArgsOrFlag(n int, flag string) cobra.PositionalArgs {
return func(cmd *cobra.Command, args []string) error {
if len(args) != n && !cmd.Flags().Changed(flag) {
return fmt.Errorf("at least %d arg(s) are required OR the flag --%s", n, flag) //nolint:err113
}
return nil
}
}