commit
efb5cdd9f1
|
@ -8,8 +8,10 @@ import (
|
|||
"time"
|
||||
|
||||
"github.com/hashicorp/nomad/helper"
|
||||
"github.com/hashicorp/nomad/nomad/mock"
|
||||
"github.com/hashicorp/nomad/testutil"
|
||||
"github.com/kr/pretty"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestJobs_Register(t *testing.T) {
|
||||
|
@ -1295,3 +1297,42 @@ func TestJobs_Sort(t *testing.T) {
|
|||
t.Fatalf("\n\n%#v\n\n%#v", jobs, expect)
|
||||
}
|
||||
}
|
||||
|
||||
func TestJobs_Summary_WithACL(t *testing.T) {
|
||||
t.Parallel()
|
||||
assert := assert.New(t)
|
||||
|
||||
c, s, root := makeACLClient(t, nil, nil)
|
||||
defer s.Stop()
|
||||
jobs := c.Jobs()
|
||||
|
||||
invalidToken := mock.ACLToken()
|
||||
|
||||
// Registering with an invalid token should fail
|
||||
c.SetSecretID(invalidToken.SecretID)
|
||||
job := testJob()
|
||||
_, _, err := jobs.Register(job, nil)
|
||||
assert.NotNil(err)
|
||||
|
||||
// Register with token should succeed
|
||||
c.SetSecretID(root.SecretID)
|
||||
resp2, wm, err := jobs.Register(job, nil)
|
||||
assert.Nil(err)
|
||||
assert.NotNil(resp2)
|
||||
assert.NotEqual("", resp2.EvalID)
|
||||
assertWriteMeta(t, wm)
|
||||
|
||||
// Query the job summary with an invalid token should fail
|
||||
c.SetSecretID(invalidToken.SecretID)
|
||||
result, _, err := jobs.Summary(*job.ID, nil)
|
||||
assert.NotNil(err)
|
||||
|
||||
// Query the job summary with a valid token should succeed
|
||||
c.SetSecretID(root.SecretID)
|
||||
result, qm, err := jobs.Summary(*job.ID, nil)
|
||||
assert.Nil(err)
|
||||
assertQueryMeta(t, qm)
|
||||
|
||||
// Check that the result is what we expect
|
||||
assert.Equal(*job.ID, result.JobID)
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/hashicorp/nomad/api"
|
||||
"github.com/hashicorp/nomad/command/agent"
|
||||
"github.com/hashicorp/nomad/nomad/mock"
|
||||
"github.com/mitchellh/cli"
|
||||
"github.com/posener/complete"
|
||||
|
@ -215,6 +216,55 @@ func TestJobStatusCommand_AutocompleteArgs(t *testing.T) {
|
|||
assert.Equal(j.ID, res[0])
|
||||
}
|
||||
|
||||
func TestJobStatusCommand_WithAccessPolicy(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
t.Parallel()
|
||||
|
||||
config := func(c *agent.Config) {
|
||||
c.ACL.Enabled = true
|
||||
}
|
||||
|
||||
srv, client, url := testServer(t, true, config)
|
||||
defer srv.Shutdown()
|
||||
|
||||
// Bootstrap an initial ACL token
|
||||
token := srv.Token
|
||||
assert.NotNil(token, "failed to bootstrap ACL token")
|
||||
|
||||
// Register a job
|
||||
j := testJob("job1_sfx")
|
||||
|
||||
invalidToken := mock.ACLToken()
|
||||
|
||||
ui := new(cli.MockUi)
|
||||
cmd := &JobStatusCommand{Meta: Meta{Ui: ui, flagAddress: url}}
|
||||
|
||||
// registering a job without a token fails
|
||||
client.SetSecretID(invalidToken.SecretID)
|
||||
resp, _, err := client.Jobs().Register(j, nil)
|
||||
assert.NotNil(err)
|
||||
|
||||
// registering a job with a valid token succeeds
|
||||
client.SetSecretID(token.SecretID)
|
||||
resp, _, err = client.Jobs().Register(j, nil)
|
||||
assert.Nil(err)
|
||||
code := waitForSuccess(ui, client, fullId, t, resp.EvalID)
|
||||
assert.Equal(0, code)
|
||||
|
||||
// Request Job List without providing a valid token
|
||||
code = cmd.Run([]string{"-address=" + url, "-token=" + invalidToken.SecretID, "-short"})
|
||||
assert.Equal(1, code)
|
||||
|
||||
// Request Job List with a valid token
|
||||
code = cmd.Run([]string{"-address=" + url, "-token=" + token.SecretID, "-short"})
|
||||
assert.Equal(0, code)
|
||||
|
||||
out := ui.OutputWriter.String()
|
||||
if !strings.Contains(out, *j.ID) {
|
||||
t.Fatalf("should contain full identifiers, got %s", out)
|
||||
}
|
||||
}
|
||||
|
||||
func waitForSuccess(ui cli.Ui, client *api.Client, length int, t *testing.T, evalId string) int {
|
||||
mon := newMonitor(ui, client, length)
|
||||
monErr := mon.monitor(evalId, false)
|
||||
|
|
|
@ -47,6 +47,9 @@ type Meta struct {
|
|||
// namespace to send API requests
|
||||
namespace string
|
||||
|
||||
// token is used for ACLs to access privilaged information
|
||||
token string
|
||||
|
||||
caCert string
|
||||
caPath string
|
||||
clientCert string
|
||||
|
@ -74,6 +77,7 @@ func (m *Meta) FlagSet(n string, fs FlagSetFlags) *flag.FlagSet {
|
|||
f.StringVar(&m.clientKey, "client-key", "", "")
|
||||
f.BoolVar(&m.insecure, "insecure", false, "")
|
||||
f.BoolVar(&m.insecure, "tls-skip-verify", false, "")
|
||||
f.StringVar(&m.token, "token", "", "")
|
||||
|
||||
}
|
||||
|
||||
|
@ -110,6 +114,7 @@ func (m *Meta) AutocompleteFlags(fs FlagSetFlags) complete.Flags {
|
|||
"-client-key": complete.PredictFiles("*"),
|
||||
"-insecure": complete.PredictNothing,
|
||||
"-tls-skip-verify": complete.PredictNothing,
|
||||
"-token": complete.PredictAnything,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -142,6 +147,10 @@ func (m *Meta) Client() (*api.Client, error) {
|
|||
config.TLSConfig = t
|
||||
}
|
||||
|
||||
if m.token != "" {
|
||||
config.SecretID = m.token
|
||||
}
|
||||
|
||||
return api.NewClient(config)
|
||||
}
|
||||
|
||||
|
@ -198,6 +207,10 @@ func generalOptionsUsage() string {
|
|||
-tls-skip-verify
|
||||
Do not verify TLS certificate. This is highly not recommended. Verification
|
||||
will also be skipped if NOMAD_SKIP_VERIFY is set.
|
||||
|
||||
-token
|
||||
The SecretID of an ACL token to use to authenticate API requests with.
|
||||
Overrides the NOMAD_TOKEN environment variable if set.
|
||||
`
|
||||
return strings.TrimSpace(helpText)
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ func TestMeta_FlagSet(t *testing.T) {
|
|||
"client-key",
|
||||
"insecure",
|
||||
"tls-skip-verify",
|
||||
"token",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -281,6 +281,7 @@ func getSignalConstraint(signals []string) *structs.Constraint {
|
|||
// Summary retreives the summary of a job
|
||||
func (j *Job) Summary(args *structs.JobSummaryRequest,
|
||||
reply *structs.JobSummaryResponse) error {
|
||||
|
||||
if done, err := j.srv.forward("Job.Summary", args, args, reply); done {
|
||||
return err
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue