github.com/fastly/cli@v1.7.2-0.20240304164155-9d0f1d77c3bf/pkg/commands/domain/validate.go (about) 1 package domain 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/errors" 11 "github.com/fastly/cli/pkg/global" 12 ) 13 14 // NewValidateCommand returns a usable command registered under the parent. 15 func NewValidateCommand(parent argparser.Registerer, g *global.Data) *ValidateCommand { 16 var c ValidateCommand 17 c.CmdClause = parent.Command("validate", "Checks the status of a specific domain's DNS record for a Service Version") 18 c.Globals = g 19 20 // Required. 21 c.RegisterFlag(argparser.StringFlagOpts{ 22 Name: argparser.FlagVersionName, 23 Description: argparser.FlagVersionDesc, 24 Dst: &c.serviceVersion.Value, 25 Required: true, 26 }) 27 28 // Optional. 29 c.CmdClause.Flag("all", "Checks the status of all domains' DNS records for a Service Version").Short('a').BoolVar(&c.all) 30 c.CmdClause.Flag("name", "The name of the domain associated with this service").Short('n').Action(c.name.Set).StringVar(&c.name.Value) 31 c.RegisterFlag(argparser.StringFlagOpts{ 32 Name: argparser.FlagServiceIDName, 33 Description: argparser.FlagServiceIDDesc, 34 Dst: &g.Manifest.Flag.ServiceID, 35 Short: 's', 36 }) 37 c.RegisterFlag(argparser.StringFlagOpts{ 38 Action: c.serviceName.Set, 39 Name: argparser.FlagServiceName, 40 Description: argparser.FlagServiceDesc, 41 Dst: &c.serviceName.Value, 42 }) 43 44 return &c 45 } 46 47 // ValidateCommand calls the Fastly API to describe an appropriate resource. 48 type ValidateCommand struct { 49 argparser.Base 50 51 all bool 52 name argparser.OptionalString 53 serviceName argparser.OptionalServiceNameID 54 serviceVersion argparser.OptionalServiceVersion 55 } 56 57 // Exec invokes the application logic for the command. 58 func (c *ValidateCommand) Exec(_ io.Reader, out io.Writer) error { 59 serviceID, serviceVersion, err := argparser.ServiceDetails(argparser.ServiceDetailsOpts{ 60 AllowActiveLocked: true, 61 APIClient: c.Globals.APIClient, 62 Manifest: *c.Globals.Manifest, 63 Out: out, 64 ServiceNameFlag: c.serviceName, 65 ServiceVersionFlag: c.serviceVersion, 66 VerboseMode: c.Globals.Flags.Verbose, 67 }) 68 if err != nil { 69 c.Globals.ErrLog.AddWithContext(err, map[string]any{ 70 "Service ID": serviceID, 71 "Service Version": errors.ServiceVersion(serviceVersion), 72 }) 73 return err 74 } 75 76 serviceVersionNumber := fastly.ToValue(serviceVersion.Number) 77 78 if c.all { 79 input := c.constructInputAll(serviceID, serviceVersionNumber) 80 81 r, err := c.Globals.APIClient.ValidateAllDomains(input) 82 if err != nil { 83 c.Globals.ErrLog.AddWithContext(err, map[string]any{ 84 "Service ID": serviceID, 85 "Service Version": serviceVersionNumber, 86 }) 87 return err 88 } 89 90 c.printAll(out, r) 91 return nil 92 } 93 94 input, err := c.constructInput(serviceID, serviceVersionNumber) 95 if err != nil { 96 return err 97 } 98 99 r, err := c.Globals.APIClient.ValidateDomain(input) 100 if err != nil { 101 c.Globals.ErrLog.AddWithContext(err, map[string]any{ 102 "Service ID": serviceID, 103 "Service Version": serviceVersionNumber, 104 "Domain Name": c.name, 105 }) 106 return err 107 } 108 109 c.print(out, r) 110 return nil 111 } 112 113 // constructInput transforms values parsed from CLI flags into an object to be used by the API client library. 114 func (c *ValidateCommand) constructInput(serviceID string, serviceVersion int) (*fastly.ValidateDomainInput, error) { 115 var input fastly.ValidateDomainInput 116 117 input.ServiceID = serviceID 118 input.ServiceVersion = serviceVersion 119 120 if !c.name.WasSet { 121 return nil, errors.RemediationError{ 122 Inner: fmt.Errorf("error parsing arguments: must provide --name flag"), 123 Remediation: "Alternatively pass --all to validate all domains.", 124 } 125 } 126 input.Name = c.name.Value 127 128 return &input, nil 129 } 130 131 // print displays the information returned from the API. 132 func (c *ValidateCommand) print(out io.Writer, r *fastly.DomainValidationResult) { 133 fmt.Fprintf(out, "\nService ID: %s\n", fastly.ToValue(r.Metadata.ServiceID)) 134 fmt.Fprintf(out, "Service Version: %d\n\n", fastly.ToValue(r.Metadata.ServiceVersion)) 135 fmt.Fprintf(out, "Name: %s\n", fastly.ToValue(r.Metadata.Name)) 136 fmt.Fprintf(out, "Valid: %t\n", fastly.ToValue(r.Valid)) 137 138 if r.CName != nil { 139 fmt.Fprintf(out, "CNAME: %s\n", *r.CName) 140 } 141 if r.Metadata.CreatedAt != nil { 142 fmt.Fprintf(out, "Created at: %s\n", r.Metadata.CreatedAt) 143 } 144 if r.Metadata.UpdatedAt != nil { 145 fmt.Fprintf(out, "Updated at: %s\n", r.Metadata.UpdatedAt) 146 } 147 if r.Metadata.DeletedAt != nil { 148 fmt.Fprintf(out, "Deleted at: %s\n", r.Metadata.DeletedAt) 149 } 150 fmt.Fprintf(out, "\n") 151 } 152 153 // constructInputAll transforms values parsed from CLI flags into an object to be used by the API client library. 154 func (c *ValidateCommand) constructInputAll(serviceID string, serviceVersion int) *fastly.ValidateAllDomainsInput { 155 var input fastly.ValidateAllDomainsInput 156 157 input.ServiceID = serviceID 158 input.ServiceVersion = serviceVersion 159 160 return &input 161 } 162 163 // printAll displays all domain validation results returned from the API. 164 func (c *ValidateCommand) printAll(out io.Writer, rs []*fastly.DomainValidationResult) { 165 for i, r := range rs { 166 // We only need to print the Service ID/Version once. 167 if i == 0 { 168 fmt.Fprintf(out, "\nService ID: %s\n", fastly.ToValue(r.Metadata.ServiceID)) 169 fmt.Fprintf(out, "Service Version: %d\n\n", fastly.ToValue(r.Metadata.ServiceVersion)) 170 } 171 fmt.Fprintf(out, "Name: %s\n", fastly.ToValue(r.Metadata.Name)) 172 fmt.Fprintf(out, "Valid: %t\n", fastly.ToValue(r.Valid)) 173 174 if r.CName != nil { 175 fmt.Fprintf(out, "CNAME: %s\n", *r.CName) 176 } 177 if r.Metadata.CreatedAt != nil { 178 fmt.Fprintf(out, "Created at: %s\n", r.Metadata.CreatedAt) 179 } 180 if r.Metadata.UpdatedAt != nil { 181 fmt.Fprintf(out, "Updated at: %s\n", r.Metadata.UpdatedAt) 182 } 183 if r.Metadata.DeletedAt != nil { 184 fmt.Fprintf(out, "Deleted at: %s\n", r.Metadata.DeletedAt) 185 } 186 fmt.Fprintf(out, "\n") 187 } 188 }