From 694d9c450ab892f01ac772173d40f61b39946b53 Mon Sep 17 00:00:00 2001 From: Alex Dadgar Date: Wed, 19 Apr 2017 14:57:28 -0700 Subject: [PATCH] Revert api --- api/jobs.go | 45 +++++++++++++++++++++++++++++++++++---------- api/jobs_test.go | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+), 10 deletions(-) diff --git a/api/jobs.go b/api/jobs.go index a3c954394..0488909f5 100644 --- a/api/jobs.go +++ b/api/jobs.go @@ -52,7 +52,7 @@ func (j *Jobs) Validate(job *Job, q *WriteOptions) (*JobValidateResponse, *Write // of the evaluation, along with any errors encountered. func (j *Jobs) Register(job *Job, q *WriteOptions) (string, *WriteMeta, error) { - var resp registerJobResponse + var resp JobRegisterResponse req := &RegisterJobRequest{Job: job} wm, err := j.client.write("/v1/jobs", req, &resp, q) @@ -65,7 +65,7 @@ func (j *Jobs) Register(job *Job, q *WriteOptions) (string, *WriteMeta, error) { // EnforceRegister is used to register a job enforcing its job modify index. func (j *Jobs) EnforceRegister(job *Job, modifyIndex uint64, q *WriteOptions) (string, *WriteMeta, error) { - var resp registerJobResponse + var resp JobRegisterResponse req := &RegisterJobRequest{ Job: job, @@ -153,7 +153,7 @@ func (j *Jobs) Evaluations(jobID string, q *QueryOptions) ([]*Evaluation, *Query // is deregistered and purged from the system versus still being queryable and // eventually GC'ed from the system. Most callers should not specify purge. func (j *Jobs) Deregister(jobID string, purge bool, q *WriteOptions) (string, *WriteMeta, error) { - var resp deregisterJobResponse + var resp JobDeregisterResponse wm, err := j.client.delete(fmt.Sprintf("/v1/job/%v?purge=%t", jobID, purge), &resp, q) if err != nil { return "", nil, err @@ -163,7 +163,7 @@ func (j *Jobs) Deregister(jobID string, purge bool, q *WriteOptions) (string, *W // ForceEvaluate is used to force-evaluate an existing job. func (j *Jobs) ForceEvaluate(jobID string, q *WriteOptions) (string, *WriteMeta, error) { - var resp registerJobResponse + var resp JobRegisterResponse wm, err := j.client.write("/v1/job/"+jobID+"/evaluate", nil, &resp, q) if err != nil { return "", nil, err @@ -223,6 +223,25 @@ func (j *Jobs) Dispatch(jobID string, meta map[string]string, return &resp, wm, nil } +// Revert is used to revert the given job to the passed version. If +// enforceVersion is set, the job is only reverted if the current version is at +// the passed version. +func (j *Jobs) Revert(jobID string, version uint64, enforcePriorVersion *uint64, + q *WriteOptions) (*JobRegisterResponse, *WriteMeta, error) { + + var resp JobRegisterResponse + req := &JobRevertRequest{ + JobID: jobID, + JobVersion: version, + EnforcePriorVersion: enforcePriorVersion, + } + wm, err := j.client.write("/v1/job/"+jobID+"/revert", req, &resp, q) + if err != nil { + return nil, nil, err + } + return &resp, wm, nil +} + // periodicForceResponse is used to deserialize a force response type periodicForceResponse struct { EvalID string @@ -573,14 +592,20 @@ type RegisterJobRequest struct { JobModifyIndex uint64 `json:",omitempty"` } -// registerJobResponse is used to deserialize a job response -type registerJobResponse struct { - EvalID string +// JobRegisterResponse is used to respond to a job registration +type JobRegisterResponse struct { + EvalID string + EvalCreateIndex uint64 + JobModifyIndex uint64 + QueryMeta } -// deregisterJobResponse is used to decode a deregister response -type deregisterJobResponse struct { - EvalID string +// JobDeregisterResponse is used to respond to a job deregistration +type JobDeregisterResponse struct { + EvalID string + EvalCreateIndex uint64 + JobModifyIndex uint64 + QueryMeta } type JobPlanRequest struct { diff --git a/api/jobs_test.go b/api/jobs_test.go index f9b1d1512..e20978d9a 100644 --- a/api/jobs_test.go +++ b/api/jobs_test.go @@ -487,6 +487,54 @@ func TestJobs_EnforceRegister(t *testing.T) { assertWriteMeta(t, wm) } +func TestJobs_Revert(t *testing.T) { + c, s := makeClient(t, nil, nil) + defer s.Stop() + jobs := c.Jobs() + + // Register twice + job := testJob() + eval, wm, err := jobs.Register(job, nil) + if err != nil { + t.Fatalf("err: %s", err) + } + if eval == "" { + t.Fatalf("missing eval id") + } + assertWriteMeta(t, wm) + + eval, wm, err = jobs.Register(job, nil) + if err != nil { + t.Fatalf("err: %s", err) + } + if eval == "" { + t.Fatalf("missing eval id") + } + assertWriteMeta(t, wm) + + // Fail revert at incorrect enforce + _, wm, err = jobs.Revert(*job.ID, 0, helper.Uint64ToPtr(10), nil) + if err == nil || !strings.Contains(err.Error(), "enforcing version") { + t.Fatalf("expected enforcement error: %v", err) + } + + // Works at correct index + revertResp, wm, err := jobs.Revert(*job.ID, 0, helper.Uint64ToPtr(1), nil) + if err != nil { + t.Fatalf("err: %s", err) + } + if revertResp.EvalID == "" { + t.Fatalf("missing eval id") + } + if revertResp.EvalCreateIndex == 0 { + t.Fatalf("bad eval create index") + } + if revertResp.JobModifyIndex == 0 { + t.Fatalf("bad job modify index") + } + assertWriteMeta(t, wm) +} + func TestJobs_Info(t *testing.T) { c, s := makeClient(t, nil, nil) defer s.Stop()