github.com/fastly/cli@v1.7.2-0.20240304164155-9d0f1d77c3bf/pkg/commands/logging/ftp/create.go (about)

     1  package ftp
     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  	"github.com/fastly/cli/pkg/commands/logging/common"
    11  	"github.com/fastly/cli/pkg/errors"
    12  	"github.com/fastly/cli/pkg/global"
    13  	"github.com/fastly/cli/pkg/manifest"
    14  	"github.com/fastly/cli/pkg/text"
    15  )
    16  
    17  // CreateCommand calls the Fastly API to create an FTP logging endpoint.
    18  type CreateCommand struct {
    19  	argparser.Base
    20  	Manifest manifest.Data
    21  
    22  	// Required.
    23  	ServiceName    argparser.OptionalServiceNameID
    24  	ServiceVersion argparser.OptionalServiceVersion
    25  
    26  	// Optional.
    27  	Address           argparser.OptionalString
    28  	AutoClone         argparser.OptionalAutoClone
    29  	CompressionCodec  argparser.OptionalString
    30  	EndpointName      argparser.OptionalString // Can't shadow argparser.Base method Name().
    31  	Format            argparser.OptionalString
    32  	FormatVersion     argparser.OptionalInt
    33  	GzipLevel         argparser.OptionalInt
    34  	Password          argparser.OptionalString
    35  	Path              argparser.OptionalString
    36  	Period            argparser.OptionalInt
    37  	Placement         argparser.OptionalString
    38  	Port              argparser.OptionalInt
    39  	ResponseCondition argparser.OptionalString
    40  	TimestampFormat   argparser.OptionalString
    41  	Username          argparser.OptionalString
    42  }
    43  
    44  // NewCreateCommand returns a usable command registered under the parent.
    45  func NewCreateCommand(parent argparser.Registerer, g *global.Data) *CreateCommand {
    46  	c := CreateCommand{
    47  		Base: argparser.Base{
    48  			Globals: g,
    49  		},
    50  	}
    51  	c.CmdClause = parent.Command("create", "Create an FTP logging endpoint on a Fastly service version").Alias("add")
    52  
    53  	// Required.
    54  	c.RegisterFlag(argparser.StringFlagOpts{
    55  		Name:        argparser.FlagVersionName,
    56  		Description: argparser.FlagVersionDesc,
    57  		Dst:         &c.ServiceVersion.Value,
    58  		Required:    true,
    59  	})
    60  
    61  	// Optional.
    62  	c.RegisterAutoCloneFlag(argparser.AutoCloneFlagOpts{
    63  		Action: c.AutoClone.Set,
    64  		Dst:    &c.AutoClone.Value,
    65  	})
    66  	c.CmdClause.Flag("address", "An hostname or IPv4 address").Action(c.Address.Set).StringVar(&c.Address.Value)
    67  	common.CompressionCodec(c.CmdClause, &c.CompressionCodec)
    68  	c.CmdClause.Flag("name", "The name of the FTP logging object. Used as a primary key for API access").Short('n').Action(c.EndpointName.Set).StringVar(&c.EndpointName.Value)
    69  	common.Format(c.CmdClause, &c.Format)
    70  	common.FormatVersion(c.CmdClause, &c.FormatVersion)
    71  	common.GzipLevel(c.CmdClause, &c.GzipLevel)
    72  	c.CmdClause.Flag("password", "The password for the server (for anonymous use an email address)").Action(c.Password.Set).StringVar(&c.Password.Value)
    73  	c.CmdClause.Flag("path", "The path to upload log files to. If the path ends in / then it is treated as a directory").Action(c.Path.Set).StringVar(&c.Path.Value)
    74  	common.Period(c.CmdClause, &c.Period)
    75  	common.Placement(c.CmdClause, &c.Placement)
    76  	c.CmdClause.Flag("port", "The port number").Action(c.Port.Set).IntVar(&c.Port.Value)
    77  	common.ResponseCondition(c.CmdClause, &c.ResponseCondition)
    78  	common.TimestampFormat(c.CmdClause, &c.TimestampFormat)
    79  	c.RegisterFlag(argparser.StringFlagOpts{
    80  		Name:        argparser.FlagServiceIDName,
    81  		Description: argparser.FlagServiceIDDesc,
    82  		Dst:         &g.Manifest.Flag.ServiceID,
    83  		Short:       's',
    84  	})
    85  	c.RegisterFlag(argparser.StringFlagOpts{
    86  		Action:      c.ServiceName.Set,
    87  		Name:        argparser.FlagServiceName,
    88  		Description: argparser.FlagServiceDesc,
    89  		Dst:         &c.ServiceName.Value,
    90  	})
    91  	c.CmdClause.Flag("user", "The username for the server (can be anonymous)").Action(c.Username.Set).StringVar(&c.Username.Value)
    92  	return &c
    93  }
    94  
    95  // ConstructInput transforms values parsed from CLI flags into an object to be used by the API client library.
    96  func (c *CreateCommand) ConstructInput(serviceID string, serviceVersion int) (*fastly.CreateFTPInput, error) {
    97  	var input fastly.CreateFTPInput
    98  
    99  	input.ServiceID = serviceID
   100  	input.ServiceVersion = serviceVersion
   101  	if c.EndpointName.WasSet {
   102  		input.Name = &c.EndpointName.Value
   103  	}
   104  	if c.Address.WasSet {
   105  		input.Address = &c.Address.Value
   106  	}
   107  	if c.Username.WasSet {
   108  		input.Username = &c.Username.Value
   109  	}
   110  	if c.Password.WasSet {
   111  		input.Password = &c.Password.Value
   112  	}
   113  
   114  	// The following blocks enforces the mutual exclusivity of the
   115  	// CompressionCodec and GzipLevel flags.
   116  	if c.CompressionCodec.WasSet && c.GzipLevel.WasSet {
   117  		return nil, fmt.Errorf("error parsing arguments: the --compression-codec flag is mutually exclusive with the --gzip-level flag")
   118  	}
   119  
   120  	if c.Port.WasSet {
   121  		input.Port = &c.Port.Value
   122  	}
   123  
   124  	if c.Path.WasSet {
   125  		input.Path = &c.Path.Value
   126  	}
   127  
   128  	if c.Period.WasSet {
   129  		input.Period = &c.Period.Value
   130  	}
   131  
   132  	if c.Format.WasSet {
   133  		input.Format = &c.Format.Value
   134  	}
   135  
   136  	if c.FormatVersion.WasSet {
   137  		input.FormatVersion = &c.FormatVersion.Value
   138  	}
   139  
   140  	if c.GzipLevel.WasSet {
   141  		input.GzipLevel = &c.GzipLevel.Value
   142  	}
   143  
   144  	if c.ResponseCondition.WasSet {
   145  		input.ResponseCondition = &c.ResponseCondition.Value
   146  	}
   147  
   148  	if c.TimestampFormat.WasSet {
   149  		input.TimestampFormat = &c.TimestampFormat.Value
   150  	}
   151  
   152  	if c.Placement.WasSet {
   153  		input.Placement = &c.Placement.Value
   154  	}
   155  
   156  	if c.CompressionCodec.WasSet {
   157  		input.CompressionCodec = &c.CompressionCodec.Value
   158  	}
   159  
   160  	return &input, nil
   161  }
   162  
   163  // Exec invokes the application logic for the command.
   164  func (c *CreateCommand) Exec(_ io.Reader, out io.Writer) error {
   165  	serviceID, serviceVersion, err := argparser.ServiceDetails(argparser.ServiceDetailsOpts{
   166  		AutoCloneFlag:      c.AutoClone,
   167  		APIClient:          c.Globals.APIClient,
   168  		Manifest:           *c.Globals.Manifest,
   169  		Out:                out,
   170  		ServiceNameFlag:    c.ServiceName,
   171  		ServiceVersionFlag: c.ServiceVersion,
   172  		VerboseMode:        c.Globals.Flags.Verbose,
   173  	})
   174  	if err != nil {
   175  		c.Globals.ErrLog.AddWithContext(err, map[string]any{
   176  			"Service ID":      serviceID,
   177  			"Service Version": errors.ServiceVersion(serviceVersion),
   178  		})
   179  		return err
   180  	}
   181  
   182  	input, err := c.ConstructInput(serviceID, fastly.ToValue(serviceVersion.Number))
   183  	if err != nil {
   184  		c.Globals.ErrLog.Add(err)
   185  		return err
   186  	}
   187  
   188  	d, err := c.Globals.APIClient.CreateFTP(input)
   189  	if err != nil {
   190  		c.Globals.ErrLog.Add(err)
   191  		return err
   192  	}
   193  
   194  	text.Success(out,
   195  		"Created FTP logging endpoint %s (service %s version %d)",
   196  		fastly.ToValue(d.Name),
   197  		fastly.ToValue(d.ServiceID),
   198  		fastly.ToValue(d.ServiceVersion),
   199  	)
   200  	return nil
   201  }