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  }