Skip to content

Commit

Permalink
cli: -namespace should override job namespace
Browse files Browse the repository at this point in the history
When a jobspec doesn't include a namespace, we provide it with the default
namespace, but this ends up overriding the explicit `-namespace` flag. This
changeset uses the same logic as region parsing to create an order of
precedence: the query string parameter (the `-namespace` flag) overrides the
API request body which overrides the jobspec.
  • Loading branch information
tgross committed Jul 8, 2021
1 parent b397edf commit 38af39e
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 3 deletions.
3 changes: 3 additions & 0 deletions .changelog/10875.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:bug
cli: Fixed a bug where `-namespace` flag was not respected for `job run` and `job plan` commands.
```
28 changes: 25 additions & 3 deletions command/agent/job_endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -706,18 +706,21 @@ func (s *HTTPServer) apiJobAndRequestToStructs(job *api.Job, req *http.Request,
AuthToken: apiReq.SecretID,
}

queryRegion := req.URL.Query().Get("region")
s.parseToken(req, &writeReq.AuthToken)
parseNamespace(req, &writeReq.Namespace)

queryRegion := req.URL.Query().Get("region")
requestRegion, jobRegion := regionForJob(
job, queryRegion, writeReq.Region, s.agent.config.Region,
)

sJob := ApiJobToStructJob(job)
sJob.Region = jobRegion
writeReq.Region = requestRegion
writeReq.Namespace = sJob.Namespace

queryNamespace := req.URL.Query().Get("namespace")
namespace := namespaceForJob(job.Namespace, queryNamespace, writeReq.Namespace)
sJob.Namespace = namespace
writeReq.Namespace = namespace

return sJob, writeReq
}
Expand Down Expand Up @@ -774,6 +777,25 @@ func regionForJob(job *api.Job, queryRegion, apiRegion, agentRegion string) (str
return requestRegion, jobRegion
}

func namespaceForJob(jobNamespace *string, queryNamespace, apiNamespace string) string {

// Namespace in query param (-namespace flag) takes precedence.
if queryNamespace != "" {
return queryNamespace
}

// Next the request body...
if apiNamespace != "" {
return apiNamespace
}

if jobNamespace != nil && *jobNamespace != "" {
return *jobNamespace
}

return structs.DefaultNamespace
}

func ApiJobToStructJob(job *api.Job) *structs.Job {
job.Canonicalize()

Expand Down
71 changes: 71 additions & 0 deletions command/agent/job_endpoint_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1845,6 +1845,77 @@ func TestJobs_RegionForJob(t *testing.T) {
}
}

func TestJobs_NamespaceForJob(t *testing.T) {
t.Parallel()

// test namespace for pointer inputs
ns := "dev"

cases := []struct {
name string
job *api.Job
queryNamespace string
apiNamespace string
expected string
}{
{
name: "no namespace provided",
job: &api.Job{},
expected: structs.DefaultNamespace,
},

{
name: "jobspec has namespace",
job: &api.Job{Namespace: &ns},
expected: "dev",
},

{
name: "-namespace flag overrides empty job namespace",
job: &api.Job{},
queryNamespace: "prod",
expected: "prod",
},

{
name: "-namespace flag overrides job namespace",
job: &api.Job{Namespace: &ns},
queryNamespace: "prod",
expected: "prod",
},

{
name: "-namespace flag overrides job namespace even if default",
job: &api.Job{Namespace: &ns},
queryNamespace: structs.DefaultNamespace,
expected: structs.DefaultNamespace,
},

{
name: "API param overrides empty job namespace",
job: &api.Job{},
apiNamespace: "prod",
expected: "prod",
},

{
name: "-namespace flag overrides API param",
job: &api.Job{Namespace: &ns},
queryNamespace: "prod",
apiNamespace: "whatever",
expected: "prod",
},
}

for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
require.Equal(t, tc.expected,
namespaceForJob(tc.job.Namespace, tc.queryNamespace, tc.apiNamespace),
)
})
}
}

func TestJobs_ApiJobToStructsJob(t *testing.T) {
apiJob := &api.Job{
Stop: helper.BoolToPtr(true),
Expand Down

0 comments on commit 38af39e

Please sign in to comment.