mirror of https://github.com/status-im/consul.git
v2 explicit destination traffic permissions (#18823)
* workload identity boilerplate * notes from discussion with Iryna * WIP traffic permissions controller poc * workload identity, traffic permissions validation, errors, types * traffic permissions mapper framing, traffic permissions controller updates. * more roughing out of the controller * cleanup * controller and mapper logic * tests * refactor mapper logic, add tests * clean up tenancy and integration test stubs * consolidate mapping * cleanup cache leak, revert bimapper changes * address review comments * test fix and rebase * use resource helper --------- Co-authored-by: John Landa <john.landa@hashicorp.com>
This commit is contained in:
parent
bd2fdb7f7d
commit
202090e5d5
|
@ -4,12 +4,38 @@
|
|||
package auth
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/consul/internal/auth/internal/controllers"
|
||||
"github.com/hashicorp/consul/internal/auth/internal/controllers/trafficpermissions"
|
||||
"github.com/hashicorp/consul/internal/auth/internal/mappers/trafficpermissionsmapper"
|
||||
"github.com/hashicorp/consul/internal/auth/internal/types"
|
||||
"github.com/hashicorp/consul/internal/controller"
|
||||
"github.com/hashicorp/consul/internal/resource"
|
||||
)
|
||||
|
||||
var (
|
||||
// Controller statuses
|
||||
|
||||
StatusKey = trafficpermissions.StatusKey
|
||||
TrafficPermissionsConditionComputed = trafficpermissions.ConditionComputed
|
||||
TrafficPermissionsConditionFailedToCompute = trafficpermissions.ConditionFailedToCompute
|
||||
)
|
||||
|
||||
// RegisterTypes adds all resource types within the "catalog" API group
|
||||
// to the given type registry
|
||||
func RegisterTypes(r resource.Registry) {
|
||||
types.Register(r)
|
||||
}
|
||||
|
||||
type ControllerDependencies = controllers.Dependencies
|
||||
|
||||
func DefaultControllerDependencies() ControllerDependencies {
|
||||
return ControllerDependencies{
|
||||
TrafficPermissionsMapper: trafficpermissionsmapper.New(),
|
||||
}
|
||||
}
|
||||
|
||||
// RegisterControllers registers controllers for the auth types with
|
||||
// the given controller manager.
|
||||
func RegisterControllers(mgr *controller.Manager, deps ControllerDependencies) {
|
||||
controllers.Register(mgr, deps)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/consul/internal/auth/internal/controllers/trafficpermissions"
|
||||
"github.com/hashicorp/consul/internal/controller"
|
||||
)
|
||||
|
||||
type Dependencies struct {
|
||||
TrafficPermissionsMapper trafficpermissions.TrafficPermissionsMapper
|
||||
}
|
||||
|
||||
func Register(mgr *controller.Manager, deps Dependencies) {
|
||||
mgr.Register(trafficpermissions.Controller(deps.TrafficPermissionsMapper))
|
||||
}
|
|
@ -0,0 +1,189 @@
|
|||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package trafficpermissions
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"google.golang.org/protobuf/proto"
|
||||
"google.golang.org/protobuf/types/known/anypb"
|
||||
|
||||
"github.com/hashicorp/consul/internal/controller"
|
||||
"github.com/hashicorp/consul/internal/resource"
|
||||
pbauth "github.com/hashicorp/consul/proto-public/pbauth/v2beta1"
|
||||
"github.com/hashicorp/consul/proto-public/pbresource"
|
||||
)
|
||||
|
||||
// TrafficPermissionsMapper is used to map a watch event for a TrafficPermissions resource and translate
|
||||
// it to a ComputedTrafficPermissions resource which contains the effective permissions
|
||||
// from all referencing TrafficPermissions resources.
|
||||
type TrafficPermissionsMapper interface {
|
||||
// MapTrafficPermissions will take a TrafficPermission resource and return controller requests for all
|
||||
// ComputedTrafficPermissions associated with that TrafficPermission.
|
||||
MapTrafficPermissions(context.Context, controller.Runtime, *pbresource.Resource) ([]controller.Request, error)
|
||||
|
||||
// UntrackTrafficPermissions instructs the Mapper to forget about the TrafficPermission.
|
||||
UntrackTrafficPermissions(*pbresource.ID)
|
||||
|
||||
// GetTrafficPermissionsForCTP returns the tracked TrafficPermissions that are used to create a CTP
|
||||
GetTrafficPermissionsForCTP(*pbresource.ID) []*pbresource.Reference
|
||||
}
|
||||
|
||||
// Controller creates a controller for automatic ComputedTrafficPermissions management for
|
||||
// updates to WorkloadIdentity or TrafficPermission resources.
|
||||
func Controller(mapper TrafficPermissionsMapper) controller.Controller {
|
||||
if mapper == nil {
|
||||
panic("No TrafficPermissionsMapper was provided to the TrafficPermissionsController constructor")
|
||||
}
|
||||
|
||||
return controller.ForType(pbauth.ComputedTrafficPermissionsType).
|
||||
WithWatch(pbauth.WorkloadIdentityType, controller.ReplaceType(pbauth.ComputedTrafficPermissionsType)).
|
||||
WithWatch(pbauth.TrafficPermissionsType, mapper.MapTrafficPermissions).
|
||||
WithReconciler(&reconciler{mapper: mapper})
|
||||
}
|
||||
|
||||
type reconciler struct {
|
||||
mapper TrafficPermissionsMapper
|
||||
}
|
||||
|
||||
// Reconcile will reconcile one ComputedTrafficPermission (CTP) in response to some event.
|
||||
// Events include adding, modifying or deleting a WorkloadIdentity or TrafficPermission.
|
||||
func (r *reconciler) Reconcile(ctx context.Context, rt controller.Runtime, req controller.Request) error {
|
||||
rt.Logger = rt.Logger.With("resource-id", req.ID, "controller", StatusKey)
|
||||
/*
|
||||
* A CTP ID could come in for a variety of reasons.
|
||||
* 1. workload identity create / delete: this results in the creation / deletion of a new CTP
|
||||
* 2. traffic permission create / modify / delete: this results in a potential modification of an existing CTP
|
||||
*
|
||||
* Part 1: Handle Workload Identity changes:
|
||||
* Check if the workload identity exists. If it doesn't we can stop here.
|
||||
* CTPs are always generated from WorkloadIdentities, therefore the WI resource must already exist.
|
||||
* If it is missing, that means it was deleted.
|
||||
*/
|
||||
ctpID := req.ID
|
||||
wi := resource.ReplaceType(pbauth.WorkloadIdentityType, ctpID)
|
||||
workloadIdentity, err := resource.GetDecodedResource[*pbauth.WorkloadIdentity](ctx, rt.Client, wi)
|
||||
if err != nil {
|
||||
rt.Logger.Error("error retrieving corresponding Workload Identity", "error", err)
|
||||
return err
|
||||
}
|
||||
if workloadIdentity == nil || workloadIdentity.Resource == nil {
|
||||
rt.Logger.Trace("workload identity has been deleted")
|
||||
return nil
|
||||
}
|
||||
|
||||
// Check if CTP exists:
|
||||
oldCTPData, err := resource.GetDecodedResource[*pbauth.ComputedTrafficPermissions](ctx, rt.Client, ctpID)
|
||||
if err != nil {
|
||||
rt.Logger.Error("error retrieving computed permissions", "error", err)
|
||||
return err
|
||||
}
|
||||
var oldResource *pbresource.Resource
|
||||
var owner *pbresource.ID
|
||||
if oldCTPData == nil {
|
||||
// CTP does not yet exist, so we need to make a new one
|
||||
rt.Logger.Trace("creating new computed traffic permissions for workload identity")
|
||||
owner = workloadIdentity.Resource.Id
|
||||
} else {
|
||||
oldResource = oldCTPData.Resource
|
||||
owner = oldCTPData.Resource.Owner
|
||||
}
|
||||
|
||||
// Part 2: Recompute a CTP from TP create / modify / delete, or create a new CTP from existing TPs:
|
||||
latestTrafficPermissions, err := computeNewTrafficPermissions(ctx, rt, r.mapper, ctpID, oldResource)
|
||||
if err != nil {
|
||||
rt.Logger.Error("error calculating computed permissions", "error", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if oldCTPData != nil && proto.Equal(oldCTPData.Data, latestTrafficPermissions) {
|
||||
// there are no changes to the computed traffic permissions, and we can return early
|
||||
rt.Logger.Trace("no new computed traffic permissions")
|
||||
return nil
|
||||
}
|
||||
newCTPData, err := anypb.New(latestTrafficPermissions)
|
||||
if err != nil {
|
||||
rt.Logger.Error("error marshalling latest traffic permissions", "error", err)
|
||||
writeFailedStatus(ctx, rt, oldResource, nil, err.Error())
|
||||
return err
|
||||
}
|
||||
rt.Logger.Trace("writing computed traffic permissions")
|
||||
rsp, err := rt.Client.Write(ctx, &pbresource.WriteRequest{
|
||||
Resource: &pbresource.Resource{
|
||||
Id: req.ID,
|
||||
Data: newCTPData,
|
||||
Owner: owner,
|
||||
},
|
||||
})
|
||||
if err != nil || rsp.Resource == nil {
|
||||
rt.Logger.Error("error writing new computed traffic permissions", "error", err)
|
||||
writeFailedStatus(ctx, rt, oldResource, nil, err.Error())
|
||||
return err
|
||||
} else {
|
||||
rt.Logger.Trace("new computed traffic permissions were successfully written")
|
||||
}
|
||||
newStatus := &pbresource.Status{
|
||||
ObservedGeneration: rsp.Resource.Generation,
|
||||
Conditions: []*pbresource.Condition{
|
||||
ConditionComputed(req.ID.Name),
|
||||
},
|
||||
}
|
||||
_, err = rt.Client.WriteStatus(ctx, &pbresource.WriteStatusRequest{
|
||||
Id: rsp.Resource.Id,
|
||||
Key: StatusKey,
|
||||
Status: newStatus,
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
func writeFailedStatus(ctx context.Context, rt controller.Runtime, ctp *pbresource.Resource, tp *pbresource.ID, errDetail string) error {
|
||||
if ctp == nil {
|
||||
return nil
|
||||
}
|
||||
newStatus := &pbresource.Status{
|
||||
ObservedGeneration: ctp.Generation,
|
||||
Conditions: []*pbresource.Condition{
|
||||
ConditionFailedToCompute(ctp.Id.Name, tp.Name, errDetail),
|
||||
},
|
||||
}
|
||||
_, err := rt.Client.WriteStatus(ctx, &pbresource.WriteStatusRequest{
|
||||
Id: ctp.Id,
|
||||
Key: StatusKey,
|
||||
Status: newStatus,
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
// computeNewTrafficPermissions will use all associated Traffic Permissions to create new ComputedTrafficPermissions data
|
||||
func computeNewTrafficPermissions(ctx context.Context, rt controller.Runtime, wm TrafficPermissionsMapper, ctpID *pbresource.ID, ctp *pbresource.Resource) (*pbauth.ComputedTrafficPermissions, error) {
|
||||
// Part 1: Get all TPs that apply to workload identity
|
||||
// Get already associated WorkloadIdentities/CTPs for reconcile requests:
|
||||
trackedTPs := wm.GetTrafficPermissionsForCTP(ctpID)
|
||||
if len(trackedTPs) > 0 {
|
||||
rt.Logger.Trace("got tracked traffic permissions for CTP", "tps:", trackedTPs)
|
||||
} else {
|
||||
rt.Logger.Trace("found no tracked traffic permissions for CTP")
|
||||
}
|
||||
ap := make([]*pbauth.Permission, 0)
|
||||
dp := make([]*pbauth.Permission, 0)
|
||||
for _, t := range trackedTPs {
|
||||
rsp, err := resource.GetDecodedResource[*pbauth.TrafficPermissions](ctx, rt.Client, resource.IDFromReference(t))
|
||||
if err != nil {
|
||||
rt.Logger.Error("error reading traffic permissions resource for computation", "error", err)
|
||||
writeFailedStatus(ctx, rt, ctp, resource.IDFromReference(t), err.Error())
|
||||
return nil, err
|
||||
}
|
||||
if rsp == nil {
|
||||
rt.Logger.Trace("untracking deleted TrafficPermissions", "traffic-permissions-name", t.Name)
|
||||
wm.UntrackTrafficPermissions(resource.IDFromReference(t))
|
||||
continue
|
||||
}
|
||||
if rsp.Data.Action == pbauth.Action_ACTION_ALLOW {
|
||||
ap = append(ap, rsp.Data.Permissions...)
|
||||
} else {
|
||||
dp = append(dp, rsp.Data.Permissions...)
|
||||
}
|
||||
}
|
||||
return &pbauth.ComputedTrafficPermissions{AllowPermissions: ap, DenyPermissions: dp}, nil
|
||||
}
|
|
@ -0,0 +1,617 @@
|
|||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package trafficpermissions
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
svctest "github.com/hashicorp/consul/agent/grpc-external/services/resource/testing"
|
||||
"github.com/hashicorp/consul/internal/auth/internal/mappers/trafficpermissionsmapper"
|
||||
"github.com/hashicorp/consul/internal/auth/internal/types"
|
||||
"github.com/hashicorp/consul/internal/controller"
|
||||
"github.com/hashicorp/consul/internal/resource"
|
||||
rtest "github.com/hashicorp/consul/internal/resource/resourcetest"
|
||||
pbauth "github.com/hashicorp/consul/proto-public/pbauth/v2beta1"
|
||||
"github.com/hashicorp/consul/proto-public/pbresource"
|
||||
"github.com/hashicorp/consul/proto/private/prototest"
|
||||
"github.com/hashicorp/consul/sdk/testutil"
|
||||
)
|
||||
|
||||
type controllerSuite struct {
|
||||
suite.Suite
|
||||
ctx context.Context
|
||||
client *rtest.Client
|
||||
rt controller.Runtime
|
||||
|
||||
mapper *trafficpermissionsmapper.TrafficPermissionsMapper
|
||||
reconciler *reconciler
|
||||
}
|
||||
|
||||
func (suite *controllerSuite) SetupTest() {
|
||||
suite.ctx = testutil.TestContext(suite.T())
|
||||
client := svctest.RunResourceService(suite.T(), types.Register)
|
||||
suite.client = rtest.NewClient(client)
|
||||
suite.rt = controller.Runtime{
|
||||
Client: suite.client,
|
||||
Logger: testutil.Logger(suite.T()),
|
||||
}
|
||||
suite.mapper = trafficpermissionsmapper.New()
|
||||
suite.reconciler = &reconciler{mapper: suite.mapper}
|
||||
}
|
||||
|
||||
func (suite *controllerSuite) requireTrafficPermissionsTracking(tp *pbresource.Resource, ids ...*pbresource.ID) {
|
||||
reqs, err := suite.mapper.MapTrafficPermissions(suite.ctx, suite.rt, tp)
|
||||
require.NoError(suite.T(), err)
|
||||
require.Len(suite.T(), reqs, len(ids))
|
||||
for _, id := range ids {
|
||||
prototest.AssertContainsElement(suite.T(), reqs, controller.Request{ID: id})
|
||||
}
|
||||
for _, req := range reqs {
|
||||
prototest.AssertContainsElement(suite.T(), ids, req.ID)
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *controllerSuite) requireCTP(resource *pbresource.Resource, allowExpected []*pbauth.Permission, denyExpected []*pbauth.Permission) {
|
||||
var ctp pbauth.ComputedTrafficPermissions
|
||||
require.NoError(suite.T(), resource.Data.UnmarshalTo(&ctp))
|
||||
require.Len(suite.T(), ctp.AllowPermissions, len(allowExpected))
|
||||
require.Len(suite.T(), ctp.DenyPermissions, len(denyExpected))
|
||||
prototest.AssertElementsMatch(suite.T(), allowExpected, ctp.AllowPermissions)
|
||||
prototest.AssertElementsMatch(suite.T(), denyExpected, ctp.DenyPermissions)
|
||||
}
|
||||
|
||||
func (suite *controllerSuite) TestReconcile_CTPCreate_NoReferencingTrafficPermissionsExist() {
|
||||
wi := rtest.Resource(pbauth.WorkloadIdentityType, "wi1").Write(suite.T(), suite.client)
|
||||
require.NotNil(suite.T(), wi)
|
||||
id := rtest.Resource(pbauth.ComputedTrafficPermissionsType, wi.Id.Name).WithTenancy(resource.DefaultNamespacedTenancy()).WithOwner(wi.Id).ID()
|
||||
require.NotNil(suite.T(), id)
|
||||
|
||||
err := suite.reconciler.Reconcile(suite.ctx, suite.rt, controller.Request{ID: id})
|
||||
require.NoError(suite.T(), err)
|
||||
|
||||
// Ensure that the CTP was created
|
||||
ctp := suite.client.RequireResourceExists(suite.T(), id)
|
||||
suite.requireCTP(ctp, []*pbauth.Permission{}, []*pbauth.Permission{})
|
||||
}
|
||||
|
||||
func (suite *controllerSuite) TestReconcile_CTPCreate_ReferencingTrafficPermissionsExist() {
|
||||
// create dead-end traffic permissions
|
||||
p1 := &pbauth.Permission{}
|
||||
tp1 := rtest.Resource(pbauth.TrafficPermissionsType, "tp1").WithData(suite.T(), &pbauth.TrafficPermissions{
|
||||
Destination: &pbauth.Destination{
|
||||
IdentityName: "wi1",
|
||||
},
|
||||
Action: pbauth.Action_ACTION_DENY,
|
||||
Permissions: []*pbauth.Permission{p1},
|
||||
}).Write(suite.T(), suite.client)
|
||||
wi1ID := &pbresource.ID{
|
||||
Name: "wi1",
|
||||
Type: pbauth.ComputedTrafficPermissionsType,
|
||||
Tenancy: tp1.Id.Tenancy,
|
||||
}
|
||||
suite.requireTrafficPermissionsTracking(tp1, wi1ID)
|
||||
p2 := &pbauth.Permission{
|
||||
Sources: []*pbauth.Source{
|
||||
{
|
||||
IdentityName: "wi2",
|
||||
Namespace: "default",
|
||||
Partition: "default",
|
||||
Peer: "local",
|
||||
}},
|
||||
}
|
||||
tp2 := rtest.Resource(pbauth.TrafficPermissionsType, "tp2").WithData(suite.T(), &pbauth.TrafficPermissions{
|
||||
Destination: &pbauth.Destination{
|
||||
IdentityName: "wi1",
|
||||
},
|
||||
Action: pbauth.Action_ACTION_ALLOW,
|
||||
Permissions: []*pbauth.Permission{p2},
|
||||
}).Write(suite.T(), suite.client)
|
||||
suite.requireTrafficPermissionsTracking(tp2, wi1ID)
|
||||
|
||||
// create the workload identity that they reference
|
||||
wi := rtest.Resource(pbauth.WorkloadIdentityType, "wi1").Write(suite.T(), suite.client)
|
||||
id := rtest.Resource(pbauth.ComputedTrafficPermissionsType, wi.Id.Name).WithTenancy(resource.DefaultNamespacedTenancy()).WithOwner(wi.Id).ID()
|
||||
|
||||
err := suite.reconciler.Reconcile(suite.ctx, suite.rt, controller.Request{ID: id})
|
||||
require.NoError(suite.T(), err)
|
||||
|
||||
// Ensure that the CTP was created
|
||||
ctp := suite.client.RequireResourceExists(suite.T(), id)
|
||||
suite.requireCTP(ctp, []*pbauth.Permission{p2}, []*pbauth.Permission{p1})
|
||||
rtest.RequireOwner(suite.T(), ctp, wi.Id, true)
|
||||
}
|
||||
|
||||
func (suite *controllerSuite) TestReconcile_WorkloadIdentityDelete_ReferencingTrafficPermissionsExist() {
|
||||
p1 := &pbauth.Permission{}
|
||||
tp1 := rtest.Resource(pbauth.TrafficPermissionsType, "tp1").WithData(suite.T(), &pbauth.TrafficPermissions{
|
||||
Destination: &pbauth.Destination{
|
||||
IdentityName: "wi1",
|
||||
},
|
||||
Action: pbauth.Action_ACTION_DENY,
|
||||
Permissions: []*pbauth.Permission{p1},
|
||||
}).Write(suite.T(), suite.client)
|
||||
wi1ID := &pbresource.ID{
|
||||
Name: "wi1",
|
||||
Type: pbauth.ComputedTrafficPermissionsType,
|
||||
Tenancy: tp1.Id.Tenancy,
|
||||
}
|
||||
suite.requireTrafficPermissionsTracking(tp1, wi1ID)
|
||||
p2 := &pbauth.Permission{
|
||||
Sources: []*pbauth.Source{
|
||||
{
|
||||
IdentityName: "wi2",
|
||||
Namespace: "default",
|
||||
Partition: "default",
|
||||
Peer: "local",
|
||||
}},
|
||||
}
|
||||
tp2 := rtest.Resource(pbauth.TrafficPermissionsType, "tp2").WithData(suite.T(), &pbauth.TrafficPermissions{
|
||||
Destination: &pbauth.Destination{
|
||||
IdentityName: "wi1",
|
||||
},
|
||||
Action: pbauth.Action_ACTION_ALLOW,
|
||||
Permissions: []*pbauth.Permission{p2},
|
||||
}).Write(suite.T(), suite.client)
|
||||
suite.requireTrafficPermissionsTracking(tp2, wi1ID)
|
||||
|
||||
// create the workload identity that they reference
|
||||
wi := rtest.Resource(pbauth.WorkloadIdentityType, "wi1").Write(suite.T(), suite.client)
|
||||
id := rtest.Resource(pbauth.ComputedTrafficPermissionsType, wi.Id.Name).WithTenancy(resource.DefaultNamespacedTenancy()).WithOwner(wi.Id).ID()
|
||||
|
||||
err := suite.reconciler.Reconcile(suite.ctx, suite.rt, controller.Request{ID: id})
|
||||
require.NoError(suite.T(), err)
|
||||
|
||||
// delete the workload identity
|
||||
suite.client.MustDelete(suite.T(), wi.Id)
|
||||
|
||||
// re-reconcile: should untrack the CTP
|
||||
err = suite.reconciler.Reconcile(suite.ctx, suite.rt, controller.Request{ID: id})
|
||||
require.NoError(suite.T(), err)
|
||||
}
|
||||
|
||||
func (suite *controllerSuite) TestReconcile_WorkloadIdentityDelete_NoReferencingTrafficPermissionsExist() {
|
||||
// create the workload identity that they reference
|
||||
wi := rtest.Resource(pbauth.WorkloadIdentityType, "wi1").Write(suite.T(), suite.client)
|
||||
id := rtest.Resource(pbauth.ComputedTrafficPermissionsType, wi.Id.Name).WithTenancy(resource.DefaultNamespacedTenancy()).WithOwner(wi.Id).ID()
|
||||
|
||||
err := suite.reconciler.Reconcile(suite.ctx, suite.rt, controller.Request{ID: id})
|
||||
require.NoError(suite.T(), err)
|
||||
|
||||
// delete the workload identity
|
||||
suite.client.MustDelete(suite.T(), wi.Id)
|
||||
|
||||
// re-reconcile: should untrack the CTP
|
||||
err = suite.reconciler.Reconcile(suite.ctx, suite.rt, controller.Request{ID: id})
|
||||
require.NoError(suite.T(), err)
|
||||
|
||||
// there should not be any traffic permissions to compute
|
||||
tps := suite.mapper.GetTrafficPermissionsForCTP(id)
|
||||
require.Len(suite.T(), tps, 0)
|
||||
}
|
||||
|
||||
func (suite *controllerSuite) TestReconcile_TrafficPermissionsCreate_DestinationWorkloadIdentityExists() {
|
||||
// create the workload identity to be referenced
|
||||
wi := rtest.Resource(pbauth.WorkloadIdentityType, "wi1").Write(suite.T(), suite.client)
|
||||
id := rtest.Resource(pbauth.ComputedTrafficPermissionsType, wi.Id.Name).WithTenancy(resource.DefaultNamespacedTenancy()).WithOwner(wi.Id).ID()
|
||||
|
||||
err := suite.reconciler.Reconcile(suite.ctx, suite.rt, controller.Request{ID: id})
|
||||
require.NoError(suite.T(), err)
|
||||
|
||||
// create traffic permissions
|
||||
p1 := &pbauth.Permission{}
|
||||
tp1 := rtest.Resource(pbauth.TrafficPermissionsType, "tp1").WithData(suite.T(), &pbauth.TrafficPermissions{
|
||||
Destination: &pbauth.Destination{
|
||||
IdentityName: "wi1",
|
||||
},
|
||||
Action: pbauth.Action_ACTION_DENY,
|
||||
Permissions: []*pbauth.Permission{p1},
|
||||
}).Write(suite.T(), suite.client)
|
||||
suite.requireTrafficPermissionsTracking(tp1, id)
|
||||
p2 := &pbauth.Permission{
|
||||
Sources: []*pbauth.Source{
|
||||
{
|
||||
IdentityName: "wi2",
|
||||
Namespace: "default",
|
||||
Partition: "default",
|
||||
Peer: "local",
|
||||
}},
|
||||
}
|
||||
tp2 := rtest.Resource(pbauth.TrafficPermissionsType, "tp2").WithData(suite.T(), &pbauth.TrafficPermissions{
|
||||
Destination: &pbauth.Destination{
|
||||
IdentityName: "wi1",
|
||||
},
|
||||
Action: pbauth.Action_ACTION_ALLOW,
|
||||
Permissions: []*pbauth.Permission{p2},
|
||||
}).Write(suite.T(), suite.client)
|
||||
suite.requireTrafficPermissionsTracking(tp2, id)
|
||||
|
||||
err = suite.reconciler.Reconcile(suite.ctx, suite.rt, controller.Request{ID: id})
|
||||
require.NoError(suite.T(), err)
|
||||
|
||||
// Ensure that the CTP was updated
|
||||
ctp := suite.client.RequireResourceExists(suite.T(), id)
|
||||
suite.requireCTP(ctp, []*pbauth.Permission{p2}, []*pbauth.Permission{p1})
|
||||
rtest.RequireOwner(suite.T(), ctp, wi.Id, true)
|
||||
|
||||
// Add another TP
|
||||
p3 := &pbauth.Permission{
|
||||
Sources: []*pbauth.Source{
|
||||
{
|
||||
IdentityName: "wi3",
|
||||
Namespace: "default",
|
||||
Partition: "default",
|
||||
Peer: "local",
|
||||
}},
|
||||
}
|
||||
tp3 := rtest.Resource(pbauth.TrafficPermissionsType, "tp3").WithData(suite.T(), &pbauth.TrafficPermissions{
|
||||
Destination: &pbauth.Destination{
|
||||
IdentityName: "wi1",
|
||||
},
|
||||
Action: pbauth.Action_ACTION_DENY,
|
||||
Permissions: []*pbauth.Permission{p3},
|
||||
}).Write(suite.T(), suite.client)
|
||||
suite.requireTrafficPermissionsTracking(tp3, id)
|
||||
|
||||
err = suite.reconciler.Reconcile(suite.ctx, suite.rt, controller.Request{ID: id})
|
||||
require.NoError(suite.T(), err)
|
||||
|
||||
// Ensure that the CTP was updated
|
||||
ctp = suite.client.RequireResourceExists(suite.T(), id)
|
||||
suite.requireCTP(ctp, []*pbauth.Permission{p2}, []*pbauth.Permission{p1, p3})
|
||||
rtest.RequireOwner(suite.T(), ctp, wi.Id, true)
|
||||
}
|
||||
|
||||
func (suite *controllerSuite) TestReconcile_TrafficPermissionsDelete_DestinationWorkloadIdentityExists() {
|
||||
// create the workload identity to be referenced
|
||||
wi := rtest.Resource(pbauth.WorkloadIdentityType, "wi1").Write(suite.T(), suite.client)
|
||||
id := rtest.Resource(pbauth.ComputedTrafficPermissionsType, wi.Id.Name).WithTenancy(resource.DefaultNamespacedTenancy()).WithOwner(wi.Id).ID()
|
||||
|
||||
err := suite.reconciler.Reconcile(suite.ctx, suite.rt, controller.Request{ID: id})
|
||||
require.NoError(suite.T(), err)
|
||||
|
||||
// create traffic permissions
|
||||
p1 := &pbauth.Permission{}
|
||||
tp1 := rtest.Resource(pbauth.TrafficPermissionsType, "tp1").WithData(suite.T(), &pbauth.TrafficPermissions{
|
||||
Destination: &pbauth.Destination{
|
||||
IdentityName: "wi1",
|
||||
},
|
||||
Action: pbauth.Action_ACTION_DENY,
|
||||
Permissions: []*pbauth.Permission{p1},
|
||||
}).Write(suite.T(), suite.client)
|
||||
suite.requireTrafficPermissionsTracking(tp1, id)
|
||||
p2 := &pbauth.Permission{
|
||||
Sources: []*pbauth.Source{
|
||||
{
|
||||
IdentityName: "wi2",
|
||||
Namespace: "default",
|
||||
Partition: "default",
|
||||
Peer: "local",
|
||||
}},
|
||||
}
|
||||
tp2 := rtest.Resource(pbauth.TrafficPermissionsType, "tp2").WithData(suite.T(), &pbauth.TrafficPermissions{
|
||||
Destination: &pbauth.Destination{
|
||||
IdentityName: "wi1",
|
||||
},
|
||||
Action: pbauth.Action_ACTION_ALLOW,
|
||||
Permissions: []*pbauth.Permission{p2},
|
||||
}).Write(suite.T(), suite.client)
|
||||
suite.requireTrafficPermissionsTracking(tp2, id)
|
||||
|
||||
err = suite.reconciler.Reconcile(suite.ctx, suite.rt, controller.Request{ID: id})
|
||||
require.NoError(suite.T(), err)
|
||||
|
||||
ctp := suite.client.RequireResourceExists(suite.T(), id)
|
||||
suite.requireCTP(ctp, []*pbauth.Permission{p2}, []*pbauth.Permission{p1})
|
||||
rtest.RequireOwner(suite.T(), ctp, wi.Id, true)
|
||||
|
||||
// Delete TP2
|
||||
suite.client.MustDelete(suite.T(), tp2.Id)
|
||||
|
||||
err = suite.reconciler.Reconcile(suite.ctx, suite.rt, controller.Request{ID: id})
|
||||
require.NoError(suite.T(), err)
|
||||
|
||||
// Ensure that the CTP was updated
|
||||
ctp = suite.client.RequireResourceExists(suite.T(), id)
|
||||
suite.requireCTP(ctp, []*pbauth.Permission{}, []*pbauth.Permission{p1})
|
||||
|
||||
// Ensure TP2 is untracked
|
||||
newTps := suite.mapper.GetTrafficPermissionsForCTP(ctp.Id)
|
||||
require.Len(suite.T(), newTps, 1)
|
||||
require.Equal(suite.T(), newTps[0].Name, tp1.Id.Name)
|
||||
}
|
||||
|
||||
func (suite *controllerSuite) TestReconcile_TrafficPermissionsDelete_DestinationWorkloadIdentityDoesNotExist() {
|
||||
// create traffic permissions
|
||||
p1 := &pbauth.Permission{}
|
||||
tp1 := rtest.Resource(pbauth.TrafficPermissionsType, "tp1").WithData(suite.T(), &pbauth.TrafficPermissions{
|
||||
Destination: &pbauth.Destination{
|
||||
IdentityName: "wi1",
|
||||
},
|
||||
Action: pbauth.Action_ACTION_DENY,
|
||||
Permissions: []*pbauth.Permission{p1},
|
||||
}).Write(suite.T(), suite.client)
|
||||
wi1ID := &pbresource.ID{
|
||||
Name: "wi1",
|
||||
Type: pbauth.ComputedTrafficPermissionsType,
|
||||
Tenancy: tp1.Id.Tenancy,
|
||||
}
|
||||
suite.requireTrafficPermissionsTracking(tp1, wi1ID)
|
||||
p2 := &pbauth.Permission{
|
||||
Sources: []*pbauth.Source{
|
||||
{
|
||||
IdentityName: "wi2",
|
||||
Namespace: "default",
|
||||
Partition: "default",
|
||||
Peer: "local",
|
||||
}},
|
||||
}
|
||||
tp2 := rtest.Resource(pbauth.TrafficPermissionsType, "tp2").WithData(suite.T(), &pbauth.TrafficPermissions{
|
||||
Destination: &pbauth.Destination{
|
||||
IdentityName: "wi1",
|
||||
},
|
||||
Action: pbauth.Action_ACTION_ALLOW,
|
||||
Permissions: []*pbauth.Permission{p2},
|
||||
}).Write(suite.T(), suite.client)
|
||||
suite.requireTrafficPermissionsTracking(tp2, wi1ID)
|
||||
|
||||
// Delete TP2
|
||||
suite.client.MustDelete(suite.T(), tp2.Id)
|
||||
|
||||
// Ensure that no CTPs exist
|
||||
rsp, err := suite.client.List(suite.ctx, &pbresource.ListRequest{
|
||||
Type: pbauth.ComputedTrafficPermissionsType,
|
||||
Tenancy: resource.DefaultNamespacedTenancy(),
|
||||
})
|
||||
require.NoError(suite.T(), err)
|
||||
require.Empty(suite.T(), rsp.Resources)
|
||||
}
|
||||
|
||||
func (suite *controllerSuite) TestControllerBasic() {
|
||||
// TODO: refactor this
|
||||
// In this test we check basic operations for a workload identity and referencing traffic permission
|
||||
mgr := controller.NewManager(suite.client, suite.rt.Logger)
|
||||
mgr.Register(Controller(suite.mapper))
|
||||
mgr.SetRaftLeader(true)
|
||||
go mgr.Run(suite.ctx)
|
||||
|
||||
// Add a workload identity
|
||||
workloadIdentity := rtest.Resource(pbauth.WorkloadIdentityType, "wi1").Write(suite.T(), suite.client)
|
||||
|
||||
// Wait for the controller to record that the CTP has been computed
|
||||
res := suite.client.WaitForReconciliation(suite.T(), resource.ReplaceType(pbauth.ComputedTrafficPermissionsType, workloadIdentity.Id), StatusKey)
|
||||
// Check that the status was updated
|
||||
rtest.RequireStatusCondition(suite.T(), res, StatusKey, ConditionComputed("wi1"))
|
||||
|
||||
// Check that the CTP resource exists and contains no permissions
|
||||
ctpID := rtest.Resource(pbauth.ComputedTrafficPermissionsType, "wi1").ID()
|
||||
ctpObject := suite.client.RequireResourceExists(suite.T(), ctpID)
|
||||
suite.requireCTP(ctpObject, nil, nil)
|
||||
|
||||
// add a traffic permission that references wi1
|
||||
p1 := &pbauth.Permission{
|
||||
Sources: []*pbauth.Source{{
|
||||
IdentityName: "wi2",
|
||||
Namespace: "default",
|
||||
Partition: "default",
|
||||
Peer: "local",
|
||||
}},
|
||||
DestinationRules: nil,
|
||||
}
|
||||
tp1 := rtest.Resource(pbauth.TrafficPermissionsType, "tp1").WithData(suite.T(), &pbauth.TrafficPermissions{
|
||||
Destination: &pbauth.Destination{IdentityName: "wi1"},
|
||||
Action: pbauth.Action_ACTION_ALLOW,
|
||||
Permissions: []*pbauth.Permission{p1},
|
||||
}).Write(suite.T(), suite.client)
|
||||
suite.client.RequireResourceExists(suite.T(), tp1.Id)
|
||||
// Wait for the controller to record that the CTP has been re-computed
|
||||
res = suite.client.WaitForReconciliation(suite.T(), resource.ReplaceType(pbauth.ComputedTrafficPermissionsType, workloadIdentity.Id), StatusKey)
|
||||
rtest.RequireStatusCondition(suite.T(), res, StatusKey, ConditionComputed("wi1"))
|
||||
// Check that the ctp has been regenerated
|
||||
ctpObject = suite.client.WaitForNewVersion(suite.T(), ctpID, ctpObject.Version)
|
||||
// check wi1
|
||||
suite.requireCTP(ctpObject, []*pbauth.Permission{p1}, nil)
|
||||
|
||||
// add a traffic permission that references wi2
|
||||
p2 := &pbauth.Permission{
|
||||
Sources: []*pbauth.Source{{
|
||||
IdentityName: "wi1",
|
||||
Namespace: "default",
|
||||
Partition: "default",
|
||||
Peer: "local",
|
||||
}},
|
||||
DestinationRules: nil,
|
||||
}
|
||||
tp2 := rtest.Resource(pbauth.TrafficPermissionsType, "tp2").WithData(suite.T(), &pbauth.TrafficPermissions{
|
||||
Destination: &pbauth.Destination{IdentityName: "wi2"},
|
||||
Action: pbauth.Action_ACTION_ALLOW,
|
||||
Permissions: []*pbauth.Permission{p2},
|
||||
}).Write(suite.T(), suite.client)
|
||||
suite.client.RequireResourceExists(suite.T(), tp2.Id)
|
||||
// check wi1 is the same
|
||||
ctpObject = suite.client.RequireResourceExists(suite.T(), ctpID)
|
||||
suite.requireCTP(ctpObject, []*pbauth.Permission{p1}, nil)
|
||||
// check no ctp2
|
||||
ctpID2 := rtest.Resource(pbauth.ComputedTrafficPermissionsType, "wi2").ID()
|
||||
suite.client.RequireResourceNotFound(suite.T(), ctpID2)
|
||||
|
||||
// delete tp1
|
||||
suite.client.MustDelete(suite.T(), tp1.Id)
|
||||
suite.client.WaitForDeletion(suite.T(), tp1.Id)
|
||||
// check wi1 has no permissions
|
||||
ctpObject = suite.client.WaitForNewVersion(suite.T(), ctpID, ctpObject.Version)
|
||||
suite.requireCTP(ctpObject, nil, nil)
|
||||
|
||||
// edit tp2 to point to wi1
|
||||
rtest.Resource(pbauth.TrafficPermissionsType, "tp2").WithData(suite.T(), &pbauth.TrafficPermissions{
|
||||
Destination: &pbauth.Destination{IdentityName: "wi1"},
|
||||
Action: pbauth.Action_ACTION_ALLOW,
|
||||
Permissions: []*pbauth.Permission{p2},
|
||||
}).Write(suite.T(), suite.client)
|
||||
// check wi1 has tp2's permissions
|
||||
ctpObject = suite.client.WaitForNewVersion(suite.T(), ctpID, ctpObject.Version)
|
||||
suite.requireCTP(ctpObject, []*pbauth.Permission{p2}, nil)
|
||||
// check no ctp2
|
||||
ctpID2 = rtest.Resource(pbauth.ComputedTrafficPermissionsType, "wi2").ID()
|
||||
suite.client.RequireResourceNotFound(suite.T(), ctpID2)
|
||||
}
|
||||
|
||||
func (suite *controllerSuite) TestControllerMultipleTrafficPermissions() {
|
||||
// TODO: refactor this, turn back on once timing flakes are understood
|
||||
suite.T().Skip("flaky behavior observed")
|
||||
// In this test we check operations for a workload identity and multiple referencing traffic permissions
|
||||
mgr := controller.NewManager(suite.client, suite.rt.Logger)
|
||||
mgr.Register(Controller(suite.mapper))
|
||||
mgr.SetRaftLeader(true)
|
||||
go mgr.Run(suite.ctx)
|
||||
|
||||
wi1ID := &pbresource.ID{
|
||||
Name: "wi1",
|
||||
Type: pbauth.ComputedTrafficPermissionsType,
|
||||
Tenancy: resource.DefaultNamespacedTenancy(),
|
||||
}
|
||||
// add tp1 and tp2
|
||||
p1 := &pbauth.Permission{
|
||||
Sources: []*pbauth.Source{{
|
||||
IdentityName: "wi2",
|
||||
Namespace: "default",
|
||||
Partition: "default",
|
||||
Peer: "local",
|
||||
}},
|
||||
DestinationRules: nil,
|
||||
}
|
||||
tp1 := rtest.Resource(pbauth.TrafficPermissionsType, "tp1").WithData(suite.T(), &pbauth.TrafficPermissions{
|
||||
Destination: &pbauth.Destination{IdentityName: "wi1"},
|
||||
Action: pbauth.Action_ACTION_ALLOW,
|
||||
Permissions: []*pbauth.Permission{p1},
|
||||
}).Write(suite.T(), suite.client)
|
||||
suite.client.RequireResourceExists(suite.T(), tp1.Id)
|
||||
suite.requireTrafficPermissionsTracking(tp1, wi1ID)
|
||||
p2 := &pbauth.Permission{
|
||||
Sources: []*pbauth.Source{{
|
||||
IdentityName: "wi3",
|
||||
Namespace: "default",
|
||||
Partition: "default",
|
||||
Peer: "local",
|
||||
}},
|
||||
DestinationRules: nil,
|
||||
}
|
||||
tp2 := rtest.Resource(pbauth.TrafficPermissionsType, "tp2").WithData(suite.T(), &pbauth.TrafficPermissions{
|
||||
Destination: &pbauth.Destination{IdentityName: "wi1"},
|
||||
Action: pbauth.Action_ACTION_ALLOW,
|
||||
Permissions: []*pbauth.Permission{p2},
|
||||
}).Write(suite.T(), suite.client)
|
||||
suite.client.RequireResourceExists(suite.T(), tp2.Id)
|
||||
suite.requireTrafficPermissionsTracking(tp1, wi1ID)
|
||||
|
||||
// Add a workload identity
|
||||
workloadIdentity := rtest.Resource(pbauth.WorkloadIdentityType, "wi1").Write(suite.T(), suite.client)
|
||||
ctpID := resource.ReplaceType(pbauth.ComputedTrafficPermissionsType, workloadIdentity.Id)
|
||||
// Wait for the controller to record that the CTP has been computed
|
||||
res := suite.client.WaitForReconciliation(suite.T(), ctpID, StatusKey)
|
||||
rtest.RequireStatusCondition(suite.T(), res, StatusKey, ConditionComputed("wi1"))
|
||||
// check ctp1 has tp1 and tp2
|
||||
ctpObject := suite.client.RequireResourceExists(suite.T(), res.Id)
|
||||
suite.requireCTP(ctpObject, []*pbauth.Permission{p1, p2}, nil)
|
||||
|
||||
// add tp3
|
||||
p3 := &pbauth.Permission{
|
||||
Sources: []*pbauth.Source{{
|
||||
IdentityName: "wi4",
|
||||
Namespace: "default",
|
||||
Partition: "default",
|
||||
Peer: "local",
|
||||
}},
|
||||
DestinationRules: nil,
|
||||
}
|
||||
tp3 := rtest.Resource(pbauth.TrafficPermissionsType, "tp3").WithData(suite.T(), &pbauth.TrafficPermissions{
|
||||
Destination: &pbauth.Destination{IdentityName: "wi1"},
|
||||
Action: pbauth.Action_ACTION_DENY,
|
||||
Permissions: []*pbauth.Permission{p3},
|
||||
}).Write(suite.T(), suite.client)
|
||||
suite.client.RequireResourceExists(suite.T(), tp3.Id)
|
||||
// check ctp1 has tp3
|
||||
ctpObject = suite.client.WaitForReconciliation(suite.T(), ctpObject.Id, StatusKey)
|
||||
ctpObject = suite.client.WaitForNewVersion(suite.T(), ctpObject.Id, ctpObject.Version)
|
||||
suite.requireCTP(ctpObject, []*pbauth.Permission{p1, p2}, []*pbauth.Permission{p3})
|
||||
|
||||
// delete ctp
|
||||
suite.client.MustDelete(suite.T(), ctpObject.Id)
|
||||
suite.client.WaitForDeletion(suite.T(), ctpObject.Id)
|
||||
// check ctp regenerated, has all permissions
|
||||
res = suite.client.WaitForReconciliation(suite.T(), ctpID, StatusKey)
|
||||
rtest.RequireStatusCondition(suite.T(), res, StatusKey, ConditionComputed("wi1"))
|
||||
ctpObject = suite.client.RequireResourceExists(suite.T(), res.Id)
|
||||
suite.requireCTP(ctpObject, []*pbauth.Permission{p1, p2}, []*pbauth.Permission{p3})
|
||||
|
||||
// delete wi1
|
||||
suite.client.MustDelete(suite.T(), workloadIdentity.Id)
|
||||
suite.client.WaitForDeletion(suite.T(), workloadIdentity.Id)
|
||||
|
||||
// recreate wi1
|
||||
rtest.Resource(pbauth.WorkloadIdentityType, "wi1").Write(suite.T(), suite.client)
|
||||
// check ctp regenerated, has all permissions
|
||||
res = suite.client.WaitForReconciliation(suite.T(), ctpID, StatusKey)
|
||||
rtest.RequireStatusCondition(suite.T(), res, StatusKey, ConditionComputed("wi1"))
|
||||
ctpObject = suite.client.RequireResourceExists(suite.T(), res.Id)
|
||||
suite.requireCTP(ctpObject, []*pbauth.Permission{p1, p2}, []*pbauth.Permission{p3})
|
||||
|
||||
// delete tp3
|
||||
suite.client.MustDelete(suite.T(), tp3.Id)
|
||||
suite.client.WaitForDeletion(suite.T(), tp3.Id)
|
||||
suite.client.RequireResourceNotFound(suite.T(), tp3.Id)
|
||||
// check ctp1 has tp1 and tp2, and not tp3
|
||||
res = suite.client.WaitForReconciliation(suite.T(), ctpObject.Id, StatusKey)
|
||||
ctpObject = suite.client.WaitForNewVersion(suite.T(), res.Id, ctpObject.Version)
|
||||
suite.requireCTP(ctpObject, []*pbauth.Permission{p1, p2}, nil)
|
||||
|
||||
// add wi2
|
||||
workloadIdentity2 := rtest.Resource(pbauth.WorkloadIdentityType, "wi2").Write(suite.T(), suite.client)
|
||||
// Wait for the controller to record that the CTP has been computed
|
||||
res2 := suite.client.WaitForReconciliation(suite.T(), resource.ReplaceType(pbauth.ComputedTrafficPermissionsType, workloadIdentity2.Id), StatusKey)
|
||||
rtest.RequireStatusCondition(suite.T(), res2, StatusKey, ConditionComputed("wi2"))
|
||||
// check ctp2 has no permissions
|
||||
ctpObject2 := suite.client.RequireResourceExists(suite.T(), res2.Id)
|
||||
suite.requireCTP(ctpObject2, nil, nil)
|
||||
|
||||
// edit all traffic permissions to point to wi2
|
||||
tp1 = rtest.Resource(pbauth.TrafficPermissionsType, "tp1").WithData(suite.T(), &pbauth.TrafficPermissions{
|
||||
Destination: &pbauth.Destination{IdentityName: "wi2"},
|
||||
Action: pbauth.Action_ACTION_ALLOW,
|
||||
Permissions: []*pbauth.Permission{p1},
|
||||
}).Write(suite.T(), suite.client)
|
||||
tp2 = rtest.Resource(pbauth.TrafficPermissionsType, "tp2").WithData(suite.T(), &pbauth.TrafficPermissions{
|
||||
Destination: &pbauth.Destination{IdentityName: "wi2"},
|
||||
Action: pbauth.Action_ACTION_ALLOW,
|
||||
Permissions: []*pbauth.Permission{p2},
|
||||
}).Write(suite.T(), suite.client)
|
||||
tp3 = rtest.Resource(pbauth.TrafficPermissionsType, "tp3").WithData(suite.T(), &pbauth.TrafficPermissions{
|
||||
Destination: &pbauth.Destination{IdentityName: "wi2"},
|
||||
Action: pbauth.Action_ACTION_DENY,
|
||||
Permissions: []*pbauth.Permission{p3},
|
||||
}).Write(suite.T(), suite.client)
|
||||
suite.client.RequireResourceExists(suite.T(), tp1.Id)
|
||||
suite.client.RequireResourceExists(suite.T(), tp2.Id)
|
||||
suite.client.RequireResourceExists(suite.T(), tp3.Id)
|
||||
|
||||
// check wi2 has updated with all permissions after 6 reconciles
|
||||
ctpObject2 = suite.client.WaitForReconciliation(suite.T(), ctpObject2.Id, StatusKey)
|
||||
res2 = suite.client.WaitForReconciliation(suite.T(), ctpObject2.Id, StatusKey)
|
||||
suite.client.WaitForResourceState(suite.T(), res2.Id, func(t rtest.T, res *pbresource.Resource) {
|
||||
suite.requireCTP(res, []*pbauth.Permission{p1, p2}, []*pbauth.Permission{p3})
|
||||
})
|
||||
// check wi1 has no permissions after 6 reconciles
|
||||
ctpObject = suite.client.WaitForReconciliation(suite.T(), ctpObject.Id, StatusKey)
|
||||
res = suite.client.WaitForReconciliation(suite.T(), ctpObject.Id, StatusKey)
|
||||
suite.client.WaitForResourceState(suite.T(), res.Id, func(t rtest.T, res *pbresource.Resource) {
|
||||
suite.requireCTP(res, nil, nil)
|
||||
})
|
||||
}
|
||||
|
||||
func TestController(t *testing.T) {
|
||||
suite.Run(t, new(controllerSuite))
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package trafficpermissions
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/consul/proto-public/pbresource"
|
||||
)
|
||||
|
||||
const (
|
||||
StatusKey = "consul.io/traffic-permissions"
|
||||
StatusTrafficPermissionsComputed = "Traffic permissions have been computed"
|
||||
StatusTrafficPermissionsNotComputed = "Traffic permissions have been computed"
|
||||
ConditionPermissionsAppliedMsg = "Workload identity %s has new permission set"
|
||||
ConditionPermissionsFailedMsg = "Unable to calculate new permission set for Workload identity %s"
|
||||
)
|
||||
|
||||
var (
|
||||
ConditionComputed = func(workloadIdentity string) *pbresource.Condition {
|
||||
return &pbresource.Condition{
|
||||
Type: StatusTrafficPermissionsComputed,
|
||||
State: pbresource.Condition_STATE_TRUE,
|
||||
Message: fmt.Sprintf(ConditionPermissionsAppliedMsg, workloadIdentity),
|
||||
}
|
||||
}
|
||||
ConditionFailedToCompute = func(workloadIdentity string, trafficPermissions string, errDetail string) *pbresource.Condition {
|
||||
message := fmt.Sprintf(ConditionPermissionsFailedMsg, workloadIdentity)
|
||||
if len(trafficPermissions) > 0 {
|
||||
message = message + fmt.Sprintf(", traffic permission %s cannot be computed", trafficPermissions)
|
||||
}
|
||||
if len(errDetail) > 0 {
|
||||
message = message + fmt.Sprintf(", error details: %s", errDetail)
|
||||
}
|
||||
return &pbresource.Condition{
|
||||
Type: StatusTrafficPermissionsNotComputed,
|
||||
State: pbresource.Condition_STATE_FALSE,
|
||||
Message: message,
|
||||
}
|
||||
}
|
||||
)
|
|
@ -0,0 +1,73 @@
|
|||
// Copyright (c) HashiCorp, Inc.
|
||||
// SPDX-License-Identifier: BUSL-1.1
|
||||
|
||||
package trafficpermissionsmapper
|
||||
|
||||
import (
|
||||
"context"
|
||||
"sync"
|
||||
|
||||
"github.com/hashicorp/consul/internal/auth/internal/types"
|
||||
"github.com/hashicorp/consul/internal/controller"
|
||||
"github.com/hashicorp/consul/internal/resource"
|
||||
"github.com/hashicorp/consul/internal/resource/mappers/bimapper"
|
||||
pbauth "github.com/hashicorp/consul/proto-public/pbauth/v2beta1"
|
||||
"github.com/hashicorp/consul/proto-public/pbresource"
|
||||
)
|
||||
|
||||
type TrafficPermissionsMapper struct {
|
||||
lock sync.Mutex
|
||||
mapper *bimapper.Mapper
|
||||
}
|
||||
|
||||
func New() *TrafficPermissionsMapper {
|
||||
return &TrafficPermissionsMapper{
|
||||
lock: sync.Mutex{},
|
||||
mapper: bimapper.New(pbauth.TrafficPermissionsType, pbauth.ComputedTrafficPermissionsType),
|
||||
}
|
||||
}
|
||||
|
||||
// TrafficPermissionsMapper functions
|
||||
|
||||
func (tm *TrafficPermissionsMapper) MapTrafficPermissions(_ context.Context, _ controller.Runtime, res *pbresource.Resource) ([]controller.Request, error) {
|
||||
tm.lock.Lock()
|
||||
defer tm.lock.Unlock()
|
||||
var tp pbauth.TrafficPermissions
|
||||
err := res.Data.UnmarshalTo(&tp)
|
||||
if err != nil {
|
||||
return nil, resource.NewErrDataParse(&tp, err)
|
||||
}
|
||||
// get new CTP associations based on destination
|
||||
if len(tp.Destination.IdentityName) == 0 {
|
||||
// this error should never happen if validation is working
|
||||
return nil, types.ErrWildcardNotSupported
|
||||
}
|
||||
newCTP := &pbresource.ID{
|
||||
Name: tp.Destination.IdentityName,
|
||||
Type: pbauth.ComputedTrafficPermissionsType,
|
||||
Tenancy: res.Id.Tenancy,
|
||||
}
|
||||
requests := []controller.Request{{ID: newCTP}}
|
||||
// add already associated WorkloadIdentities/CTPs for reconcile requests:
|
||||
oldCTPs := tm.mapper.LinkIDsForItem(res.Id)
|
||||
for _, mappedWI := range oldCTPs {
|
||||
if mappedWI.Name != newCTP.Name {
|
||||
requests = append(requests, controller.Request{ID: mappedWI})
|
||||
}
|
||||
}
|
||||
// re-map traffic permission to new CTP
|
||||
tm.mapper.TrackItem(res.Id, []resource.ReferenceOrID{newCTP})
|
||||
return requests, nil
|
||||
}
|
||||
|
||||
func (tm *TrafficPermissionsMapper) UntrackTrafficPermissions(tp *pbresource.ID) {
|
||||
tm.lock.Lock()
|
||||
defer tm.lock.Unlock()
|
||||
tm.mapper.UntrackItem(tp)
|
||||
}
|
||||
|
||||
func (tm *TrafficPermissionsMapper) GetTrafficPermissionsForCTP(ctp *pbresource.ID) []*pbresource.Reference {
|
||||
tm.lock.Lock()
|
||||
defer tm.lock.Unlock()
|
||||
return tm.mapper.ItemRefsForLink(ctp)
|
||||
}
|
|
@ -6,9 +6,10 @@ 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")
|
||||
errSourceWildcards = errors.New("permission sources may not have wildcard namespaces and explicit names.")
|
||||
errSourceExcludes = errors.New("must be defined on wildcard sources")
|
||||
errInvalidPrefixValues = errors.New("prefix values, regex values, and explicit names must not combined")
|
||||
errInvalidAction = errors.New("action must be either allow or deny")
|
||||
errSourcesTenancy = errors.New("permissions sources may not specify partitions, peers, and sameness_groups together")
|
||||
errSourceWildcards = errors.New("permission sources may not have wildcard namespaces and explicit names.")
|
||||
errSourceExcludes = errors.New("must be defined on wildcard sources")
|
||||
errInvalidPrefixValues = errors.New("prefix values, regex values, and explicit names must not combined")
|
||||
ErrWildcardNotSupported = errors.New("traffic permissions without explicit destinations are not yet supported")
|
||||
)
|
||||
|
|
|
@ -44,9 +44,11 @@ func (d *DecodedResource[T]) GetData() T {
|
|||
func Decode[T proto.Message](res *pbresource.Resource) (*DecodedResource[T], error) {
|
||||
var zero T
|
||||
data := zero.ProtoReflect().New().Interface().(T)
|
||||
|
||||
if err := res.Data.UnmarshalTo(data); err != nil {
|
||||
return nil, NewErrDataParse(data, err)
|
||||
// check that there is data to unmarshall
|
||||
if res.Data != nil {
|
||||
if err := res.Data.UnmarshalTo(data); err != nil {
|
||||
return nil, NewErrDataParse(data, err)
|
||||
}
|
||||
}
|
||||
return &DecodedResource[T]{
|
||||
Resource: res,
|
||||
|
@ -64,6 +66,5 @@ func GetDecodedResource[T proto.Message](ctx context.Context, client pbresource.
|
|||
case err != nil:
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return Decode[T](rsp.Resource)
|
||||
}
|
||||
|
|
|
@ -268,8 +268,7 @@ type Destination struct {
|
|||
sizeCache protoimpl.SizeCache
|
||||
unknownFields protoimpl.UnknownFields
|
||||
|
||||
IdentityName string `protobuf:"bytes,1,opt,name=identity_name,json=identityName,proto3" json:"identity_name,omitempty"`
|
||||
IdentityPrefix string `protobuf:"bytes,2,opt,name=identity_prefix,json=identityPrefix,proto3" json:"identity_prefix,omitempty"`
|
||||
IdentityName string `protobuf:"bytes,1,opt,name=identity_name,json=identityName,proto3" json:"identity_name,omitempty"`
|
||||
}
|
||||
|
||||
func (x *Destination) Reset() {
|
||||
|
@ -311,13 +310,6 @@ func (x *Destination) GetIdentityName() string {
|
|||
return ""
|
||||
}
|
||||
|
||||
func (x *Destination) GetIdentityPrefix() string {
|
||||
if x != nil {
|
||||
return x.IdentityPrefix
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// permissions is a list of permissions to match on.
|
||||
type Permission struct {
|
||||
state protoimpl.MessageState
|
||||
|
@ -881,120 +873,118 @@ var file_pbauth_v2beta1_traffic_permissions_proto_rawDesc = []byte{
|
|||
0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x61, 0x75, 0x74, 0x68,
|
||||
0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73,
|
||||
0x69, 0x6f, 0x6e, 0x52, 0x0b, 0x70, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73,
|
||||
0x3a, 0x06, 0xa2, 0x93, 0x04, 0x02, 0x08, 0x02, 0x22, 0x5b, 0x0a, 0x0b, 0x44, 0x65, 0x73, 0x74,
|
||||
0x3a, 0x06, 0xa2, 0x93, 0x04, 0x02, 0x08, 0x02, 0x22, 0x32, 0x0a, 0x0b, 0x44, 0x65, 0x73, 0x74,
|
||||
0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x64, 0x65, 0x6e, 0x74,
|
||||
0x69, 0x74, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c,
|
||||
0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x27, 0x0a, 0x0f,
|
||||
0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18,
|
||||
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x50,
|
||||
0x72, 0x65, 0x66, 0x69, 0x78, 0x22, 0xaa, 0x01, 0x0a, 0x0a, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73,
|
||||
0x73, 0x69, 0x6f, 0x6e, 0x12, 0x3f, 0x0a, 0x07, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18,
|
||||
0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72,
|
||||
0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x76, 0x32,
|
||||
0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x07, 0x73, 0x6f,
|
||||
0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x5b, 0x0a, 0x11, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b,
|
||||
0x32, 0x2e, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e,
|
||||
0x73, 0x75, 0x6c, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31,
|
||||
0x2e, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x75, 0x6c, 0x65,
|
||||
0x52, 0x10, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x75, 0x6c,
|
||||
0x65, 0x73, 0x22, 0xec, 0x01, 0x0a, 0x06, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x23, 0x0a,
|
||||
0x0d, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01,
|
||||
0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x4e, 0x61,
|
||||
0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18,
|
||||
0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65,
|
||||
0x12, 0x1c, 0x0a, 0x09, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12,
|
||||
0x0a, 0x04, 0x70, 0x65, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x65,
|
||||
0x65, 0x72, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x61, 0x6d, 0x65, 0x6e, 0x65, 0x73, 0x73, 0x5f, 0x67,
|
||||
0x72, 0x6f, 0x75, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x61, 0x6d, 0x65,
|
||||
0x6e, 0x65, 0x73, 0x73, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x12, 0x46, 0x0a, 0x07, 0x65, 0x78, 0x63,
|
||||
0x6c, 0x75, 0x64, 0x65, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2c, 0x2e, 0x68, 0x61, 0x73,
|
||||
0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x61, 0x75,
|
||||
0x74, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x45, 0x78, 0x63, 0x6c, 0x75,
|
||||
0x64, 0x65, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52, 0x07, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64,
|
||||
0x65, 0x22, 0xab, 0x01, 0x0a, 0x0d, 0x45, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x53, 0x6f, 0x75,
|
||||
0x72, 0x63, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f,
|
||||
0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x69, 0x64, 0x65, 0x6e,
|
||||
0x74, 0x69, 0x74, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65,
|
||||
0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d,
|
||||
0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x72, 0x74, 0x69,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x65, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x04, 0x70, 0x65, 0x65, 0x72, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x61, 0x6d, 0x65,
|
||||
0x6e, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x0d, 0x73, 0x61, 0x6d, 0x65, 0x6e, 0x65, 0x73, 0x73, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x22,
|
||||
0xc7, 0x02, 0x0a, 0x0f, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52,
|
||||
0x75, 0x6c, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x65, 0x78, 0x61, 0x63,
|
||||
0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x74, 0x68, 0x45, 0x78, 0x61,
|
||||
0x63, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x69,
|
||||
0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x61, 0x74, 0x68, 0x50, 0x72, 0x65,
|
||||
0x66, 0x69, 0x78, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x72, 0x65, 0x67, 0x65,
|
||||
0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x74, 0x68, 0x52, 0x65, 0x67,
|
||||
0x65, 0x78, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x18, 0x04, 0x20,
|
||||
0x03, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x12, 0x4c, 0x0a, 0x06,
|
||||
0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x68,
|
||||
0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x22, 0xaa, 0x01, 0x0a,
|
||||
0x0a, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x3f, 0x0a, 0x07, 0x73,
|
||||
0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x25, 0x2e, 0x68,
|
||||
0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e,
|
||||
0x61, 0x75, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x73,
|
||||
0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x75, 0x6c, 0x65, 0x48, 0x65, 0x61, 0x64,
|
||||
0x65, 0x72, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x6f,
|
||||
0x72, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09,
|
||||
0x70, 0x6f, 0x72, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x4e, 0x0a, 0x07, 0x65, 0x78, 0x63,
|
||||
0x6c, 0x75, 0x64, 0x65, 0x18, 0x07, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x68, 0x61, 0x73,
|
||||
0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x61, 0x75,
|
||||
0x74, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x45, 0x78, 0x63, 0x6c, 0x75,
|
||||
0x64, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x75, 0x6c, 0x65,
|
||||
0x52, 0x07, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x22, 0xfd, 0x01, 0x0a, 0x15, 0x45, 0x78,
|
||||
0x63, 0x6c, 0x75, 0x64, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52,
|
||||
0x75, 0x6c, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x65, 0x78, 0x61, 0x63,
|
||||
0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x74, 0x68, 0x45, 0x78, 0x61,
|
||||
0x63, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x69,
|
||||
0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a, 0x70, 0x61, 0x74, 0x68, 0x50, 0x72, 0x65,
|
||||
0x66, 0x69, 0x78, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61, 0x74, 0x68, 0x5f, 0x72, 0x65, 0x67, 0x65,
|
||||
0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x74, 0x68, 0x52, 0x65, 0x67,
|
||||
0x65, 0x78, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x18, 0x04, 0x20,
|
||||
0x03, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x73, 0x12, 0x4c, 0x0a, 0x06,
|
||||
0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x68,
|
||||
0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e,
|
||||
0x61, 0x75, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x73,
|
||||
0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x75, 0x6c, 0x65, 0x48, 0x65, 0x61, 0x64,
|
||||
0x65, 0x72, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x6f,
|
||||
0x72, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09,
|
||||
0x70, 0x6f, 0x72, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x22, 0xb9, 0x01, 0x0a, 0x15, 0x44, 0x65,
|
||||
0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x75, 0x6c, 0x65, 0x48, 0x65, 0x61,
|
||||
0x64, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x70, 0x72, 0x65, 0x73, 0x65,
|
||||
0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x07, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e,
|
||||
0x74, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x78, 0x61, 0x63, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x05, 0x65, 0x78, 0x61, 0x63, 0x74, 0x12, 0x16, 0x0a, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69,
|
||||
0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12,
|
||||
0x16, 0x0a, 0x06, 0x73, 0x75, 0x66, 0x66, 0x69, 0x78, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52,
|
||||
0x06, 0x73, 0x75, 0x66, 0x66, 0x69, 0x78, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x65, 0x67, 0x65, 0x78,
|
||||
0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x72, 0x65, 0x67, 0x65, 0x78, 0x12, 0x16, 0x0a,
|
||||
0x06, 0x69, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x18, 0x07, 0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x69,
|
||||
0x6e, 0x76, 0x65, 0x72, 0x74, 0x2a, 0x43, 0x0a, 0x06, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12,
|
||||
0x16, 0x0a, 0x12, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43,
|
||||
0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f, 0x0a, 0x0b, 0x41, 0x43, 0x54, 0x49, 0x4f,
|
||||
0x4e, 0x5f, 0x44, 0x45, 0x4e, 0x59, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x41, 0x43, 0x54, 0x49,
|
||||
0x4f, 0x4e, 0x5f, 0x41, 0x4c, 0x4c, 0x4f, 0x57, 0x10, 0x02, 0x42, 0x98, 0x02, 0x0a, 0x21, 0x63,
|
||||
0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e,
|
||||
0x73, 0x75, 0x6c, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31,
|
||||
0x42, 0x17, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73,
|
||||
0x69, 0x6f, 0x6e, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x43, 0x67, 0x69, 0x74,
|
||||
0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72,
|
||||
0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x70,
|
||||
0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x61, 0x75, 0x74, 0x68, 0x2f, 0x76, 0x32, 0x62,
|
||||
0x65, 0x74, 0x61, 0x31, 0x3b, 0x61, 0x75, 0x74, 0x68, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31,
|
||||
0xa2, 0x02, 0x03, 0x48, 0x43, 0x41, 0xaa, 0x02, 0x1d, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f,
|
||||
0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x41, 0x75, 0x74, 0x68, 0x2e, 0x56,
|
||||
0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x1d, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f,
|
||||
0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x41, 0x75, 0x74, 0x68, 0x5c, 0x56,
|
||||
0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x29, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f,
|
||||
0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x41, 0x75, 0x74, 0x68, 0x5c, 0x56,
|
||||
0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61,
|
||||
0x74, 0x61, 0xea, 0x02, 0x20, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a,
|
||||
0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x41, 0x75, 0x74, 0x68, 0x3a, 0x3a, 0x56, 0x32,
|
||||
0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
|
||||
0x61, 0x75, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x53, 0x6f, 0x75,
|
||||
0x72, 0x63, 0x65, 0x52, 0x07, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x12, 0x5b, 0x0a, 0x11,
|
||||
0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x75, 0x6c, 0x65,
|
||||
0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2e, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63,
|
||||
0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x2e,
|
||||
0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74,
|
||||
0x69, 0x6f, 0x6e, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x10, 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x52, 0x75, 0x6c, 0x65, 0x73, 0x22, 0xec, 0x01, 0x0a, 0x06, 0x53, 0x6f,
|
||||
0x75, 0x72, 0x63, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79,
|
||||
0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0c, 0x69, 0x64, 0x65,
|
||||
0x6e, 0x74, 0x69, 0x74, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d,
|
||||
0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x6e, 0x61,
|
||||
0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x70, 0x61, 0x72, 0x74, 0x69,
|
||||
0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x72, 0x74,
|
||||
0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x65, 0x65, 0x72, 0x18, 0x04, 0x20,
|
||||
0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x65, 0x65, 0x72, 0x12, 0x25, 0x0a, 0x0e, 0x73, 0x61, 0x6d,
|
||||
0x65, 0x6e, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x0d, 0x73, 0x61, 0x6d, 0x65, 0x6e, 0x65, 0x73, 0x73, 0x47, 0x72, 0x6f, 0x75, 0x70,
|
||||
0x12, 0x46, 0x0a, 0x07, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x18, 0x06, 0x20, 0x03, 0x28,
|
||||
0x0b, 0x32, 0x2c, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f,
|
||||
0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61,
|
||||
0x31, 0x2e, 0x45, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x52,
|
||||
0x07, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x22, 0xab, 0x01, 0x0a, 0x0d, 0x45, 0x78, 0x63,
|
||||
0x6c, 0x75, 0x64, 0x65, 0x53, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x64,
|
||||
0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28,
|
||||
0x09, 0x52, 0x0c, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x4e, 0x61, 0x6d, 0x65, 0x12,
|
||||
0x1c, 0x0a, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01,
|
||||
0x28, 0x09, 0x52, 0x09, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x70, 0x61, 0x63, 0x65, 0x12, 0x1c, 0x0a,
|
||||
0x09, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09,
|
||||
0x52, 0x09, 0x70, 0x61, 0x72, 0x74, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x12, 0x0a, 0x04, 0x70,
|
||||
0x65, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x65, 0x65, 0x72, 0x12,
|
||||
0x25, 0x0a, 0x0e, 0x73, 0x61, 0x6d, 0x65, 0x6e, 0x65, 0x73, 0x73, 0x5f, 0x67, 0x72, 0x6f, 0x75,
|
||||
0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x73, 0x61, 0x6d, 0x65, 0x6e, 0x65, 0x73,
|
||||
0x73, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x22, 0xc7, 0x02, 0x0a, 0x0f, 0x44, 0x65, 0x73, 0x74, 0x69,
|
||||
0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61,
|
||||
0x74, 0x68, 0x5f, 0x65, 0x78, 0x61, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09,
|
||||
0x70, 0x61, 0x74, 0x68, 0x45, 0x78, 0x61, 0x63, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x61, 0x74,
|
||||
0x68, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a,
|
||||
0x70, 0x61, 0x74, 0x68, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61,
|
||||
0x74, 0x68, 0x5f, 0x72, 0x65, 0x67, 0x65, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09,
|
||||
0x70, 0x61, 0x74, 0x68, 0x52, 0x65, 0x67, 0x65, 0x78, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x74,
|
||||
0x68, 0x6f, 0x64, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x74, 0x68,
|
||||
0x6f, 0x64, 0x73, 0x12, 0x4c, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x05, 0x20,
|
||||
0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e,
|
||||
0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65,
|
||||
0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52,
|
||||
0x75, 0x6c, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65,
|
||||
0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18,
|
||||
0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x70, 0x6f, 0x72, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73,
|
||||
0x12, 0x4e, 0x0a, 0x07, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x18, 0x07, 0x20, 0x03, 0x28,
|
||||
0x0b, 0x32, 0x34, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f,
|
||||
0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61,
|
||||
0x31, 0x2e, 0x45, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73,
|
||||
0x69, 0x6f, 0x6e, 0x52, 0x75, 0x6c, 0x65, 0x52, 0x07, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65,
|
||||
0x22, 0xfd, 0x01, 0x0a, 0x15, 0x45, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x50, 0x65, 0x72, 0x6d,
|
||||
0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x75, 0x6c, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61,
|
||||
0x74, 0x68, 0x5f, 0x65, 0x78, 0x61, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09,
|
||||
0x70, 0x61, 0x74, 0x68, 0x45, 0x78, 0x61, 0x63, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x61, 0x74,
|
||||
0x68, 0x5f, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0a,
|
||||
0x70, 0x61, 0x74, 0x68, 0x50, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61,
|
||||
0x74, 0x68, 0x5f, 0x72, 0x65, 0x67, 0x65, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09,
|
||||
0x70, 0x61, 0x74, 0x68, 0x52, 0x65, 0x67, 0x65, 0x78, 0x12, 0x18, 0x0a, 0x07, 0x6d, 0x65, 0x74,
|
||||
0x68, 0x6f, 0x64, 0x73, 0x18, 0x04, 0x20, 0x03, 0x28, 0x09, 0x52, 0x07, 0x6d, 0x65, 0x74, 0x68,
|
||||
0x6f, 0x64, 0x73, 0x12, 0x4c, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x05, 0x20,
|
||||
0x01, 0x28, 0x0b, 0x32, 0x34, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e,
|
||||
0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65,
|
||||
0x74, 0x61, 0x31, 0x2e, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52,
|
||||
0x75, 0x6c, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65,
|
||||
0x72, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x6f, 0x72, 0x74, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x18,
|
||||
0x06, 0x20, 0x03, 0x28, 0x09, 0x52, 0x09, 0x70, 0x6f, 0x72, 0x74, 0x4e, 0x61, 0x6d, 0x65, 0x73,
|
||||
0x22, 0xb9, 0x01, 0x0a, 0x15, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e,
|
||||
0x52, 0x75, 0x6c, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61,
|
||||
0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x18,
|
||||
0x0a, 0x07, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52,
|
||||
0x07, 0x70, 0x72, 0x65, 0x73, 0x65, 0x6e, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x78, 0x61, 0x63,
|
||||
0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x78, 0x61, 0x63, 0x74, 0x12, 0x16,
|
||||
0x0a, 0x06, 0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06,
|
||||
0x70, 0x72, 0x65, 0x66, 0x69, 0x78, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x75, 0x66, 0x66, 0x69, 0x78,
|
||||
0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x75, 0x66, 0x66, 0x69, 0x78, 0x12, 0x14,
|
||||
0x0a, 0x05, 0x72, 0x65, 0x67, 0x65, 0x78, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x72,
|
||||
0x65, 0x67, 0x65, 0x78, 0x12, 0x16, 0x0a, 0x06, 0x69, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x18, 0x07,
|
||||
0x20, 0x01, 0x28, 0x08, 0x52, 0x06, 0x69, 0x6e, 0x76, 0x65, 0x72, 0x74, 0x2a, 0x43, 0x0a, 0x06,
|
||||
0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x0a, 0x12, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e,
|
||||
0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0f,
|
||||
0x0a, 0x0b, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x44, 0x45, 0x4e, 0x59, 0x10, 0x01, 0x12,
|
||||
0x10, 0x0a, 0x0c, 0x41, 0x43, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x41, 0x4c, 0x4c, 0x4f, 0x57, 0x10,
|
||||
0x02, 0x42, 0x98, 0x02, 0x0a, 0x21, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63,
|
||||
0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x2e,
|
||||
0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x42, 0x17, 0x54, 0x72, 0x61, 0x66, 0x66, 0x69, 0x63,
|
||||
0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x50, 0x72, 0x6f, 0x74, 0x6f,
|
||||
0x50, 0x01, 0x5a, 0x43, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68,
|
||||
0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2f,
|
||||
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2d, 0x70, 0x75, 0x62, 0x6c, 0x69, 0x63, 0x2f, 0x70, 0x62, 0x61,
|
||||
0x75, 0x74, 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x3b, 0x61, 0x75, 0x74, 0x68,
|
||||
0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xa2, 0x02, 0x03, 0x48, 0x43, 0x41, 0xaa, 0x02, 0x1d,
|
||||
0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c,
|
||||
0x2e, 0x41, 0x75, 0x74, 0x68, 0x2e, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xca, 0x02, 0x1d,
|
||||
0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c,
|
||||
0x5c, 0x41, 0x75, 0x74, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0xe2, 0x02, 0x29,
|
||||
0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c,
|
||||
0x5c, 0x41, 0x75, 0x74, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x47, 0x50,
|
||||
0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0xea, 0x02, 0x20, 0x48, 0x61, 0x73, 0x68,
|
||||
0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x41,
|
||||
0x75, 0x74, 0x68, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72,
|
||||
0x6f, 0x74, 0x6f, 0x33,
|
||||
}
|
||||
|
||||
var (
|
||||
|
|
|
@ -50,7 +50,6 @@ message PartitionTrafficPermissions {
|
|||
// be in the same tenancy as the TrafficPermissions resource.
|
||||
message Destination {
|
||||
string identity_name = 1;
|
||||
string identity_prefix = 2;
|
||||
}
|
||||
|
||||
enum Action {
|
||||
|
|
Loading…
Reference in New Issue