github.com/fastly/cli@v1.7.2-0.20240304164155-9d0f1d77c3bf/pkg/commands/vcl/snippet/describe.go (about) 1 package snippet 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 ) 13 14 // NewDescribeCommand returns a usable command registered under the parent. 15 func NewDescribeCommand(parent argparser.Registerer, g *global.Data) *DescribeCommand { 16 c := DescribeCommand{ 17 Base: argparser.Base{ 18 Globals: g, 19 }, 20 } 21 c.CmdClause = parent.Command("describe", "Get the uploaded VCL snippet for a particular service and version").Alias("get") 22 23 // Required. 24 c.RegisterFlag(argparser.StringFlagOpts{ 25 Name: argparser.FlagVersionName, 26 Description: argparser.FlagVersionDesc, 27 Dst: &c.serviceVersion.Value, 28 Required: true, 29 }) 30 31 // Optional. 32 c.CmdClause.Flag("dynamic", "Whether the VCL snippet is dynamic or versioned").Action(c.dynamic.Set).BoolVar(&c.dynamic.Value) 33 c.RegisterFlagBool(c.JSONFlag()) // --json 34 c.CmdClause.Flag("name", "The name of the VCL snippet").StringVar(&c.name) 35 c.RegisterFlag(argparser.StringFlagOpts{ 36 Name: argparser.FlagServiceIDName, 37 Description: argparser.FlagServiceIDDesc, 38 Dst: &g.Manifest.Flag.ServiceID, 39 Short: 's', 40 }) 41 c.RegisterFlag(argparser.StringFlagOpts{ 42 Action: c.serviceName.Set, 43 Name: argparser.FlagServiceName, 44 Description: argparser.FlagServiceDesc, 45 Dst: &c.serviceName.Value, 46 }) 47 c.CmdClause.Flag("snippet-id", "Alphanumeric string identifying a VCL Snippet").StringVar(&c.snippetID) 48 49 return &c 50 } 51 52 // DescribeCommand calls the Fastly API to describe an appropriate resource. 53 type DescribeCommand struct { 54 argparser.Base 55 argparser.JSONOutput 56 57 dynamic argparser.OptionalBool 58 name string 59 serviceName argparser.OptionalServiceNameID 60 serviceVersion argparser.OptionalServiceVersion 61 snippetID string 62 } 63 64 // Exec invokes the application logic for the command. 65 func (c *DescribeCommand) Exec(_ io.Reader, out io.Writer) error { 66 if c.Globals.Verbose() && c.JSONOutput.Enabled { 67 return fsterr.ErrInvalidVerboseJSONCombo 68 } 69 70 serviceID, serviceVersion, err := argparser.ServiceDetails(argparser.ServiceDetailsOpts{ 71 AllowActiveLocked: true, 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 serviceVersionNumber := fastly.ToValue(serviceVersion.Number) 88 89 if c.dynamic.WasSet { 90 input, err := c.constructDynamicInput(serviceID, serviceVersionNumber) 91 if err != nil { 92 c.Globals.ErrLog.AddWithContext(err, map[string]any{ 93 "Service ID": serviceID, 94 "Service Version": serviceVersionNumber, 95 }) 96 return err 97 } 98 99 o, err := c.Globals.APIClient.GetDynamicSnippet(input) 100 if err != nil { 101 c.Globals.ErrLog.AddWithContext(err, map[string]any{ 102 "Service ID": serviceID, 103 "Service Version": serviceVersionNumber, 104 }) 105 return err 106 } 107 108 if ok, err := c.WriteJSON(out, o); ok { 109 return err 110 } 111 112 return c.printDynamic(out, o) 113 } 114 115 input, err := c.constructInput(serviceID, serviceVersionNumber) 116 if err != nil { 117 c.Globals.ErrLog.AddWithContext(err, map[string]any{ 118 "Service ID": serviceID, 119 "Service Version": serviceVersionNumber, 120 }) 121 return err 122 } 123 124 o, err := c.Globals.APIClient.GetSnippet(input) 125 if err != nil { 126 c.Globals.ErrLog.AddWithContext(err, map[string]any{ 127 "Service ID": serviceID, 128 "Service Version": serviceVersionNumber, 129 }) 130 return err 131 } 132 133 if ok, err := c.WriteJSON(out, o); ok { 134 return err 135 } 136 137 return c.print(out, o) 138 } 139 140 // constructDynamicInput transforms values parsed from CLI flags into an object to be used by the API client library. 141 func (c *DescribeCommand) constructDynamicInput(serviceID string, _ int) (*fastly.GetDynamicSnippetInput, error) { 142 var input fastly.GetDynamicSnippetInput 143 144 input.SnippetID = c.snippetID 145 input.ServiceID = serviceID 146 147 if c.snippetID == "" { 148 return nil, fmt.Errorf("error parsing arguments: must provide --snippet-id with a dynamic VCL snippet") 149 } 150 151 return &input, nil 152 } 153 154 // constructInput transforms values parsed from CLI flags into an object to be used by the API client library. 155 func (c *DescribeCommand) constructInput(serviceID string, serviceVersion int) (*fastly.GetSnippetInput, error) { 156 var input fastly.GetSnippetInput 157 158 input.Name = c.name 159 input.ServiceID = serviceID 160 input.ServiceVersion = serviceVersion 161 162 if c.name == "" { 163 return nil, fmt.Errorf("error parsing arguments: must provide --name with a versioned VCL snippet") 164 } 165 166 return &input, nil 167 } 168 169 // print displays the 'dynamic' information returned from the API. 170 func (c *DescribeCommand) printDynamic(out io.Writer, ds *fastly.DynamicSnippet) error { 171 fmt.Fprintf(out, "\nService ID: %s\n", fastly.ToValue(ds.ServiceID)) 172 fmt.Fprintf(out, "ID: %s\n", fastly.ToValue(ds.SnippetID)) 173 fmt.Fprintf(out, "Content: \n%s\n", fastly.ToValue(ds.Content)) 174 if ds.CreatedAt != nil { 175 fmt.Fprintf(out, "Created at: %s\n", ds.CreatedAt) 176 } 177 if ds.UpdatedAt != nil { 178 fmt.Fprintf(out, "Updated at: %s\n", ds.UpdatedAt) 179 } 180 return nil 181 } 182 183 // print displays the information returned from the API. 184 func (c *DescribeCommand) print(out io.Writer, s *fastly.Snippet) error { 185 if !c.Globals.Verbose() { 186 fmt.Fprintf(out, "\nService ID: %s\n", fastly.ToValue(s.ServiceID)) 187 } 188 fmt.Fprintf(out, "Service Version: %d\n", fastly.ToValue(s.ServiceVersion)) 189 fmt.Fprintf(out, "\nName: %s\n", fastly.ToValue(s.Name)) 190 fmt.Fprintf(out, "ID: %s\n", fastly.ToValue(s.SnippetID)) 191 fmt.Fprintf(out, "Priority: %d\n", fastly.ToValue(s.Priority)) 192 fmt.Fprintf(out, "Dynamic: %t\n", argparser.IntToBool(fastly.ToValue(s.Dynamic))) 193 fmt.Fprintf(out, "Type: %s\n", fastly.ToValue(s.Type)) 194 fmt.Fprintf(out, "Content: \n%s\n", fastly.ToValue(s.Content)) 195 if s.CreatedAt != nil { 196 fmt.Fprintf(out, "Created at: %s\n", s.CreatedAt) 197 } 198 if s.UpdatedAt != nil { 199 fmt.Fprintf(out, "Updated at: %s\n", s.UpdatedAt) 200 } 201 if s.DeletedAt != nil { 202 fmt.Fprintf(out, "Deleted at: %s\n", s.DeletedAt) 203 } 204 return nil 205 }