Skip to content

Commit

Permalink
register traffic permission and workload identity types (#18704)
Browse files Browse the repository at this point in the history
* add workload identity and traffic permission protos

* register new types

* add generated pb code

* fix exports.go path

* add proto newlines

* fix type name

Co-authored-by: Eric Haberkorn <erichaberkorn@gmail.com>

* address review

* fix protos and add tests

* fix validation constraints

* add tests

---------

Co-authored-by: Eric Haberkorn <erichaberkorn@gmail.com>
  • Loading branch information
skpratt and erichaberkorn authored Sep 14, 2023
1 parent d667cc3 commit e5808d8
Show file tree
Hide file tree
Showing 17 changed files with 2,361 additions and 0 deletions.
2 changes: 2 additions & 0 deletions agent/consul/type_registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
package consul

import (
"github.com/hashicorp/consul/internal/auth"
"github.com/hashicorp/consul/internal/catalog"
"github.com/hashicorp/consul/internal/mesh"
"github.com/hashicorp/consul/internal/resource"
Expand All @@ -23,6 +24,7 @@ func NewTypeRegistry() resource.Registry {
demo.RegisterTypes(registry)
mesh.RegisterTypes(registry)
catalog.RegisterTypes(registry)
auth.RegisterTypes(registry)

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

package auth

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

var (
// API Group Information

APIGroup = types.GroupName
VersionV1Alpha1 = types.VersionV1Alpha1
CurrentVersion = types.CurrentVersion

// Resource Kind Names.

WorkloadIdentity = types.WorkloadIdentityKind
TrafficPermissions = types.TrafficPermissionsKind
ComputedTrafficPermissions = types.ComputedTrafficPermissionsKind

// Resource Types for the v1alpha1 version.

WorkloadIdentityV1Alpha1Type = types.WorkloadIdentityV1Alpha1Type
TrafficPermissionsV1Alpha1Type = types.TrafficPermissionsV1Alpha1Type
ComputedTrafficPermissionsV1Alpha1Type = types.ComputedTrafficPermissionsV1Alpha1Type

// Resource Types for the latest version.

WorkloadIdentityType = types.WorkloadIdentityType
TrafficPermissionsType = types.TrafficPermissionsType
ComputedTrafficPermissionsType = types.ComputedTrafficPermissionsType
)

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

package types

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

const (
ComputedTrafficPermissionsKind = "ComputedTrafficPermission"
)

var (
ComputedTrafficPermissionsV1Alpha1Type = &pbresource.Type{
Group: GroupName,
GroupVersion: VersionV1Alpha1,
Kind: ComputedTrafficPermissionsKind,
}

ComputedTrafficPermissionsType = ComputedTrafficPermissionsV1Alpha1Type
)

func RegisterComputedTrafficPermission(r resource.Registry) {
r.Register(resource.Registration{
Type: ComputedTrafficPermissionsV1Alpha1Type,
Proto: &pbauth.ComputedTrafficPermissions{},
Scope: resource.ScopeNamespace,
Validate: nil,
})
}
12 changes: 12 additions & 0 deletions internal/auth/internal/types/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1

package types

import "errors"

var (
errInvalidAction = errors.New("action must be either allow or deny")
errSourcesTenancy = errors.New("permissions sources may not specify partitions, peers, and sameness_groups together")
errInvalidPrefixValues = errors.New("prefix values, regex values, and explicit names must not combined")
)
144 changes: 144 additions & 0 deletions internal/auth/internal/types/traffic_permissions.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1

package types

import (
"github.com/hashicorp/go-multierror"

"github.com/hashicorp/consul/internal/resource"
pbauth "github.com/hashicorp/consul/proto-public/pbauth/v1alpha1"
"github.com/hashicorp/consul/proto-public/pbresource"
)

const (
TrafficPermissionsKind = "TrafficPermissions"
)

var (
TrafficPermissionsV1Alpha1Type = &pbresource.Type{
Group: GroupName,
GroupVersion: VersionV1Alpha1,
Kind: TrafficPermissionsKind,
}

TrafficPermissionsType = TrafficPermissionsV1Alpha1Type
)

func RegisterTrafficPermissions(r resource.Registry) {
r.Register(resource.Registration{
Type: TrafficPermissionsV1Alpha1Type,
Proto: &pbauth.TrafficPermissions{},
Scope: resource.ScopeNamespace,
Validate: ValidateTrafficPermissions,
})
}

func ValidateTrafficPermissions(res *pbresource.Resource) error {
var tp pbauth.TrafficPermissions

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

var err error

if tp.Action == pbauth.Action_ACTION_UNSPECIFIED {
err = multierror.Append(err, resource.ErrInvalidField{
Name: "data.action",
Wrapped: errInvalidAction,
})
}
if tp.Destination == nil || (len(tp.Destination.IdentityName) == 0) {
err = multierror.Append(err, resource.ErrInvalidField{
Name: "data.destination",
Wrapped: resource.ErrEmpty,
})
}
// Validate permissions
for i, permission := range tp.Permissions {
wrapPermissionErr := func(err error) error {
return resource.ErrInvalidListElement{
Name: "permissions",
Index: i,
Wrapped: err,
}
}
for s, src := range permission.Sources {
wrapSrcErr := func(err error) error {
return wrapPermissionErr(resource.ErrInvalidListElement{
Name: "sources",
Index: s,
Wrapped: err,
})
}
if (len(src.Partition) > 0 && len(src.Peer) > 0) ||
(len(src.Partition) > 0 && len(src.SamenessGroup) > 0) ||
(len(src.Peer) > 0 && len(src.SamenessGroup) > 0) {
err = multierror.Append(err, wrapSrcErr(resource.ErrInvalidListElement{
Name: "source",
Wrapped: errSourcesTenancy,
}))
}
if len(src.Exclude) > 0 {
for e, d := range src.Exclude {
wrapExclSrcErr := func(err error) error {
return wrapPermissionErr(resource.ErrInvalidListElement{
Name: "exclude_sources",
Index: e,
Wrapped: err,
})
}
if (len(d.Partition) > 0 && len(d.Peer) > 0) ||
(len(d.Partition) > 0 && len(d.SamenessGroup) > 0) ||
(len(d.Peer) > 0 && len(d.SamenessGroup) > 0) {
err = multierror.Append(err, wrapExclSrcErr(resource.ErrInvalidListElement{
Name: "exclude_source",
Wrapped: errSourcesTenancy,
}))
}
}
}
}
if len(permission.DestinationRules) > 0 {
for d, dest := range permission.DestinationRules {
wrapDestRuleErr := func(err error) error {
return wrapPermissionErr(resource.ErrInvalidListElement{
Name: "destination_rules",
Index: d,
Wrapped: err,
})
}
if (len(dest.PathExact) > 0 && len(dest.PathPrefix) > 0) ||
(len(dest.PathRegex) > 0 && len(dest.PathExact) > 0) ||
(len(dest.PathRegex) > 0 && len(dest.PathPrefix) > 0) {
err = multierror.Append(err, wrapDestRuleErr(resource.ErrInvalidListElement{
Name: "destination_rule",
Wrapped: errInvalidPrefixValues,
}))
}
if len(dest.Exclude) > 0 {
for e, excl := range dest.Exclude {
wrapExclPermRuleErr := func(err error) error {
return wrapPermissionErr(resource.ErrInvalidListElement{
Name: "exclude_permission_rules",
Index: e,
Wrapped: err,
})
}
if (len(excl.PathExact) > 0 && len(excl.PathPrefix) > 0) ||
(len(excl.PathRegex) > 0 && len(excl.PathExact) > 0) ||
(len(excl.PathRegex) > 0 && len(excl.PathPrefix) > 0) {
err = multierror.Append(err, wrapExclPermRuleErr(resource.ErrInvalidListElement{
Name: "exclude_permission_rule",
Wrapped: errInvalidPrefixValues,
}))
}
}
}
}
}
}

return err
}
Loading

0 comments on commit e5808d8

Please sign in to comment.