Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Net 5875 - Create the Exported Services Resources #19117

Merged
merged 88 commits into from
Oct 26, 2023
Merged
Show file tree
Hide file tree
Changes from 47 commits
Commits
Show all changes
88 commits
Select commit Hold shift + click to select a range
714f8a3
init
absolutelightning Oct 9, 2023
c1e1e4e
computed exported service
absolutelightning Oct 9, 2023
8be5941
make proto
absolutelightning Oct 9, 2023
f7f396e
exported services resource
absolutelightning Oct 9, 2023
55ba121
exported services test
absolutelightning Oct 9, 2023
755b08d
added some tests and namespace exported service
absolutelightning Oct 9, 2023
10af828
partition exported services
absolutelightning Oct 9, 2023
c97f8c2
computed service
absolutelightning Oct 9, 2023
074ed36
computed services tests
absolutelightning Oct 9, 2023
4221562
register types
absolutelightning Oct 9, 2023
7415265
fix comment
absolutelightning Oct 9, 2023
75e2b49
Merge branch 'main' into NET-5875
absolutelightning Oct 9, 2023
689de78
make proto lint
absolutelightning Oct 9, 2023
5375a1a
fix proto format make proto
absolutelightning Oct 9, 2023
e15f0eb
Merge branch 'NET-5875' of ssh://github.com/hashicorp/consul into NET…
absolutelightning Oct 9, 2023
13e59ff
make codegen
absolutelightning Oct 9, 2023
a681ded
Update proto-public/pbmulticluster/v1alpha1/computed_exported_service…
absolutelightning Oct 10, 2023
ff6a831
Update internal/multicluster/internal/types/computed_exported_service…
absolutelightning Oct 10, 2023
f2a7e22
using different way of resource creation in tests
absolutelightning Oct 10, 2023
13a5ed0
make proto
absolutelightning Oct 10, 2023
2e21983
Merge branch 'main' into NET-5875
absolutelightning Oct 10, 2023
6cfa2a0
fix computed exported services test
absolutelightning Oct 11, 2023
d12e785
fix tests
absolutelightning Oct 11, 2023
3df55fb
differnet validation for computed services for ent and ce
absolutelightning Oct 11, 2023
e1a8e96
Acls for exported services
absolutelightning Oct 11, 2023
8a922ae
added validations for enterprise features in ce
absolutelightning Oct 11, 2023
bbb7592
fix error
absolutelightning Oct 11, 2023
08d9d6e
fix acls test
absolutelightning Oct 11, 2023
393e5eb
Update internal/multicluster/internal/types/validation_exported_servi…
absolutelightning Oct 12, 2023
59cb443
removed the create method
absolutelightning Oct 12, 2023
15febaf
update proto
absolutelightning Oct 12, 2023
9d5e2da
removed namespace
absolutelightning Oct 12, 2023
437490b
created seperate function for ce and ent
absolutelightning Oct 13, 2023
d97bfd8
test files updated and validations fixed
absolutelightning Oct 13, 2023
2985849
added nil checks
absolutelightning Oct 13, 2023
2103241
fix tests
absolutelightning Oct 13, 2023
5c1ef95
added comments
absolutelightning Oct 13, 2023
792e493
removed tenancy check
absolutelightning Oct 16, 2023
9a6f4b6
added mutation function
absolutelightning Oct 16, 2023
022be04
fix mutation method
absolutelightning Oct 16, 2023
c0757c8
fix list permissions in test
absolutelightning Oct 16, 2023
617b297
fix pr comments
absolutelightning Oct 16, 2023
a9202a6
fix tests
absolutelightning Oct 17, 2023
63aa314
lisence
absolutelightning Oct 17, 2023
9ff14cc
busl license
absolutelightning Oct 17, 2023
c7469ca
Merge branch 'main' into NET-5875
absolutelightning Oct 17, 2023
f78152f
Merge branch 'main' into NET-5875
absolutelightning Oct 18, 2023
79eda17
Update internal/multicluster/internal/types/helpers_ce.go
absolutelightning Oct 19, 2023
25d0993
Update internal/multicluster/internal/types/helpers_ce.go
absolutelightning Oct 19, 2023
d48c01e
Update internal/multicluster/internal/types/helpers_ce.go
absolutelightning Oct 19, 2023
c44b424
make proto
absolutelightning Oct 19, 2023
e6bb0db
Merge branch 'NET-5875' of ssh://github.com/hashicorp/consul into NET…
absolutelightning Oct 19, 2023
fc29782
some pr comments addressed
absolutelightning Oct 19, 2023
20e5781
some pr comments addressed
absolutelightning Oct 19, 2023
d729d59
acls helper
absolutelightning Oct 19, 2023
1c4cf98
Merge branch 'main' of ssh://github.com/hashicorp/consul into NET-5875
absolutelightning Oct 19, 2023
112ad62
Merge branch 'main' into NET-5875
absolutelightning Oct 20, 2023
7732609
some comment changes
absolutelightning Oct 23, 2023
82c0ddb
Merge branch 'NET-5875' of ssh://github.com/hashicorp/consul into NET…
absolutelightning Oct 23, 2023
5308961
removed unused files
absolutelightning Oct 23, 2023
d091b46
fixes
absolutelightning Oct 23, 2023
b4d0247
fix function in file
absolutelightning Oct 23, 2023
e6380c2
caps
absolutelightning Oct 23, 2023
07f3932
Merge branch 'main' into NET-5875
absolutelightning Oct 23, 2023
e2b2052
Merge branch 'NET-5875' of ssh://github.com/hashicorp/consul into NET…
absolutelightning Oct 23, 2023
5f9589e
some positioing
absolutelightning Oct 23, 2023
d51bbdf
added test for validation error
absolutelightning Oct 23, 2023
e84e237
fix names
absolutelightning Oct 23, 2023
1c7efd8
made valid a function
absolutelightning Oct 23, 2023
e2e379b
remvoed patch
absolutelightning Oct 23, 2023
d982a03
Merge branch 'main' into NET-5875
absolutelightning Oct 23, 2023
3aac88d
removed mutations
absolutelightning Oct 23, 2023
678b311
Merge branch 'NET-5875' of ssh://github.com/hashicorp/consul into NET…
absolutelightning Oct 23, 2023
c6ea870
v2 beta1
absolutelightning Oct 23, 2023
999dd6f
v2beta1
absolutelightning Oct 23, 2023
3b37a0a
rmeoved v1alpha1
absolutelightning Oct 23, 2023
732e2ca
validate error
absolutelightning Oct 24, 2023
add5b45
Merge branch 'main' into NET-5875
absolutelightning Oct 24, 2023
cd29bed
Merge branch 'NET-5875' of ssh://github.com/hashicorp/consul into NET…
absolutelightning Oct 24, 2023
11fd797
Merge branch 'main' of ssh://github.com/hashicorp/consul into NET-5875
absolutelightning Oct 25, 2023
a11ad98
merge ent
absolutelightning Oct 25, 2023
d5a4ccc
some nits
absolutelightning Oct 26, 2023
a837887
Merge branch 'main' into NET-5875
absolutelightning Oct 26, 2023
00984f1
removed dup func
absolutelightning Oct 26, 2023
5407a04
Merge branch 'NET-5875' of ssh://github.com/hashicorp/consul into NET…
absolutelightning Oct 26, 2023
4f963f0
removed nil check
absolutelightning Oct 26, 2023
b15d668
Merge branch 'main' into NET-5875
absolutelightning Oct 26, 2023
d1892da
Merge branch 'NET-5875' of ssh://github.com/hashicorp/consul into NET…
absolutelightning Oct 26, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions agent/consul/type_registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"github.com/hashicorp/consul/internal/auth"
"github.com/hashicorp/consul/internal/catalog"
"github.com/hashicorp/consul/internal/mesh"
"github.com/hashicorp/consul/internal/multicluster"
"github.com/hashicorp/consul/internal/resource"
"github.com/hashicorp/consul/internal/resource/demo"
"github.com/hashicorp/consul/internal/tenancy"
Expand All @@ -27,6 +28,7 @@ func NewTypeRegistry() resource.Registry {
catalog.RegisterTypes(registry)
auth.RegisterTypes(registry)
tenancy.RegisterTypes(registry)
multicluster.RegisterTypes(registry)

return registry
}
22 changes: 22 additions & 0 deletions internal/multicluster/exports.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1

package multicluster

import (
"github.com/hashicorp/consul/internal/multicluster/internal/types"
"github.com/hashicorp/consul/internal/resource"
)

var (
// API Group Information
APIGroup = types.GroupName
VersionV1Alpha1 = types.VersionV1Alpha1
CurrentVersion = types.CurrentVersion
)

// RegisterTypes adds all resource types within the "multicluster" API group
// to the given type registry
func RegisterTypes(r resource.Registry) {
types.Register(r)
}
44 changes: 44 additions & 0 deletions internal/multicluster/internal/types/computed_exported_services.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1

package types

import (
"github.com/hashicorp/consul/acl"
"github.com/hashicorp/consul/internal/resource"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v1alpha1"
"github.com/hashicorp/consul/proto-public/pbresource"
)

const (
ComputedExportedServicesName = "global"
)

func RegisterComputedExportedServices(r resource.Registry) {
r.Register(resource.Registration{
Type: pbmulticluster.ComputedExportedServicesType,
Proto: &pbmulticluster.ComputedExportedServices{},
Scope: resource.ScopePartition,
Mutate: MutateComputedExportedServices,
Validate: ValidateComputedExportedServices,
ACLs: &resource.ACLHooks{
Read: aclReadHookComputedExportedServices,
Write: aclWriteHookComputedExportedServices,
List: aclListHookComputedExportedServices,
},
})
}

func aclReadHookComputedExportedServices(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, id *pbresource.ID, _ *pbresource.Resource) error {
return authorizer.ToAllowAuthorizer().MeshReadAllowed(authzContext)
}

func aclWriteHookComputedExportedServices(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, res *pbresource.Resource) error {
return authorizer.ToAllowAuthorizer().MeshWriteAllowed(authzContext)
}

func aclListHookComputedExportedServices(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext) error {
// No-op List permission as we want to default to filtering resources
// from the list using the Read enforcement.
return nil
absolutelightning marked this conversation as resolved.
Show resolved Hide resolved
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1

//go:build !consulent
// +build !consulent

package types

import (
multiclusterv1alpha1 "github.com/hashicorp/consul/proto-public/pbmulticluster/v1alpha1"
)

func validComputedExportedServicesWithPeer() *multiclusterv1alpha1.ComputedExportedServices {
consumers := []*multiclusterv1alpha1.ComputedExportedService{
{
Consumers: []*multiclusterv1alpha1.ComputedExportedServicesConsumer{
{
ConsumerTenancy: &multiclusterv1alpha1.ComputedExportedServicesConsumer_Peer{
Peer: "",
},
},
},
},
}
return &multiclusterv1alpha1.ComputedExportedServices{
Consumers: consumers,
}
}

func validComputedExportedServicesWithPartition() *multiclusterv1alpha1.ComputedExportedServices {
consumers := []*multiclusterv1alpha1.ComputedExportedService{
{
Consumers: []*multiclusterv1alpha1.ComputedExportedServicesConsumer{
{
ConsumerTenancy: &multiclusterv1alpha1.ComputedExportedServicesConsumer_Partition{
Partition: "default",
},
},
},
},
}
return &multiclusterv1alpha1.ComputedExportedServices{
Consumers: consumers,
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1

package types

import (
"errors"
"github.com/hashicorp/consul/acl"
"github.com/hashicorp/consul/agent/structs"
"github.com/hashicorp/consul/internal/resource"
"github.com/hashicorp/consul/internal/resource/resourcetest"
multiclusterv1alpha1 "github.com/hashicorp/consul/proto-public/pbmulticluster/v1alpha1"
"github.com/hashicorp/consul/proto-public/pbresource"
"github.com/stretchr/testify/require"
"testing"
)

func TestComputedExportedServicesValidations(t *testing.T) {
type testcase struct {
Resource *pbresource.Resource
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It might simplify things a bit to just specify *multiclusterv1alpha1.ComputedExportedServices here and build out the resource within run.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resourcetest.Resource( returns pbresource.Resource.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, this is more of a nit than anything. Making this change woud result in each test case specifying a computed exported resource and then building the resource similar to the following in run:

resourcetest.Resource(multiclusterv1alpha1.ComputedExportedServicesType, ComputedExportedServicesName).
	WithData(t, tc.resource).
	Build()

}
run := func(t *testing.T, tc testcase) {
err := ValidateComputedExportedServices(tc.Resource)
require.NoError(t, err)
}

cases := map[string]testcase{
"computed exported services with peer": {
Resource: resourcetest.Resource(multiclusterv1alpha1.ComputedExportedServicesType, ComputedExportedServicesName).
WithData(t, validComputedExportedServicesWithPeer()).
Build(),
},
"computed exported services with partition": {
Resource: resourcetest.Resource(multiclusterv1alpha1.ComputedExportedServicesType, ComputedExportedServicesName).
WithData(t, validComputedExportedServicesWithPartition()).
Build(),
},
}

for name, tc := range cases {
t.Run(name, func(t *testing.T) {
run(t, tc)
})
}
}

func TestComputedExportedServicesValidations_InvalidName(t *testing.T) {
res := resourcetest.Resource(multiclusterv1alpha1.ComputedExportedServicesType, "computed-exported-services").
WithData(t, validComputedExportedServicesWithPeer()).
Build()

err := ValidateComputedExportedServices(res)
require.Error(t, err)
expectedError := errors.New("invalid \"name\" field: name can only be \"global\"")
require.ErrorAs(t, err, &expectedError)
}

func TestComputedExportedServicesACLs(t *testing.T) {
// Wire up a registry to generically invoke hooks
registry := resource.NewRegistry()
Register(registry)

type testcase struct {
rules string
check func(t *testing.T, authz acl.Authorizer, res *pbresource.Resource)
readOK string
writeOK string
listOK string
}

const (
DENY = "deny"
ALLOW = "allow"
DEFAULT = "default"
)

checkF := func(t *testing.T, expect string, got error) {
switch expect {
case ALLOW:
if acl.IsErrPermissionDenied(got) {
t.Fatal("should be allowed")
}
case DENY:
if !acl.IsErrPermissionDenied(got) {
t.Fatal("should be denied")
}
case DEFAULT:
require.Nil(t, got, "expected fallthrough decision")
default:
t.Fatalf("unexpected expectation: %q", expect)
}
}

reg, ok := registry.Resolve(multiclusterv1alpha1.ComputedExportedServicesType)
require.True(t, ok)

run := func(t *testing.T, tc testcase) {
exportedServiceData := &multiclusterv1alpha1.ComputedExportedServices{}
res := resourcetest.Resource(multiclusterv1alpha1.ComputedExportedServicesType, "global").
WithData(t, exportedServiceData).
Build()
resourcetest.ValidateAndNormalize(t, registry, res)

config := acl.Config{
WildcardName: structs.WildcardSpecifier,
}
authz, err := acl.NewAuthorizerFromRules(tc.rules, &config, nil)
require.NoError(t, err)
authz = acl.NewChainedAuthorizer([]acl.Authorizer{authz, acl.DenyAll()})

t.Run("read", func(t *testing.T) {
err := reg.ACLs.Read(authz, &acl.AuthorizerContext{}, res.Id, res)
checkF(t, tc.readOK, err)
})
t.Run("write", func(t *testing.T) {
err := reg.ACLs.Write(authz, &acl.AuthorizerContext{}, res)
checkF(t, tc.writeOK, err)
})
t.Run("list", func(t *testing.T) {
err := reg.ACLs.List(authz, &acl.AuthorizerContext{})
checkF(t, tc.listOK, err)
})
}

cases := map[string]testcase{
"no rules": {
rules: ``,
readOK: DENY,
writeOK: DENY,
listOK: DEFAULT,
},
"mesh read policy": {
rules: `mesh = "read"`,
readOK: ALLOW,
writeOK: DENY,
listOK: DEFAULT,
},
"mesh write policy": {
rules: `mesh = "write"`,
readOK: ALLOW,
writeOK: ALLOW,
listOK: ALLOW,
},
}

for name, tc := range cases {
t.Run(name, func(t *testing.T) {
run(t, tc)
})
}
}
62 changes: 62 additions & 0 deletions internal/multicluster/internal/types/exported_services.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1

package types

import (
"github.com/hashicorp/consul/acl"
"github.com/hashicorp/consul/internal/resource"
pbmulticluster "github.com/hashicorp/consul/proto-public/pbmulticluster/v1alpha1"
"github.com/hashicorp/consul/proto-public/pbresource"
)

func RegisterExportedServices(r resource.Registry) {
r.Register(resource.Registration{
Type: pbmulticluster.ExportedServicesType,
Proto: &pbmulticluster.ExportedServices{},
Scope: resource.ScopeNamespace,
Mutate: MutateExportedServices,
Validate: ValidateExportedServices,
ACLs: &resource.ACLHooks{
Read: aclReadHookExportedServices,
Write: aclWriteHookExportedServices,
List: aclListHookExportedServices,
},
})
}

func aclReadHookExportedServices(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, _ *pbresource.ID, res *pbresource.Resource) error {
var exportedService pbmulticluster.ExportedServices
absolutelightning marked this conversation as resolved.
Show resolved Hide resolved

if err := res.Data.UnmarshalTo(&exportedService); err != nil {
return resource.NewErrDataParse(&exportedService, err)
}

for _, serviceName := range exportedService.Services {
if err := authorizer.ToAllowAuthorizer().ServiceReadAllowed(serviceName, authzContext); err != nil {
return err
}
}
return nil
}

func aclWriteHookExportedServices(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext, res *pbresource.Resource) error {
var exportedService pbmulticluster.ExportedServices

if err := res.Data.UnmarshalTo(&exportedService); err != nil {
return resource.NewErrDataParse(&exportedService, err)
}
absolutelightning marked this conversation as resolved.
Show resolved Hide resolved

for _, serviceName := range exportedService.Services {
if err := authorizer.ToAllowAuthorizer().ServiceWriteAllowed(serviceName, authzContext); err != nil {
return err
}
}
return nil
}

func aclListHookExportedServices(authorizer acl.Authorizer, authzContext *acl.AuthorizerContext) error {
// No-op List permission as we want to default to filtering resources
// from the list using the Read enforcement.
return nil
}
Loading
Loading