-
Notifications
You must be signed in to change notification settings - Fork 4.4k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
catalog, mesh: implement missing ACL hooks (#19143)
This change adds ACL hooks to the remaining catalog and mesh resources, excluding any computed ones. Those will for now continue using the default operator:x permissions. It refactors a lot of the common testing functions so that they can be re-used between resources. There are also some types that we don't yet support (e.g. virtual IPs) that this change adds ACL hooks to for future-proofing.
- Loading branch information
Showing
50 changed files
with
996 additions
and
179 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
21 changes: 21 additions & 0 deletions
21
internal/catalog/catalogtest/helpers/acl_hooks_test_helpers.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
// Copyright (c) HashiCorp, Inc. | ||
// SPDX-License-Identifier: BUSL-1.1 | ||
|
||
package helpers | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/hashicorp/consul/internal/catalog" | ||
"github.com/hashicorp/consul/internal/catalog/internal/testhelpers" | ||
"github.com/hashicorp/consul/internal/resource" | ||
pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" | ||
"github.com/hashicorp/consul/proto-public/pbresource" | ||
) | ||
|
||
func RunWorkloadSelectingTypeACLsTests[T catalog.WorkloadSelecting](t *testing.T, typ *pbresource.Type, | ||
getData func(selector *pbcatalog.WorkloadSelector) T, | ||
registerFunc func(registry resource.Registry), | ||
) { | ||
testhelpers.RunWorkloadSelectingTypeACLsTests[T](t, typ, getData, registerFunc) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
113 changes: 113 additions & 0 deletions
113
internal/catalog/internal/testhelpers/acl_hooks_test_helpers.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
// Copyright (c) HashiCorp, Inc. | ||
// SPDX-License-Identifier: BUSL-1.1 | ||
|
||
package testhelpers | ||
|
||
import ( | ||
"testing" | ||
|
||
"google.golang.org/protobuf/proto" | ||
|
||
"github.com/hashicorp/consul/internal/resource" | ||
"github.com/hashicorp/consul/internal/resource/resourcetest" | ||
pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1" | ||
"github.com/hashicorp/consul/proto-public/pbresource" | ||
) | ||
|
||
// WorkloadSelecting denotes a resource type that uses workload selectors. | ||
type WorkloadSelecting interface { | ||
proto.Message | ||
GetWorkloads() *pbcatalog.WorkloadSelector | ||
} | ||
|
||
func RunWorkloadSelectingTypeACLsTests[T WorkloadSelecting](t *testing.T, typ *pbresource.Type, | ||
getData func(selector *pbcatalog.WorkloadSelector) T, | ||
registerFunc func(registry resource.Registry), | ||
) { | ||
// Wire up a registry to generically invoke hooks | ||
registry := resource.NewRegistry() | ||
registerFunc(registry) | ||
|
||
cases := map[string]resourcetest.ACLTestCase{ | ||
"no rules": { | ||
Rules: ``, | ||
Data: getData(&pbcatalog.WorkloadSelector{Names: []string{"workload"}}), | ||
Typ: typ, | ||
ReadOK: resourcetest.DENY, | ||
WriteOK: resourcetest.DENY, | ||
ListOK: resourcetest.DEFAULT, | ||
}, | ||
"service test read": { | ||
Rules: `service "test" { policy = "read" }`, | ||
Data: getData(&pbcatalog.WorkloadSelector{Names: []string{"workload"}}), | ||
Typ: typ, | ||
ReadOK: resourcetest.ALLOW, | ||
WriteOK: resourcetest.DENY, | ||
ListOK: resourcetest.DEFAULT, | ||
}, | ||
"service test write with named selectors and insufficient policy": { | ||
Rules: `service "test" { policy = "write" }`, | ||
Data: getData(&pbcatalog.WorkloadSelector{Names: []string{"workload"}}), | ||
Typ: typ, | ||
ReadOK: resourcetest.ALLOW, | ||
WriteOK: resourcetest.DENY, | ||
ListOK: resourcetest.DEFAULT, | ||
}, | ||
"service test write with prefixed selectors and insufficient policy": { | ||
Rules: `service "test" { policy = "write" }`, | ||
Data: getData(&pbcatalog.WorkloadSelector{Prefixes: []string{"workload"}}), | ||
Typ: typ, | ||
ReadOK: resourcetest.ALLOW, | ||
WriteOK: resourcetest.DENY, | ||
ListOK: resourcetest.DEFAULT, | ||
}, | ||
"service test write with named selectors": { | ||
Rules: `service "test" { policy = "write" } service "workload" { policy = "read" }`, | ||
Data: getData(&pbcatalog.WorkloadSelector{Names: []string{"workload"}}), | ||
Typ: typ, | ||
ReadOK: resourcetest.ALLOW, | ||
WriteOK: resourcetest.ALLOW, | ||
ListOK: resourcetest.DEFAULT, | ||
}, | ||
"service test write with prefixed selectors": { | ||
Rules: `service "test" { policy = "write" } service_prefix "workload-" { policy = "read" }`, | ||
Data: getData(&pbcatalog.WorkloadSelector{Prefixes: []string{"workload-"}}), | ||
Typ: typ, | ||
ReadOK: resourcetest.ALLOW, | ||
WriteOK: resourcetest.ALLOW, | ||
ListOK: resourcetest.DEFAULT, | ||
}, | ||
"service test write with prefixed selectors and a policy with more specific than the selector": { | ||
Rules: `service "test" { policy = "write" } service_prefix "workload-" { policy = "read" }`, | ||
Data: getData(&pbcatalog.WorkloadSelector{Prefixes: []string{"wor"}}), | ||
Typ: typ, | ||
ReadOK: resourcetest.ALLOW, | ||
WriteOK: resourcetest.DENY, | ||
ListOK: resourcetest.DEFAULT, | ||
}, | ||
"service test write with prefixed selectors and a policy with less specific than the selector": { | ||
Rules: `service "test" { policy = "write" } service_prefix "wor" { policy = "read" }`, | ||
Data: getData(&pbcatalog.WorkloadSelector{Prefixes: []string{"workload-"}}), | ||
Typ: typ, | ||
ReadOK: resourcetest.ALLOW, | ||
WriteOK: resourcetest.ALLOW, | ||
ListOK: resourcetest.DEFAULT, | ||
}, | ||
"service test write with prefixed selectors and a policy with a specific service": { | ||
Rules: `service "test" { policy = "write" } service "workload" { policy = "read" }`, | ||
Data: getData(&pbcatalog.WorkloadSelector{Prefixes: []string{"workload"}}), | ||
Typ: typ, | ||
ReadOK: resourcetest.ALLOW, | ||
// TODO (ishustava): this is wrong and should be fixed in a follow up PR. We should not allow | ||
// a policy for a specific service when only prefixes are specified in the selector. | ||
WriteOK: resourcetest.ALLOW, | ||
ListOK: resourcetest.DEFAULT, | ||
}, | ||
} | ||
|
||
for name, tc := range cases { | ||
t.Run(name, func(t *testing.T) { | ||
resourcetest.RunACLTestCase(t, tc, registry) | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
// Copyright (c) HashiCorp, Inc. | ||
// SPDX-License-Identifier: BUSL-1.1 | ||
|
||
package types | ||
|
||
import ( | ||
"github.com/hashicorp/consul/acl" | ||
"github.com/hashicorp/consul/internal/resource" | ||
"github.com/hashicorp/consul/proto-public/pbresource" | ||
) | ||
|
||
func aclReadHookResourceWithWorkloadSelector(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, id *pbresource.ID, _ *pbresource.Resource) error { | ||
return authorizer.ToAllowAuthorizer().ServiceReadAllowed(id.GetName(), authzContext) | ||
} | ||
|
||
func aclWriteHookResourceWithWorkloadSelector[T WorkloadSelecting](authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, res *pbresource.Resource) error { | ||
if res == nil { | ||
return resource.ErrNeedResource | ||
} | ||
|
||
decodedService, err := resource.Decode[T](res) | ||
if err != nil { | ||
return resource.ErrNeedResource | ||
} | ||
|
||
// First check service:write on the name. | ||
err = authorizer.ToAllowAuthorizer().ServiceWriteAllowed(res.GetId().GetName(), authzContext) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
// Then also check whether we're allowed to select a service. | ||
for _, name := range decodedService.GetData().GetWorkloads().GetNames() { | ||
err = authorizer.ToAllowAuthorizer().ServiceReadAllowed(name, authzContext) | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
|
||
for _, prefix := range decodedService.GetData().GetWorkloads().GetPrefixes() { | ||
err = authorizer.ToAllowAuthorizer().ServiceReadAllowed(prefix, authzContext) | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
|
||
return nil | ||
} | ||
|
||
func ACLHooksForWorkloadSelectingType[T WorkloadSelecting]() *resource.ACLHooks { | ||
return &resource.ACLHooks{ | ||
Read: aclReadHookResourceWithWorkloadSelector, | ||
Write: aclWriteHookResourceWithWorkloadSelector[T], | ||
List: resource.NoOpACLListHook, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.