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 }