github.com/fastly/cli@v1.7.2-0.20240304164155-9d0f1d77c3bf/pkg/commands/aclentry/list.go (about) 1 package aclentry 2 3 import ( 4 "fmt" 5 "io" 6 7 "github.com/fastly/go-fastly/v9/fastly" 8 9 "github.com/fastly/cli/pkg/argparser" 10 fsterr "github.com/fastly/cli/pkg/errors" 11 "github.com/fastly/cli/pkg/global" 12 "github.com/fastly/cli/pkg/text" 13 ) 14 15 // NewListCommand returns a usable command registered under the parent. 16 func NewListCommand(parent argparser.Registerer, g *global.Data) *ListCommand { 17 c := ListCommand{ 18 Base: argparser.Base{ 19 Globals: g, 20 }, 21 } 22 c.CmdClause = parent.Command("list", "List ACLs") 23 24 // Required. 25 c.CmdClause.Flag("acl-id", "Alphanumeric string identifying a ACL").Required().StringVar(&c.aclID) 26 27 // Optional. 28 c.RegisterFlagBool(c.JSONFlag()) // --json 29 c.RegisterFlag(argparser.StringFlagOpts{ 30 Name: argparser.FlagServiceIDName, 31 Description: argparser.FlagServiceIDDesc, 32 Dst: &g.Manifest.Flag.ServiceID, 33 Short: 's', 34 }) 35 c.RegisterFlag(argparser.StringFlagOpts{ 36 Action: c.serviceName.Set, 37 Name: argparser.FlagServiceName, 38 Description: argparser.FlagServiceDesc, 39 Dst: &c.serviceName.Value, 40 }) 41 42 c.CmdClause.Flag("direction", "Direction in which to sort results").Default(argparser.PaginationDirection[0]).HintOptions(argparser.PaginationDirection...).EnumVar(&c.direction, argparser.PaginationDirection...) 43 c.CmdClause.Flag("page", "Page number of data set to fetch").IntVar(&c.page) 44 c.CmdClause.Flag("per-page", "Number of records per page").IntVar(&c.perPage) 45 c.CmdClause.Flag("sort", "Field on which to sort").Default("created").StringVar(&c.sort) 46 47 return &c 48 } 49 50 // ListCommand calls the Fastly API to list appropriate resources. 51 type ListCommand struct { 52 argparser.Base 53 argparser.JSONOutput 54 55 aclID string 56 direction string 57 page int 58 perPage int 59 serviceName argparser.OptionalServiceNameID 60 sort string 61 } 62 63 // Exec invokes the application logic for the command. 64 func (c *ListCommand) Exec(_ io.Reader, out io.Writer) error { 65 if c.Globals.Verbose() && c.JSONOutput.Enabled { 66 return fsterr.ErrInvalidVerboseJSONCombo 67 } 68 69 serviceID, source, flag, err := argparser.ServiceID(c.serviceName, *c.Globals.Manifest, c.Globals.APIClient, c.Globals.ErrLog) 70 if err != nil { 71 return err 72 } 73 if c.Globals.Verbose() { 74 argparser.DisplayServiceID(serviceID, flag, source, out) 75 } 76 77 input := c.constructInput(serviceID) 78 paginator := c.Globals.APIClient.GetACLEntries(input) 79 80 var o []*fastly.ACLEntry 81 for paginator.HasNext() { 82 data, err := paginator.GetNext() 83 if err != nil { 84 c.Globals.ErrLog.AddWithContext(err, map[string]any{ 85 "ACL ID": c.aclID, 86 "Service ID": serviceID, 87 "Remaining Pages": paginator.Remaining(), 88 }) 89 return err 90 } 91 o = append(o, data...) 92 } 93 94 if ok, err := c.WriteJSON(out, o); ok { 95 return err 96 } 97 98 if c.Globals.Verbose() { 99 c.printVerbose(out, o) 100 } else { 101 err = c.printSummary(out, o) 102 if err != nil { 103 return err 104 } 105 } 106 return nil 107 } 108 109 // constructInput transforms values parsed from CLI flags into an object to be used by the API client library. 110 func (c *ListCommand) constructInput(serviceID string) *fastly.GetACLEntriesInput { 111 var input fastly.GetACLEntriesInput 112 113 input.ACLID = c.aclID 114 if c.direction != "" { 115 input.Direction = fastly.ToPointer(c.direction) 116 } 117 if c.page > 0 { 118 input.Page = fastly.ToPointer(c.page) 119 } 120 if c.perPage > 0 { 121 input.PerPage = fastly.ToPointer(c.perPage) 122 } 123 input.ServiceID = serviceID 124 if c.sort != "" { 125 input.Sort = fastly.ToPointer(c.sort) 126 } 127 128 return &input 129 } 130 131 // printVerbose displays the information returned from the API in a verbose 132 // format. 133 func (c *ListCommand) printVerbose(out io.Writer, as []*fastly.ACLEntry) { 134 for _, a := range as { 135 fmt.Fprintf(out, "ACL ID: %s\n", fastly.ToValue(a.ACLID)) 136 fmt.Fprintf(out, "ID: %s\n", fastly.ToValue(a.EntryID)) 137 fmt.Fprintf(out, "IP: %s\n", fastly.ToValue(a.IP)) 138 fmt.Fprintf(out, "Subnet: %d\n", fastly.ToValue(a.Subnet)) 139 fmt.Fprintf(out, "Negated: %t\n", fastly.ToValue(a.Negated)) 140 fmt.Fprintf(out, "Comment: %s\n\n", fastly.ToValue(a.Comment)) 141 142 if a.CreatedAt != nil { 143 fmt.Fprintf(out, "Created at: %s\n", a.CreatedAt) 144 } 145 if a.UpdatedAt != nil { 146 fmt.Fprintf(out, "Updated at: %s\n", a.UpdatedAt) 147 } 148 if a.DeletedAt != nil { 149 fmt.Fprintf(out, "Deleted at: %s\n", a.DeletedAt) 150 } 151 152 fmt.Fprintf(out, "\n") 153 } 154 } 155 156 // printSummary displays the information returned from the API in a summarised 157 // format. 158 func (c *ListCommand) printSummary(out io.Writer, as []*fastly.ACLEntry) error { 159 t := text.NewTable(out) 160 t.AddHeader("SERVICE ID", "ID", "IP", "SUBNET", "NEGATED") 161 for _, a := range as { 162 var subnet int 163 if a.Subnet != nil { 164 subnet = *a.Subnet 165 } 166 t.AddLine( 167 fastly.ToValue(a.ServiceID), 168 fastly.ToValue(a.EntryID), 169 fastly.ToValue(a.IP), 170 subnet, 171 fastly.ToValue(a.Negated), 172 ) 173 } 174 t.Print() 175 return nil 176 }