@@ -3,18 +3,26 @@ package delete
33import (
44 "context"
55
6+ "github.com/AlecAivazis/survey/v2"
67 "github.com/redhat-developer/app-services-cli/internal/config"
78 "github.com/redhat-developer/app-services-cli/pkg/cmd/factory"
89 "github.com/redhat-developer/app-services-cli/pkg/cmd/kafka/acl/common"
910 "github.com/redhat-developer/app-services-cli/pkg/cmdutil"
1011 "github.com/redhat-developer/app-services-cli/pkg/connection"
12+ "github.com/redhat-developer/app-services-cli/pkg/dump"
13+ "github.com/redhat-developer/app-services-cli/pkg/icon"
1114 "github.com/redhat-developer/app-services-cli/pkg/iostreams"
1215 "github.com/redhat-developer/app-services-cli/pkg/localize"
1316 "github.com/redhat-developer/app-services-cli/pkg/logging"
1417 kafkainstanceclient "github.com/redhat-developer/app-services-sdk-go/kafkainstance/apiv1internal/client"
1518 "github.com/spf13/cobra"
1619)
1720
21+ var (
22+ serviceAccount string
23+ userID string
24+ )
25+
1826type options struct {
1927 Config config.IConfig
2028 Connection factory.ConnectionFunc
@@ -32,10 +40,10 @@ type options struct {
3240 group string
3341 topic string
3442 transactionalID string
35- userID string
36- serviceAccount string
43+ principal string
3744
38- output string
45+ skipConfirm bool
46+ output string
3947}
4048
4149// NewDeleteCommand creates a new command to list Kafka ACL rules
@@ -82,14 +90,30 @@ func NewDeleteCommand(f *factory.Factory) *cobra.Command {
8290 resourceTypeFlagEntries := []* localize.TemplateEntry {
8391 localize .NewEntry ("ClusterFlag" , common .ClusterFlagName ),
8492 localize .NewEntry ("TopicFlag" , common .TopicFlagName ),
85- localize .NewEntry ("TransactionalIDFlag" , common .TopicFlagName ),
93+ localize .NewEntry ("TransactionalIDFlag" , common .TransactionalIDFlagName ),
8694 localize .NewEntry ("GroupFlag" , common .GroupFlagName ),
8795 }
8896
8997 if selectedResourceTypeCount != 1 {
9098 return opts .localizer .MustLocalizeError ("kafka.acl.common.error.oneResourceTypeAllowed" , resourceTypeFlagEntries ... )
9199 }
92100
101+ // check if priincipal is provided
102+ if userID == "" && serviceAccount == "" {
103+ return opts .localizer .MustLocalizeError ("kafka.acl.common.error.noPrincipalsSelected" )
104+ }
105+
106+ // user and service account should not be provided together
107+ if userID != "" && serviceAccount != "" {
108+ return opts .localizer .MustLocalizeError ("kafka.acl.common.error.bothPrincipalsSelected" )
109+ }
110+
111+ if userID != "" {
112+ opts .principal = userID
113+ } else {
114+ opts .principal = serviceAccount
115+ }
116+
93117 cfg , err := opts .Config .Load ()
94118 if err != nil {
95119 return err
@@ -109,16 +133,16 @@ func NewDeleteCommand(f *factory.Factory) *cobra.Command {
109133
110134 _ = fs .AddPermission (& opts .permission ).Required ()
111135 _ = fs .AddOperation (& opts .operation ).Required ()
112- // TODO: Should not be required when resource type is cluster
113136
114137 fs .AddCluster (& opts .cluster )
115138 fs .AddPrefix (& opts .prefix )
116139 fs .AddTopic (& opts .topic )
117140 fs .AddConsumerGroup (& opts .group )
118141 fs .AddTransactionalID (& opts .transactionalID )
119142 fs .AddOutput (& opts .output )
120- fs .AddUser (& opts .userID )
121- fs .AddServiceAccount (& opts .serviceAccount )
143+ fs .AddUser (& userID )
144+ fs .AddServiceAccount (& serviceAccount )
145+ fs .AddYes (& opts .skipConfirm )
122146
123147 return cmd
124148}
@@ -157,10 +181,50 @@ func runDelete(instanceID string, opts *options) error {
157181 if opts .prefix {
158182 patternType = kafkainstanceclient .ACLPATTERNTYPEFILTER_PREFIXED
159183 }
184+
185+ // TODO ensure ALL ACLs are fetched
186+ aclList , httpRes , err := adminAPI .AclsApi .GetAcls (opts .Context ).
187+ ResourceType (common .GetResourceTypeFilter (opts .resourceType )).
188+ Principal (common .FormatPrincipal (opts .principal )).
189+ PatternType (patternType ).
190+ ResourceName (opts .resourceName ).
191+ Operation (common .GetOperationFilter (opts .operation )).
192+ Permission (common .GetPermissionFilter (opts .permission )).
193+ Execute ()
194+ if httpRes != nil {
195+ defer httpRes .Body .Close ()
196+ }
197+ if err != nil {
198+ return err
199+ }
200+ if aclList .GetTotal () == 0 {
201+ opts .Logger .Info ("No ACLs matching this criteria to delete" )
202+ return nil
203+ }
204+
205+ rows := common .MapACLsToTable (aclList .GetItems (), opts .localizer )
206+ opts .Logger .Info (icon .Warning (), "The following ACLs will be deleted:" )
207+ opts .Logger .Info ()
208+ dump .Table (opts .IO .ErrOut , rows )
209+ opts .Logger .Info ()
210+
211+ if ! opts .skipConfirm {
212+ prompt := & survey.Confirm {
213+ Message : "Are you sure you want to delete these ACLs?" ,
214+ }
215+ if err = survey .AskOne (prompt , & opts .skipConfirm ); err != nil {
216+ return err
217+ }
218+
219+ if ! opts .skipConfirm {
220+ opts .Logger .Debug ("User has not confirmed there wish to delete ACLs, returning" )
221+ return nil
222+ }
223+ }
224+
160225 bindingList , httpRes , err := adminAPI .AclsApi .DeleteAcls (opts .Context ).
161226 ResourceType (common .GetResourceTypeFilter (opts .resourceType )).
162- // TODO: Allow adding of principal via arguments
163- Principal ("User:enda1" ).
227+ Principal (common .FormatPrincipal (opts .principal )).
164228 PatternType (patternType ).
165229 ResourceName (opts .resourceName ).
166230 Operation (common .GetOperationFilter (opts .operation )).
@@ -175,7 +239,7 @@ func runDelete(instanceID string, opts *options) error {
175239 return err
176240 }
177241
178- opts .Logger .Info ("Deleted" , len ( bindingList .GetItems ()) , "ACLs " )
242+ opts .Logger .Info ("Deleted" , bindingList .GetTotal () , "ACL(s) " )
179243
180244 return nil
181245}
0 commit comments