Merge pull request #3221 from hashicorp/f-acl-cli

ACL CLI
This commit is contained in:
Chelsea Komlo 2017-09-15 20:13:57 -04:00 committed by GitHub
commit efb5cdd9f1
5 changed files with 106 additions and 0 deletions

View file

@ -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)
}

View file

@ -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)

View file

@ -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)
}

View file

@ -30,6 +30,7 @@ func TestMeta_FlagSet(t *testing.T) {
"client-key",
"insecure",
"tls-skip-verify",
"token",
},
},
}

View file

@ -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
}