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  }