add dispatch idempotency token support in the CLI (#10930)

This commit is contained in:
Luiz Aoqui 2021-10-22 12:39:05 -04:00 committed by GitHub
parent 2c7bfb7000
commit 3c22fc79a5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 75 additions and 19 deletions

3
.changelog/10930.txt Normal file
View File

@ -0,0 +1,3 @@
```release-note:improvement
cli: Add `-idempotency-token` option for the `nomad job dispatch` command
```

View File

@ -813,21 +813,22 @@ type Job struct {
/* Fields set by server, not sourced from job config file */ /* Fields set by server, not sourced from job config file */
Stop *bool Stop *bool
ParentID *string ParentID *string
Dispatched bool Dispatched bool
Payload []byte DispatchIdempotencyToken *string
ConsulNamespace *string `mapstructure:"consul_namespace"` Payload []byte
VaultNamespace *string `mapstructure:"vault_namespace"` ConsulNamespace *string `mapstructure:"consul_namespace"`
NomadTokenID *string `mapstructure:"nomad_token_id"` VaultNamespace *string `mapstructure:"vault_namespace"`
Status *string NomadTokenID *string `mapstructure:"nomad_token_id"`
StatusDescription *string Status *string
Stable *bool StatusDescription *string
Version *uint64 Stable *bool
SubmitTime *int64 Version *uint64
CreateIndex *uint64 SubmitTime *int64
ModifyIndex *uint64 CreateIndex *uint64
JobModifyIndex *uint64 ModifyIndex *uint64
JobModifyIndex *uint64
} }
// IsPeriodic returns whether a job is periodic. // IsPeriodic returns whether a job is periodic.

View File

@ -6,6 +6,7 @@ import (
"os" "os"
"strings" "strings"
"github.com/hashicorp/nomad/api"
flaghelper "github.com/hashicorp/nomad/helper/flags" flaghelper "github.com/hashicorp/nomad/helper/flags"
"github.com/posener/complete" "github.com/posener/complete"
) )
@ -23,6 +24,10 @@ Usage: nomad job dispatch [options] <parameterized job> [input source]
path to a file. Metadata can be supplied by using the meta flag one or more path to a file. Metadata can be supplied by using the meta flag one or more
times. times.
An optional idempotency token can be used to prevent more than one instance
of the job to be dispatched. If an instance with the same token already
exists, the command returns without any action.
Upon successful creation, the dispatched job ID will be printed and the Upon successful creation, the dispatched job ID will be printed and the
triggered evaluation will be monitored. This can be disabled by supplying the triggered evaluation will be monitored. This can be disabled by supplying the
detach flag. detach flag.
@ -48,6 +53,10 @@ Dispatch Options:
the evaluation ID will be printed to the screen, which can be used to the evaluation ID will be printed to the screen, which can be used to
examine the evaluation using the eval-status command. examine the evaluation using the eval-status command.
-idempotency-token
Optional identifier used to prevent more than one instance of the job from
being dispatched.
-verbose -verbose
Display full information. Display full information.
` `
@ -61,9 +70,10 @@ func (c *JobDispatchCommand) Synopsis() string {
func (c *JobDispatchCommand) AutocompleteFlags() complete.Flags { func (c *JobDispatchCommand) AutocompleteFlags() complete.Flags {
return mergeAutocompleteFlags(c.Meta.AutocompleteFlags(FlagSetClient), return mergeAutocompleteFlags(c.Meta.AutocompleteFlags(FlagSetClient),
complete.Flags{ complete.Flags{
"-meta": complete.PredictAnything, "-meta": complete.PredictAnything,
"-detach": complete.PredictNothing, "-detach": complete.PredictNothing,
"-verbose": complete.PredictNothing, "-idempotency-token": complete.PredictAnything,
"-verbose": complete.PredictNothing,
}) })
} }
@ -95,12 +105,14 @@ func (c *JobDispatchCommand) Name() string { return "job dispatch" }
func (c *JobDispatchCommand) Run(args []string) int { func (c *JobDispatchCommand) Run(args []string) int {
var detach, verbose bool var detach, verbose bool
var idempotencyToken string
var meta []string var meta []string
flags := c.Meta.FlagSet(c.Name(), FlagSetClient) flags := c.Meta.FlagSet(c.Name(), FlagSetClient)
flags.Usage = func() { c.Ui.Output(c.Help()) } flags.Usage = func() { c.Ui.Output(c.Help()) }
flags.BoolVar(&detach, "detach", false, "") flags.BoolVar(&detach, "detach", false, "")
flags.BoolVar(&verbose, "verbose", false, "") flags.BoolVar(&verbose, "verbose", false, "")
flags.StringVar(&idempotencyToken, "idempotency-token", "", "")
flags.Var((*flaghelper.StringFlag)(&meta), "meta", "") flags.Var((*flaghelper.StringFlag)(&meta), "meta", "")
if err := flags.Parse(args); err != nil { if err := flags.Parse(args); err != nil {
@ -159,7 +171,10 @@ func (c *JobDispatchCommand) Run(args []string) int {
} }
// Dispatch the job // Dispatch the job
resp, _, err := client.Jobs().Dispatch(job, metaMap, payload, nil) w := &api.WriteOptions{
IdempotencyToken: idempotencyToken,
}
resp, _, err := client.Jobs().Dispatch(job, metaMap, payload, w)
if err != nil { if err != nil {
c.Ui.Error(fmt.Sprintf("Failed to dispatch job: %s", err)) c.Ui.Error(fmt.Sprintf("Failed to dispatch job: %s", err))
return 1 return 1

View File

@ -189,6 +189,10 @@ func (c *JobStatusCommand) Run(args []string) int {
fmt.Sprintf("Parameterized|%v", parameterized), fmt.Sprintf("Parameterized|%v", parameterized),
} }
if job.DispatchIdempotencyToken != nil && *job.DispatchIdempotencyToken != "" {
basic = append(basic, fmt.Sprintf("Idempotency Token|%v", *job.DispatchIdempotencyToken))
}
if periodic && !parameterized { if periodic && !parameterized {
if *job.Stop { if *job.Stop {
basic = append(basic, "Next Periodic Launch|none (job stopped)") basic = append(basic, "Next Periodic Launch|none (job stopped)")

View File

@ -1617,6 +1617,10 @@ The table below shows this endpoint's support for
- `:job_id` `(string: <required>)` - Specifies the ID of the job (as specified - `:job_id` `(string: <required>)` - Specifies the ID of the job (as specified
in the job file during submission). This is specified as part of the path. in the job file during submission). This is specified as part of the path.
- `idempotency_token` `(string: "")` - Optional identifier used to prevent more
than one instance of the job from being dispatched. This is specified as a
URL query parameter.
- `Payload` `(string: "")` - Specifies a base64 encoded string containing the - `Payload` `(string: "")` - Specifies a base64 encoded string containing the
payload. This is limited to 16384 bytes (16KiB). payload. This is limited to 16384 bytes (16KiB).

View File

@ -30,6 +30,11 @@ flag one or more times.
The payload has a **size limit of 16384 bytes (16KiB)**. The payload has a **size limit of 16384 bytes (16KiB)**.
An optional idempotency token can be specified to prevent dispatching more than
one instance of the same job. The token can have any value and will be matched
with existing jobs. If an instance with the same token already exists, the job
will not be dispatched.
Upon successful creation, the dispatched job ID will be printed and the Upon successful creation, the dispatched job ID will be printed and the
triggered evaluation will be monitored. This can be disabled by supplying the triggered evaluation will be monitored. This can be disabled by supplying the
detach flag. detach flag.
@ -58,6 +63,9 @@ capability for the job's namespace.
will be output, which can be used to examine the evaluation using the will be output, which can be used to examine the evaluation using the
[eval status] command [eval status] command
- `-idempotency-token`: Optional identifier used to prevent more than one
instance of the job from being dispatched.
- `-verbose`: Show full information. - `-verbose`: Show full information.
## Examples ## Examples
@ -109,5 +117,26 @@ Dispatched Job ID = example/dispatch-1485380684-c37b3dba
Evaluation ID = d9034c4e Evaluation ID = d9034c4e
``` ```
Dispatch with an idempotency token for the first time:
```shell-session
$ nomad job dispatch -idempotency-token=prod video-encode video-config.json
Dispatched Job ID = video-encode/dispatch-1485379325-cb38d00d
Evaluation ID = 31199841
==> Monitoring evaluation "31199841"
Evaluation triggered by job "example/dispatch-1485379325-cb38d00d"
Allocation "8254b85f" created: node "82ff9c50", group "cache"
Evaluation status changed: "pending" -> "complete"
==> Evaluation "31199841" finished with status "complete"
```
Dispatch with the same idempotency token:
```shell-session
$ nomad job dispatch -idempotency-token=prod video-encode video-config.json
Job "video-encode/dispatch-1485379325-cb38d00d" already dispatched with idempotency token "prod".
```
[eval status]: /docs/commands/eval-status [eval status]: /docs/commands/eval-status
[parameterized job]: /docs/job-specification/parameterized 'Nomad parameterized Job Specification' [parameterized job]: /docs/job-specification/parameterized 'Nomad parameterized Job Specification'