github.com/fastly/cli@v1.7.2-0.20240304164155-9d0f1d77c3bf/pkg/commands/logging/kafka/create.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 // CreateCommand calls the Fastly API to create a Kafka 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 AuthMethod argparser.OptionalString 28 AutoClone argparser.OptionalAutoClone 29 Brokers argparser.OptionalString 30 CompressionCodec argparser.OptionalString 31 EndpointName argparser.OptionalString // Can't shadow argparser.Base method Name(). 32 Format argparser.OptionalString 33 FormatVersion argparser.OptionalInt 34 ParseLogKeyvals argparser.OptionalBool 35 Password argparser.OptionalString 36 Placement argparser.OptionalString 37 RequestMaxBytes argparser.OptionalInt 38 RequiredACKs argparser.OptionalString 39 ResponseCondition argparser.OptionalString 40 TLSCACert argparser.OptionalString 41 TLSClientCert argparser.OptionalString 42 TLSClientKey argparser.OptionalString 43 TLSHostname argparser.OptionalString 44 Topic argparser.OptionalString 45 User argparser.OptionalString 46 UseSASL argparser.OptionalBool 47 UseTLS argparser.OptionalBool 48 } 49 50 // NewCreateCommand returns a usable command registered under the parent. 51 func NewCreateCommand(parent argparser.Registerer, g *global.Data) *CreateCommand { 52 c := CreateCommand{ 53 Base: argparser.Base{ 54 Globals: g, 55 }, 56 } 57 c.CmdClause = parent.Command("create", "Create a Kafka logging endpoint on a Fastly service version").Alias("add") 58 59 // Required. 60 c.CmdClause.Flag("name", "The name of the Kafka logging object. Used as a primary key for API access").Short('n').Action(c.EndpointName.Set).StringVar(&c.EndpointName.Value) 61 c.RegisterFlag(argparser.StringFlagOpts{ 62 Name: argparser.FlagVersionName, 63 Description: argparser.FlagVersionDesc, 64 Dst: &c.ServiceVersion.Value, 65 Required: true, 66 }) 67 68 // Optional. 69 c.RegisterAutoCloneFlag(argparser.AutoCloneFlagOpts{ 70 Action: c.AutoClone.Set, 71 Dst: &c.AutoClone.Value, 72 }) 73 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") 74 c.CmdClause.Flag("brokers", "A comma-separated list of IP addresses or hostnames of Kafka brokers").Action(c.Brokers.Set).StringVar(&c.Brokers.Value) 75 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) 76 common.Format(c.CmdClause, &c.Format) 77 common.FormatVersion(c.CmdClause, &c.FormatVersion) 78 c.CmdClause.Flag("max-batch-size", "The maximum size of the log batch in bytes").Action(c.RequestMaxBytes.Set).IntVar(&c.RequestMaxBytes.Value) 79 c.CmdClause.Flag("parse-log-keyvals", "Parse key-value pairs within the log format").Action(c.ParseLogKeyvals.Set).BoolVar(&c.ParseLogKeyvals.Value) 80 c.CmdClause.Flag("password", "SASL authentication password. Required if --auth-method is specified").Action(c.Password.Set).StringVar(&c.Password.Value) 81 common.Placement(c.CmdClause, &c.Placement) 82 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) 83 common.ResponseCondition(c.CmdClause, &c.ResponseCondition) 84 c.RegisterFlag(argparser.StringFlagOpts{ 85 Name: argparser.FlagServiceIDName, 86 Description: argparser.FlagServiceIDDesc, 87 Dst: &g.Manifest.Flag.ServiceID, 88 Short: 's', 89 }) 90 c.RegisterFlag(argparser.StringFlagOpts{ 91 Action: c.ServiceName.Set, 92 Name: argparser.FlagServiceName, 93 Description: argparser.FlagServiceDesc, 94 Dst: &c.ServiceName.Value, 95 }) 96 common.TLSCACert(c.CmdClause, &c.TLSCACert) 97 common.TLSClientCert(c.CmdClause, &c.TLSClientCert) 98 common.TLSClientKey(c.CmdClause, &c.TLSClientKey) 99 common.TLSHostname(c.CmdClause, &c.TLSHostname) 100 c.CmdClause.Flag("topic", "The Kafka topic to send logs to").Action(c.Topic.Set).StringVar(&c.Topic.Value) 101 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) 102 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) 103 c.CmdClause.Flag("username", "SASL authentication username. Required if --auth-method is specified").Action(c.User.Set).StringVar(&c.User.Value) 104 return &c 105 } 106 107 // ConstructInput transforms values parsed from CLI flags into an object to be used by the API client library. 108 func (c *CreateCommand) ConstructInput(serviceID string, serviceVersion int) (*fastly.CreateKafkaInput, error) { 109 var input fastly.CreateKafkaInput 110 111 if c.UseSASL.WasSet && c.UseSASL.Value && (c.AuthMethod.Value == "" || c.User.Value == "" || c.Password.Value == "") { 112 return nil, fmt.Errorf("the --auth-method, --username, and --password flags must be present when using the --use-sasl flag") 113 } 114 115 if !c.UseSASL.Value && (c.AuthMethod.Value != "" || c.User.Value != "" || c.Password.Value != "") { 116 return nil, fmt.Errorf("the --auth-method, --username, and --password options are only valid when the --use-sasl flag is specified") 117 } 118 119 input.ServiceID = serviceID 120 input.ServiceVersion = serviceVersion 121 if c.EndpointName.WasSet { 122 input.Name = &c.EndpointName.Value 123 } 124 if c.Topic.WasSet { 125 input.Topic = &c.Topic.Value 126 } 127 if c.Brokers.WasSet { 128 input.Brokers = &c.Brokers.Value 129 } 130 131 if c.CompressionCodec.WasSet { 132 input.CompressionCodec = &c.CompressionCodec.Value 133 } 134 135 if c.RequiredACKs.WasSet { 136 input.RequiredACKs = &c.RequiredACKs.Value 137 } 138 139 if c.UseTLS.WasSet { 140 input.UseTLS = fastly.ToPointer(fastly.Compatibool(c.UseTLS.Value)) 141 } 142 143 if c.TLSCACert.WasSet { 144 input.TLSCACert = &c.TLSCACert.Value 145 } 146 147 if c.TLSClientCert.WasSet { 148 input.TLSClientCert = &c.TLSClientCert.Value 149 } 150 151 if c.TLSClientKey.WasSet { 152 input.TLSClientKey = &c.TLSClientKey.Value 153 } 154 155 if c.TLSHostname.WasSet { 156 input.TLSHostname = &c.TLSHostname.Value 157 } 158 159 if c.Format.WasSet { 160 input.Format = &c.Format.Value 161 } 162 163 if c.FormatVersion.WasSet { 164 input.FormatVersion = &c.FormatVersion.Value 165 } 166 167 if c.ResponseCondition.WasSet { 168 input.ResponseCondition = &c.ResponseCondition.Value 169 } 170 171 if c.Placement.WasSet { 172 input.Placement = &c.Placement.Value 173 } 174 175 if c.ParseLogKeyvals.WasSet { 176 input.ParseLogKeyvals = fastly.ToPointer(fastly.Compatibool(c.ParseLogKeyvals.Value)) 177 } 178 179 if c.RequestMaxBytes.WasSet { 180 input.RequestMaxBytes = &c.RequestMaxBytes.Value 181 } 182 183 if c.AuthMethod.WasSet { 184 input.AuthMethod = &c.AuthMethod.Value 185 } 186 187 if c.User.WasSet { 188 input.User = &c.User.Value 189 } 190 191 if c.Password.WasSet { 192 input.Password = &c.Password.Value 193 } 194 195 return &input, nil 196 } 197 198 // Exec invokes the application logic for the command. 199 func (c *CreateCommand) Exec(_ io.Reader, out io.Writer) error { 200 serviceID, serviceVersion, err := argparser.ServiceDetails(argparser.ServiceDetailsOpts{ 201 AutoCloneFlag: c.AutoClone, 202 APIClient: c.Globals.APIClient, 203 Manifest: *c.Globals.Manifest, 204 Out: out, 205 ServiceNameFlag: c.ServiceName, 206 ServiceVersionFlag: c.ServiceVersion, 207 VerboseMode: c.Globals.Flags.Verbose, 208 }) 209 if err != nil { 210 c.Globals.ErrLog.AddWithContext(err, map[string]any{ 211 "Service ID": serviceID, 212 "Service Version": errors.ServiceVersion(serviceVersion), 213 }) 214 return err 215 } 216 217 input, err := c.ConstructInput(serviceID, fastly.ToValue(serviceVersion.Number)) 218 if err != nil { 219 c.Globals.ErrLog.Add(err) 220 return err 221 } 222 223 d, err := c.Globals.APIClient.CreateKafka(input) 224 if err != nil { 225 c.Globals.ErrLog.Add(err) 226 return err 227 } 228 229 text.Success(out, 230 "Created Kafka logging endpoint %s (service %s version %d)", 231 fastly.ToValue(d.Name), 232 fastly.ToValue(d.ServiceID), 233 fastly.ToValue(d.ServiceVersion), 234 ) 235 return nil 236 }