Skip to content

Commit

Permalink
secret/consul: Add Consul ACL roles support (#14014)
Browse files Browse the repository at this point in the history
Co-authored-by: Brandon Ingalls <[email protected]>
  • Loading branch information
robmonte and Brandon Ingalls authored Feb 17, 2022
1 parent 85f747c commit 8b36f65
Show file tree
Hide file tree
Showing 9 changed files with 307 additions and 136 deletions.
171 changes: 143 additions & 28 deletions builtin/logical/consul/backend_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func TestBackend_Config_Access(t *testing.T) {
t.Parallel()
t.Run("pre-1.4.0", func(t *testing.T) {
t.Parallel()
testBackendConfigAccess(t, "1.3.0")
testBackendConfigAccess(t, "1.3.1")
})
t.Run("post-1.4.0", func(t *testing.T) {
t.Parallel()
Expand Down Expand Up @@ -82,7 +82,7 @@ func TestBackend_Renew_Revoke(t *testing.T) {
t.Parallel()
t.Run("pre-1.4.0", func(t *testing.T) {
t.Parallel()
testBackendRenewRevoke(t, "1.3.0")
testBackendRenewRevoke(t, "1.3.1")
})
t.Run("post-1.4.0", func(t *testing.T) {
t.Parallel()
Expand Down Expand Up @@ -118,7 +118,7 @@ func testBackendRenewRevoke(t *testing.T, version string) {
Path: "config/access",
Data: connData,
}
resp, err := b.HandleRequest(context.Background(), req)
_, err = b.HandleRequest(context.Background(), req)
if err != nil {
t.Fatal(err)
}
Expand All @@ -128,14 +128,14 @@ func testBackendRenewRevoke(t *testing.T, version string) {
"policy": base64.StdEncoding.EncodeToString([]byte(testPolicy)),
"lease": "6h",
}
resp, err = b.HandleRequest(context.Background(), req)
_, err = b.HandleRequest(context.Background(), req)
if err != nil {
t.Fatal(err)
}

req.Operation = logical.ReadOperation
req.Path = "creds/test"
resp, err = b.HandleRequest(context.Background(), req)
resp, err := b.HandleRequest(context.Background(), req)
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -186,7 +186,7 @@ func testBackendRenewRevoke(t *testing.T, version string) {
}

req.Operation = logical.RevokeOperation
resp, err = b.HandleRequest(context.Background(), req)
_, err = b.HandleRequest(context.Background(), req)
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -223,7 +223,7 @@ func testBackendRenewRevoke14(t *testing.T, version string) {
Path: "config/access",
Data: connData,
}
resp, err := b.HandleRequest(context.Background(), req)
_, err = b.HandleRequest(context.Background(), req)
if err != nil {
t.Fatal(err)
}
Expand All @@ -233,14 +233,14 @@ func testBackendRenewRevoke14(t *testing.T, version string) {
"policies": []string{"test"},
"lease": "6h",
}
resp, err = b.HandleRequest(context.Background(), req)
_, err = b.HandleRequest(context.Background(), req)
if err != nil {
t.Fatal(err)
}

req.Operation = logical.ReadOperation
req.Path = "creds/test"
resp, err = b.HandleRequest(context.Background(), req)
resp, err := b.HandleRequest(context.Background(), req)
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -289,7 +289,7 @@ func testBackendRenewRevoke14(t *testing.T, version string) {
}

req.Operation = logical.RevokeOperation
resp, err = b.HandleRequest(context.Background(), req)
_, err = b.HandleRequest(context.Background(), req)
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -335,7 +335,7 @@ func TestBackend_LocalToken(t *testing.T) {
Path: "config/access",
Data: connData,
}
resp, err := b.HandleRequest(context.Background(), req)
_, err = b.HandleRequest(context.Background(), req)
if err != nil {
t.Fatal(err)
}
Expand All @@ -346,7 +346,7 @@ func TestBackend_LocalToken(t *testing.T) {
"ttl": "6h",
"local": false,
}
resp, err = b.HandleRequest(context.Background(), req)
_, err = b.HandleRequest(context.Background(), req)
if err != nil {
t.Fatal(err)
}
Expand All @@ -357,14 +357,14 @@ func TestBackend_LocalToken(t *testing.T) {
"ttl": "6h",
"local": true,
}
resp, err = b.HandleRequest(context.Background(), req)
_, err = b.HandleRequest(context.Background(), req)
if err != nil {
t.Fatal(err)
}

req.Operation = logical.ReadOperation
req.Path = "creds/test"
resp, err = b.HandleRequest(context.Background(), req)
resp, err := b.HandleRequest(context.Background(), req)
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -447,12 +447,14 @@ func TestBackend_Management(t *testing.T) {
t.Parallel()
t.Run("pre-1.4.0", func(t *testing.T) {
t.Parallel()
testBackendManagement(t, "1.3.0")
testBackendManagement(t, "1.3.1")
})
t.Run("post-1.4.0", func(t *testing.T) {
t.Parallel()
testBackendManagement(t, "1.4.4")
})

testBackendManagement(t, "1.10.8")
})
}

Expand Down Expand Up @@ -487,15 +489,16 @@ func TestBackend_Basic(t *testing.T) {
t.Parallel()
t.Run("pre-1.4.0", func(t *testing.T) {
t.Parallel()
testBackendBasic(t, "1.3.0")
testBackendBasic(t, "1.3.1")
})
t.Run("post-1.4.0", func(t *testing.T) {
t.Parallel()
t.Run("legacy", func(t *testing.T) {
t.Parallel()
testBackendRenewRevoke(t, "1.4.4")
testBackendBasic(t, "1.4.4")
})
testBackendBasic(t, "1.4.4")

testBackendBasic(t, "1.10.8")
})
})
}
Expand Down Expand Up @@ -702,6 +705,119 @@ func testAccStepDeletePolicy(t *testing.T, name string) logicaltest.TestStep {
}
}

func TestBackend_Roles(t *testing.T) {
config := logical.TestBackendConfig()
config.StorageView = &logical.InmemStorage{}
b, err := Factory(context.Background(), config)
if err != nil {
t.Fatal(err)
}

cleanup, consulConfig := consul.PrepareTestContainer(t, "", false)
defer cleanup()

connData := map[string]interface{}{
"address": consulConfig.Address(),
"token": consulConfig.Token,
}

req := &logical.Request{
Storage: config.StorageView,
Operation: logical.UpdateOperation,
Path: "config/access",
Data: connData,
}
_, err = b.HandleRequest(context.Background(), req)
if err != nil {
t.Fatal(err)
}

// Create the consul_roles role
req.Path = "roles/test-consul-roles"
req.Data = map[string]interface{}{
"consul_roles": []string{"role-test"},
"lease": "6h",
}
_, err = b.HandleRequest(context.Background(), req)
if err != nil {
t.Fatal(err)
}

req.Operation = logical.ReadOperation
req.Path = "creds/test-consul-roles"
resp, err := b.HandleRequest(context.Background(), req)
if err != nil {
t.Fatal(err)
}
if resp == nil {
t.Fatal("resp nil")
}
if resp.IsError() {
t.Fatalf("resp is error: %v", resp.Error())
}

generatedSecret := resp.Secret
generatedSecret.TTL = 6 * time.Hour

var d struct {
Token string `mapstructure:"token"`
Accessor string `mapstructure:"accessor"`
}
if err := mapstructure.Decode(resp.Data, &d); err != nil {
t.Fatal(err)
}
t.Logf("Generated consul_roles token: %s with accessor %s", d.Token, d.Accessor)

// Build a client and verify that the credentials work
consulapiConfig := consulapi.DefaultNonPooledConfig()
consulapiConfig.Address = connData["address"].(string)
consulapiConfig.Token = d.Token
client, err := consulapi.NewClient(consulapiConfig)
if err != nil {
t.Fatal(err)
}

t.Log("Verifying that the generated token works...")
_, err = client.Catalog(), nil
if err != nil {
t.Fatal(err)
}

req.Operation = logical.RenewOperation
req.Secret = generatedSecret
resp, err = b.HandleRequest(context.Background(), req)
if err != nil {
t.Fatal(err)
}
if resp == nil {
t.Fatal("got nil response from renew")
}

req.Operation = logical.RevokeOperation
_, err = b.HandleRequest(context.Background(), req)
if err != nil {
t.Fatal(err)
}

// Build a management client and verify that the token does not exist anymore
consulmgmtConfig := consulapi.DefaultNonPooledConfig()
consulmgmtConfig.Address = connData["address"].(string)
consulmgmtConfig.Token = connData["token"].(string)
mgmtclient, err := consulapi.NewClient(consulmgmtConfig)
if err != nil {
t.Fatal(err)
}
q := &consulapi.QueryOptions{
Datacenter: "DC1",
}

t.Log("Verifying that the generated token does not exist...")
_, _, err = mgmtclient.ACL().TokenRead(d.Accessor, q)
if err == nil {
t.Fatal("err: expected error")
}
}

func TestBackend_Enterprise_Namespace(t *testing.T) {
if _, hasLicense := os.LookupEnv("CONSUL_LICENSE"); !hasLicense {
t.Skip("Skipping: No enterprise license found")
Expand Down Expand Up @@ -740,7 +856,7 @@ func testBackendEntNamespace(t *testing.T) {
Path: "config/access",
Data: connData,
}
resp, err := b.HandleRequest(context.Background(), req)
_, err = b.HandleRequest(context.Background(), req)
if err != nil {
t.Fatal(err)
}
Expand All @@ -752,14 +868,14 @@ func testBackendEntNamespace(t *testing.T) {
"lease": "6h",
"consul_namespace": "ns1",
}
resp, err = b.HandleRequest(context.Background(), req)
_, err = b.HandleRequest(context.Background(), req)
if err != nil {
t.Fatal(err)
}

req.Operation = logical.ReadOperation
req.Path = "creds/test-ns"
resp, err = b.HandleRequest(context.Background(), req)
resp, err := b.HandleRequest(context.Background(), req)
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -813,7 +929,7 @@ func testBackendEntNamespace(t *testing.T) {
}

req.Operation = logical.RevokeOperation
resp, err = b.HandleRequest(context.Background(), req)
_, err = b.HandleRequest(context.Background(), req)
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -860,7 +976,7 @@ func testBackendEntPartition(t *testing.T) {
Path: "config/access",
Data: connData,
}
resp, err := b.HandleRequest(context.Background(), req)
_, err = b.HandleRequest(context.Background(), req)
if err != nil {
t.Fatal(err)
}
Expand All @@ -872,14 +988,14 @@ func testBackendEntPartition(t *testing.T) {
"lease": "6h",
"partition": "part1",
}
resp, err = b.HandleRequest(context.Background(), req)
_, err = b.HandleRequest(context.Background(), req)
if err != nil {
t.Fatal(err)
}

req.Operation = logical.ReadOperation
req.Path = "creds/test-part"
resp, err = b.HandleRequest(context.Background(), req)
resp, err := b.HandleRequest(context.Background(), req)
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -933,7 +1049,7 @@ func testBackendEntPartition(t *testing.T) {
}

req.Operation = logical.RevokeOperation
resp, err = b.HandleRequest(context.Background(), req)
_, err = b.HandleRequest(context.Background(), req)
if err != nil {
t.Fatal(err)
}
Expand Down Expand Up @@ -961,5 +1077,4 @@ func testBackendEntPartition(t *testing.T) {
const testPolicy = `
key "" {
policy = "write"
}
`
}`
Loading

0 comments on commit 8b36f65

Please sign in to comment.