github.com/fastly/cli@v1.7.2-0.20240304164155-9d0f1d77c3bf/pkg/commands/vcl/custom/update.go (about) 1 package custom 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 // NewUpdateCommand returns a usable command registered under the parent. 16 func NewUpdateCommand(parent argparser.Registerer, g *global.Data) *UpdateCommand { 17 c := UpdateCommand{ 18 Base: argparser.Base{ 19 Globals: g, 20 }, 21 } 22 c.CmdClause = parent.Command("update", "Update the uploaded VCL for a particular service and version") 23 24 // Required. 25 c.CmdClause.Flag("name", "The name of the VCL to update").Required().StringVar(&c.name) 26 c.RegisterFlag(argparser.StringFlagOpts{ 27 Name: argparser.FlagVersionName, 28 Description: argparser.FlagVersionDesc, 29 Dst: &c.serviceVersion.Value, 30 Required: true, 31 }) 32 33 // Optional. 34 c.RegisterAutoCloneFlag(argparser.AutoCloneFlagOpts{ 35 Action: c.autoClone.Set, 36 Dst: &c.autoClone.Value, 37 }) 38 c.CmdClause.Flag("new-name", "New name for the VCL").Action(c.newName.Set).StringVar(&c.newName.Value) 39 c.CmdClause.Flag("content", "VCL passed as file path or content, e.g. $(< main.vcl)").Action(c.content.Set).StringVar(&c.content.Value) 40 c.RegisterFlag(argparser.StringFlagOpts{ 41 Name: argparser.FlagServiceIDName, 42 Description: argparser.FlagServiceIDDesc, 43 Dst: &g.Manifest.Flag.ServiceID, 44 Short: 's', 45 }) 46 c.RegisterFlag(argparser.StringFlagOpts{ 47 Action: c.serviceName.Set, 48 Name: argparser.FlagServiceName, 49 Description: argparser.FlagServiceDesc, 50 Dst: &c.serviceName.Value, 51 }) 52 53 return &c 54 } 55 56 // UpdateCommand calls the Fastly API to update an appropriate resource. 57 type UpdateCommand struct { 58 argparser.Base 59 60 autoClone argparser.OptionalAutoClone 61 content argparser.OptionalString 62 name string 63 newName argparser.OptionalString 64 serviceName argparser.OptionalServiceNameID 65 serviceVersion argparser.OptionalServiceVersion 66 } 67 68 // Exec invokes the application logic for the command. 69 func (c *UpdateCommand) Exec(_ io.Reader, out io.Writer) error { 70 serviceID, serviceVersion, err := argparser.ServiceDetails(argparser.ServiceDetailsOpts{ 71 AutoCloneFlag: c.autoClone, 72 APIClient: c.Globals.APIClient, 73 Manifest: *c.Globals.Manifest, 74 Out: out, 75 ServiceNameFlag: c.serviceName, 76 ServiceVersionFlag: c.serviceVersion, 77 VerboseMode: c.Globals.Flags.Verbose, 78 }) 79 if err != nil { 80 c.Globals.ErrLog.AddWithContext(err, map[string]any{ 81 "Service ID": serviceID, 82 "Service Version": fsterr.ServiceVersion(serviceVersion), 83 }) 84 return err 85 } 86 87 input, err := c.constructInput(serviceID, fastly.ToValue(serviceVersion.Number)) 88 if err != nil { 89 c.Globals.ErrLog.AddWithContext(err, map[string]any{ 90 "Service ID": serviceID, 91 "Service Version": fastly.ToValue(serviceVersion.Number), 92 }) 93 return err 94 } 95 96 v, err := c.Globals.APIClient.UpdateVCL(input) 97 if err != nil { 98 c.Globals.ErrLog.AddWithContext(err, map[string]any{ 99 "Service ID": serviceID, 100 "Service Version": fastly.ToValue(serviceVersion.Number), 101 }) 102 return err 103 } 104 105 if input.NewName != nil && *input.NewName != "" { 106 text.Success(out, 107 "Updated custom VCL '%s' (previously: '%s', service: %s, version: %d)", 108 fastly.ToValue(v.Name), 109 input.Name, 110 fastly.ToValue(v.ServiceID), 111 fastly.ToValue(v.ServiceVersion), 112 ) 113 } else { 114 text.Success(out, 115 "Updated custom VCL '%s' (service: %s, version: %d)", 116 fastly.ToValue(v.Name), 117 fastly.ToValue(v.ServiceID), 118 fastly.ToValue(v.ServiceVersion), 119 ) 120 } 121 return nil 122 } 123 124 // constructInput transforms values parsed from CLI flags into an object to be used by the API client library. 125 func (c *UpdateCommand) constructInput(serviceID string, serviceVersion int) (*fastly.UpdateVCLInput, error) { 126 var input fastly.UpdateVCLInput 127 128 input.Name = c.name 129 input.ServiceID = serviceID 130 input.ServiceVersion = serviceVersion 131 132 if !c.newName.WasSet && !c.content.WasSet { 133 return nil, fmt.Errorf("error parsing arguments: must provide either --new-name or --content to update the VCL") 134 } 135 if c.newName.WasSet { 136 input.NewName = &c.newName.Value 137 } 138 if c.content.WasSet { 139 input.Content = fastly.ToPointer(argparser.Content(c.content.Value)) 140 } 141 142 return &input, nil 143 }