github.com/diptanu/nomad@v0.5.7-0.20170516172507-d72e86cbe3d9/command/validate.go (about) 1 package command 2 3 import ( 4 "fmt" 5 "strings" 6 7 multierror "github.com/hashicorp/go-multierror" 8 "github.com/hashicorp/nomad/api" 9 "github.com/hashicorp/nomad/command/agent" 10 ) 11 12 type ValidateCommand struct { 13 Meta 14 JobGetter 15 } 16 17 func (c *ValidateCommand) Help() string { 18 helpText := ` 19 Usage: nomad validate [options] <path> 20 21 Checks if a given HCL job file has a valid specification. This can be used to 22 check for any syntax errors or validation problems with a job. 23 24 If the supplied path is "-", the jobfile is read from stdin. Otherwise 25 it is read from the file at the supplied path or downloaded and 26 read from URL specified. 27 ` 28 return strings.TrimSpace(helpText) 29 } 30 31 func (c *ValidateCommand) Synopsis() string { 32 return "Checks if a given job specification is valid" 33 } 34 35 func (c *ValidateCommand) Run(args []string) int { 36 flags := c.Meta.FlagSet("validate", FlagSetNone) 37 flags.Usage = func() { c.Ui.Output(c.Help()) } 38 if err := flags.Parse(args); err != nil { 39 return 1 40 } 41 42 // Check that we got exactly one node 43 args = flags.Args() 44 if len(args) != 1 { 45 c.Ui.Error(c.Help()) 46 return 1 47 } 48 49 // Get Job struct from Jobfile 50 job, err := c.JobGetter.ApiJob(args[0]) 51 if err != nil { 52 c.Ui.Error(fmt.Sprintf("Error getting job struct: %s", err)) 53 return 1 54 } 55 56 // Get the HTTP client 57 client, err := c.Meta.Client() 58 if err != nil { 59 c.Ui.Error(fmt.Sprintf("Error initializing client: %s", err)) 60 return 255 61 } 62 63 // Force the region to be that of the job. 64 if r := job.Region; r != nil { 65 client.SetRegion(*r) 66 } 67 68 // Check that the job is valid 69 jr, _, err := client.Jobs().Validate(job, nil) 70 if err != nil { 71 jr, err = c.validateLocal(job) 72 } 73 if err != nil { 74 c.Ui.Error(fmt.Sprintf("Error validating job: %s", err)) 75 return 1 76 } 77 78 if jr != nil && !jr.DriverConfigValidated { 79 c.Ui.Output( 80 c.Colorize().Color("[bold][yellow]Driver configuration not validated since connection to Nomad agent couldn't be established.[reset]\n")) 81 } 82 83 if jr != nil && jr.Error != "" { 84 c.Ui.Error( 85 c.Colorize().Color("[bold][red]Job validation errors:[reset]")) 86 c.Ui.Error(jr.Error) 87 return 1 88 } 89 90 // Done! 91 c.Ui.Output( 92 c.Colorize().Color("[bold][green]Job validation successful[reset]")) 93 return 0 94 } 95 96 // validateLocal validates without talking to a Nomad agent 97 func (c *ValidateCommand) validateLocal(aj *api.Job) (*api.JobValidateResponse, error) { 98 var out api.JobValidateResponse 99 100 job := agent.ApiJobToStructJob(aj) 101 job.Canonicalize() 102 103 if vErr := job.Validate(); vErr != nil { 104 if merr, ok := vErr.(*multierror.Error); ok { 105 for _, err := range merr.Errors { 106 out.ValidationErrors = append(out.ValidationErrors, err.Error()) 107 } 108 out.Error = merr.Error() 109 } else { 110 out.ValidationErrors = append(out.ValidationErrors, vErr.Error()) 111 out.Error = vErr.Error() 112 } 113 } 114 115 return &out, nil 116 }