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

     1  package kafka
     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  // UpdateCommand calls the Fastly API to update a Kafka logging endpoint.
    18  type UpdateCommand struct {
    19  	argparser.Base
    20  	Manifest manifest.Data
    21  
    22  	// Required.
    23  	EndpointName   string // Can't shadow argparser.Base method Name().
    24  	ServiceName    argparser.OptionalServiceNameID
    25  	ServiceVersion argparser.OptionalServiceVersion
    26  
    27  	// Optional.
    28  	AutoClone         argparser.OptionalAutoClone
    29  	NewName           argparser.OptionalString
    30  	Index             argparser.OptionalString
    31  	Topic             argparser.OptionalString
    32  	Brokers           argparser.OptionalString
    33  	UseTLS            argparser.OptionalBool
    34  	CompressionCodec  argparser.OptionalString
    35  	RequiredACKs      argparser.OptionalString
    36  	TLSCACert         argparser.OptionalString
    37  	TLSClientCert     argparser.OptionalString
    38  	TLSClientKey      argparser.OptionalString
    39  	TLSHostname       argparser.OptionalString
    40  	Format            argparser.OptionalString
    41  	FormatVersion     argparser.OptionalInt
    42  	Placement         argparser.OptionalString
    43  	ResponseCondition argparser.OptionalString
    44  	ParseLogKeyvals   argparser.OptionalBool
    45  	RequestMaxBytes   argparser.OptionalInt
    46  	UseSASL           argparser.OptionalBool
    47  	AuthMethod        argparser.OptionalString
    48  	User              argparser.OptionalString
    49  	Password          argparser.OptionalString
    50  }
    51  
    52  // NewUpdateCommand returns a usable command registered under the parent.
    53  func NewUpdateCommand(parent argparser.Registerer, g *global.Data) *UpdateCommand {
    54  	c := UpdateCommand{
    55  		Base: argparser.Base{
    56  			Globals: g,
    57  		},
    58  	}
    59  	c.CmdClause = parent.Command("update", "Update a Kafka logging endpoint on a Fastly service version")
    60  
    61  	// Required.
    62  	c.CmdClause.Flag("name", "The name of the Kafka logging object").Short('n').Required().StringVar(&c.EndpointName)
    63  	c.RegisterFlag(argparser.StringFlagOpts{
    64  		Name:        argparser.FlagVersionName,
    65  		Description: argparser.FlagVersionDesc,
    66  		Dst:         &c.ServiceVersion.Value,
    67  		Required:    true,
    68  	})
    69  
    70  	// Optional.
    71  	c.RegisterAutoCloneFlag(argparser.AutoCloneFlagOpts{
    72  		Action: c.AutoClone.Set,
    73  		Dst:    &c.AutoClone.Value,
    74  	})
    75  	c.CmdClause.Flag("auth-method", "SASL authentication method. Valid values are: plain, scram-sha-256, scram-sha-512").Action(c.AuthMethod.Set).HintOptions("plain", "scram-sha-256", "scram-sha-512").EnumVar(&c.AuthMethod.Value, "plain", "scram-sha-256", "scram-sha-512")
    76  	c.CmdClause.Flag("brokers", "A comma-separated list of IP addresses or hostnames of Kafka brokers").Action(c.Brokers.Set).StringVar(&c.Brokers.Value)
    77  	c.CmdClause.Flag("compression-codec", "The codec used for compression of your logs. One of: gzip, snappy, lz4").Action(c.CompressionCodec.Set).StringVar(&c.CompressionCodec.Value)
    78  	common.Format(c.CmdClause, &c.Format)
    79  	common.FormatVersion(c.CmdClause, &c.FormatVersion)
    80  	c.CmdClause.Flag("max-batch-size", "The maximum size of the log batch in bytes").Action(c.RequestMaxBytes.Set).IntVar(&c.RequestMaxBytes.Value)
    81  	c.CmdClause.Flag("new-name", "New name of the Kafka logging object").Action(c.NewName.Set).StringVar(&c.NewName.Value)
    82  	c.CmdClause.Flag("parse-log-keyvals", "Parse key-value pairs within the log format").Action(c.ParseLogKeyvals.Set).NegatableBoolVar(&c.ParseLogKeyvals.Value)
    83  	c.CmdClause.Flag("password", "SASL authentication password. Required if --auth-method is specified").Action(c.Password.Set).StringVar(&c.Password.Value)
    84  	common.Placement(c.CmdClause, &c.Placement)
    85  	c.CmdClause.Flag("required-acks", "The Number of acknowledgements a leader must receive before a write is considered successful. One of: 1 (default) One server needs to respond. 0	No servers need to respond. -1	Wait for all in-sync replicas to respond").Action(c.RequiredACKs.Set).StringVar(&c.RequiredACKs.Value)
    86  	common.ResponseCondition(c.CmdClause, &c.ResponseCondition)
    87  	c.RegisterFlag(argparser.StringFlagOpts{
    88  		Name:        argparser.FlagServiceIDName,
    89  		Description: argparser.FlagServiceIDDesc,
    90  		Dst:         &g.Manifest.Flag.ServiceID,
    91  		Short:       's',
    92  	})
    93  	c.RegisterFlag(argparser.StringFlagOpts{
    94  		Action:      c.ServiceName.Set,
    95  		Name:        argparser.FlagServiceName,
    96  		Description: argparser.FlagServiceDesc,
    97  		Dst:         &c.ServiceName.Value,
    98  	})
    99  	common.TLSCACert(c.CmdClause, &c.TLSCACert)
   100  	common.TLSClientCert(c.CmdClause, &c.TLSClientCert)
   101  	common.TLSClientKey(c.CmdClause, &c.TLSClientKey)
   102  	common.TLSHostname(c.CmdClause, &c.TLSHostname)
   103  	c.CmdClause.Flag("topic", "The Kafka topic to send logs to").Action(c.Topic.Set).StringVar(&c.Topic.Value)
   104  	c.CmdClause.Flag("use-sasl", "Enable SASL authentication. Requires --auth-method, --username, and --password to be specified").Action(c.UseSASL.Set).BoolVar(&c.UseSASL.Value)
   105  	c.CmdClause.Flag("use-tls", "Whether to use TLS for secure logging. Can be either true or false").Action(c.UseTLS.Set).BoolVar(&c.UseTLS.Value)
   106  	c.CmdClause.Flag("username", "SASL authentication username. Required if --auth-method is specified").Action(c.User.Set).StringVar(&c.User.Value)
   107  	return &c
   108  }
   109  
   110  // ConstructInput transforms values parsed from CLI flags into an object to be used by the API client library.
   111  func (c *UpdateCommand) ConstructInput(serviceID string, serviceVersion int) (*fastly.UpdateKafkaInput, error) {
   112  	if c.UseSASL.WasSet && c.UseSASL.Value && (c.AuthMethod.Value == "" || c.User.Value == "" || c.Password.Value == "") {
   113  		return nil, fmt.Errorf("the --auth-method, --username, and --password flags must be present when using the --use-sasl flag")
   114  	}
   115  
   116  	if !c.UseSASL.Value && (c.AuthMethod.Value != "" || c.User.Value != "" || c.Password.Value != "") {
   117  		return nil, fmt.Errorf("the --auth-method, --username, and --password options are only valid when the --use-sasl flag is specified")
   118  	}
   119  
   120  	input := fastly.UpdateKafkaInput{
   121  		ServiceID:      serviceID,
   122  		ServiceVersion: serviceVersion,
   123  		Name:           c.EndpointName,
   124  	}
   125  
   126  	if c.NewName.WasSet {
   127  		input.NewName = &c.NewName.Value
   128  	}
   129  
   130  	if c.Topic.WasSet {
   131  		input.Topic = &c.Topic.Value
   132  	}
   133  
   134  	if c.Brokers.WasSet {
   135  		input.Brokers = &c.Brokers.Value
   136  	}
   137  
   138  	if c.CompressionCodec.WasSet {
   139  		input.CompressionCodec = &c.CompressionCodec.Value
   140  	}
   141  
   142  	if c.RequiredACKs.WasSet {
   143  		input.RequiredACKs = &c.RequiredACKs.Value
   144  	}
   145  
   146  	if c.UseTLS.WasSet {
   147  		input.UseTLS = fastly.ToPointer(fastly.Compatibool(c.UseTLS.Value))
   148  	}
   149  
   150  	if c.TLSCACert.WasSet {
   151  		input.TLSCACert = &c.TLSCACert.Value
   152  	}
   153  
   154  	if c.TLSClientCert.WasSet {
   155  		input.TLSClientCert = &c.TLSClientCert.Value
   156  	}
   157  
   158  	if c.TLSClientKey.WasSet {
   159  		input.TLSClientKey = &c.TLSClientKey.Value
   160  	}
   161  
   162  	if c.TLSHostname.WasSet {
   163  		input.TLSHostname = &c.TLSHostname.Value
   164  	}
   165  
   166  	if c.Format.WasSet {
   167  		input.Format = &c.Format.Value
   168  	}
   169  
   170  	if c.FormatVersion.WasSet {
   171  		input.FormatVersion = &c.FormatVersion.Value
   172  	}
   173  
   174  	if c.ResponseCondition.WasSet {
   175  		input.ResponseCondition = &c.ResponseCondition.Value
   176  	}
   177  
   178  	if c.Placement.WasSet {
   179  		input.Placement = &c.Placement.Value
   180  	}
   181  
   182  	if c.ParseLogKeyvals.WasSet {
   183  		input.ParseLogKeyvals = fastly.ToPointer(fastly.Compatibool(c.ParseLogKeyvals.Value))
   184  	}
   185  
   186  	if c.RequestMaxBytes.WasSet {
   187  		input.RequestMaxBytes = &c.RequestMaxBytes.Value
   188  	}
   189  
   190  	if c.UseSASL.WasSet && !c.UseSASL.Value {
   191  		input.AuthMethod = fastly.ToPointer("")
   192  		input.User = fastly.ToPointer("")
   193  		input.Password = fastly.ToPointer("")
   194  	}
   195  
   196  	if c.AuthMethod.WasSet {
   197  		input.AuthMethod = &c.AuthMethod.Value
   198  	}
   199  
   200  	if c.User.WasSet {
   201  		input.User = &c.User.Value
   202  	}
   203  
   204  	if c.Password.WasSet {
   205  		input.Password = &c.Password.Value
   206  	}
   207  
   208  	return &input, nil
   209  }
   210  
   211  // Exec invokes the application logic for the command.
   212  func (c *UpdateCommand) Exec(_ io.Reader, out io.Writer) error {
   213  	serviceID, serviceVersion, err := argparser.ServiceDetails(argparser.ServiceDetailsOpts{
   214  		AutoCloneFlag:      c.AutoClone,
   215  		APIClient:          c.Globals.APIClient,
   216  		Manifest:           *c.Globals.Manifest,
   217  		Out:                out,
   218  		ServiceNameFlag:    c.ServiceName,
   219  		ServiceVersionFlag: c.ServiceVersion,
   220  		VerboseMode:        c.Globals.Flags.Verbose,
   221  	})
   222  	if err != nil {
   223  		c.Globals.ErrLog.AddWithContext(err, map[string]any{
   224  			"Service ID":      serviceID,
   225  			"Service Version": errors.ServiceVersion(serviceVersion),
   226  		})
   227  		return err
   228  	}
   229  
   230  	input, err := c.ConstructInput(serviceID, fastly.ToValue(serviceVersion.Number))
   231  	if err != nil {
   232  		c.Globals.ErrLog.Add(err)
   233  		return err
   234  	}
   235  
   236  	kafka, err := c.Globals.APIClient.UpdateKafka(input)
   237  	if err != nil {
   238  		c.Globals.ErrLog.Add(err)
   239  		return err
   240  	}
   241  
   242  	text.Success(out,
   243  		"Updated Kafka logging endpoint %s (service %s version %d)",
   244  		fastly.ToValue(kafka.Name),
   245  		fastly.ToValue(kafka.ServiceID),
   246  		fastly.ToValue(kafka.ServiceVersion),
   247  	)
   248  	return nil
   249  }