github.com/rohankumardubey/nomad@v0.11.8/command/job_revert.go (about) 1 package command 2 3 import ( 4 "fmt" 5 "os" 6 "strings" 7 8 "github.com/hashicorp/nomad/api/contexts" 9 "github.com/posener/complete" 10 ) 11 12 type JobRevertCommand struct { 13 Meta 14 } 15 16 func (c *JobRevertCommand) Help() string { 17 helpText := ` 18 Usage: nomad job revert [options] <job> <version> 19 20 Revert is used to revert a job to a prior version of the job. The available 21 versions to revert to can be found using "nomad job history" command. 22 23 General Options: 24 25 ` + generalOptionsUsage() + ` 26 27 Revert Options: 28 29 -detach 30 Return immediately instead of entering monitor mode. After job revert, 31 the evaluation ID will be printed to the screen, which can be used to 32 examine the evaluation using the eval-status command. 33 34 -consul-token 35 The Consul token used to verify that the caller has access to the Service 36 Identity policies associated in the targeted version of the job. 37 38 -vault-token 39 The Vault token used to verify that the caller has access to the Vault 40 policies in the targeted version of the job. 41 42 -verbose 43 Display full information. 44 ` 45 return strings.TrimSpace(helpText) 46 } 47 48 func (c *JobRevertCommand) Synopsis() string { 49 return "Revert to a prior version of the job" 50 } 51 52 func (c *JobRevertCommand) AutocompleteFlags() complete.Flags { 53 return mergeAutocompleteFlags(c.Meta.AutocompleteFlags(FlagSetClient), 54 complete.Flags{ 55 "-detach": complete.PredictNothing, 56 "-verbose": complete.PredictNothing, 57 }) 58 } 59 60 func (c *JobRevertCommand) AutocompleteArgs() complete.Predictor { 61 return complete.PredictFunc(func(a complete.Args) []string { 62 client, err := c.Meta.Client() 63 if err != nil { 64 return nil 65 } 66 67 resp, _, err := client.Search().PrefixSearch(a.Last, contexts.Jobs, nil) 68 if err != nil { 69 return []string{} 70 } 71 return resp.Matches[contexts.Jobs] 72 }) 73 } 74 75 func (c *JobRevertCommand) Name() string { return "job revert" } 76 77 func (c *JobRevertCommand) Run(args []string) int { 78 var detach, verbose bool 79 var consulToken, vaultToken string 80 81 flags := c.Meta.FlagSet(c.Name(), FlagSetClient) 82 flags.Usage = func() { c.Ui.Output(c.Help()) } 83 flags.BoolVar(&detach, "detach", false, "") 84 flags.BoolVar(&verbose, "verbose", false, "") 85 flags.StringVar(&consulToken, "consul-token", "", "") 86 flags.StringVar(&vaultToken, "vault-token", "", "") 87 88 if err := flags.Parse(args); err != nil { 89 return 1 90 } 91 92 // Truncate the id unless full length is requested 93 length := shortId 94 if verbose { 95 length = fullId 96 } 97 98 // Check that we got two args 99 args = flags.Args() 100 if l := len(args); l != 2 { 101 c.Ui.Error("This command takes two arguments: <job> <version>") 102 c.Ui.Error(commandErrorText(c)) 103 return 1 104 } 105 106 // Get the HTTP client 107 client, err := c.Meta.Client() 108 if err != nil { 109 c.Ui.Error(fmt.Sprintf("Error initializing client: %s", err)) 110 return 1 111 } 112 113 // Parse the Consul token 114 if consulToken == "" { 115 // Check the environment variable 116 consulToken = os.Getenv("CONSUL_HTTP_TOKEN") 117 } 118 119 // Parse the Vault token 120 if vaultToken == "" { 121 // Check the environment variable 122 vaultToken = os.Getenv("VAULT_TOKEN") 123 } 124 125 jobID := args[0] 126 revertVersion, ok, err := parseVersion(args[1]) 127 if !ok { 128 c.Ui.Error("The job version to revert to must be specified using the -job-version flag") 129 return 1 130 } 131 if err != nil { 132 c.Ui.Error(fmt.Sprintf("Failed to parse job-version flag: %v", err)) 133 return 1 134 } 135 136 // Check if the job exists 137 jobs, _, err := client.Jobs().PrefixList(jobID) 138 if err != nil { 139 c.Ui.Error(fmt.Sprintf("Error listing jobs: %s", err)) 140 return 1 141 } 142 if len(jobs) == 0 { 143 c.Ui.Error(fmt.Sprintf("No job(s) with prefix or id %q found", jobID)) 144 return 1 145 } 146 if len(jobs) > 1 && strings.TrimSpace(jobID) != jobs[0].ID { 147 c.Ui.Error(fmt.Sprintf("Prefix matched multiple jobs\n\n%s", createStatusListOutput(jobs))) 148 return 1 149 } 150 151 // Prefix lookup matched a single job 152 resp, _, err := client.Jobs().Revert(jobs[0].ID, revertVersion, nil, nil, consulToken, vaultToken) 153 if err != nil { 154 c.Ui.Error(fmt.Sprintf("Error retrieving job versions: %s", err)) 155 return 1 156 } 157 158 // Nothing to do 159 evalCreated := resp.EvalID != "" 160 if detach || !evalCreated { 161 return 0 162 } 163 164 mon := newMonitor(c.Ui, client, length) 165 return mon.monitor(resp.EvalID, false) 166 }