diff --git a/agent/xds/rbac_test.go b/agent/xds/rbac_test.go index 71b2a69433..c7805a0e49 100644 --- a/agent/xds/rbac_test.go +++ b/agent/xds/rbac_test.go @@ -12,6 +12,7 @@ import ( envoy_listener_v3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3" envoy_rbac_v3 "github.com/envoyproxy/go-control-plane/envoy/config/rbac/v3" + http_connection_managerv3 "github.com/envoyproxy/go-control-plane/envoy/extensions/filters/network/http_connection_manager/v3" envoy_matcher_v3 "github.com/envoyproxy/go-control-plane/envoy/type/matcher/v3" "github.com/stretchr/testify/assert" @@ -572,9 +573,9 @@ func TestMakeRBACNetworkAndHTTPFilters(t *testing.T) { } tests := map[string]struct { - intentionDefaultAllow bool - v1Intentions structs.SimplifiedIntentions - v2L4TrafficPermissions *pbproxystate.TrafficPermissions + intentionDefaultAllow bool + v1Intentions structs.SimplifiedIntentions + v2TrafficPermissions *pbproxystate.TrafficPermissions }{ "default-deny-mixed-precedence": { intentionDefaultAllow: false, @@ -583,7 +584,7 @@ func TestMakeRBACNetworkAndHTTPFilters(t *testing.T) { testIntention(t, "*", "api", structs.IntentionActionDeny), testIntention(t, "web", "*", structs.IntentionActionDeny), ), - v2L4TrafficPermissions: &pbproxystate.TrafficPermissions{ + v2TrafficPermissions: &pbproxystate.TrafficPermissions{ AllowPermissions: []*pbproxystate.Permission{ { Principals: []*pbproxystate.Principal{ @@ -600,7 +601,7 @@ func TestMakeRBACNetworkAndHTTPFilters(t *testing.T) { v1Intentions: sorted( testSourceIntention("*", structs.IntentionActionAllow), ), - v2L4TrafficPermissions: &pbproxystate.TrafficPermissions{ + v2TrafficPermissions: &pbproxystate.TrafficPermissions{ AllowPermissions: []*pbproxystate.Permission{ { Principals: []*pbproxystate.Principal{ @@ -623,7 +624,7 @@ func TestMakeRBACNetworkAndHTTPFilters(t *testing.T) { v1Intentions: sorted( testSourceIntention("web", structs.IntentionActionAllow), ), - v2L4TrafficPermissions: &pbproxystate.TrafficPermissions{ + v2TrafficPermissions: &pbproxystate.TrafficPermissions{ AllowPermissions: []*pbproxystate.Permission{ { Principals: []*pbproxystate.Principal{ @@ -647,7 +648,7 @@ func TestMakeRBACNetworkAndHTTPFilters(t *testing.T) { testSourceIntention("web", structs.IntentionActionDeny), testSourceIntention("*", structs.IntentionActionAllow), ), - v2L4TrafficPermissions: &pbproxystate.TrafficPermissions{ + v2TrafficPermissions: &pbproxystate.TrafficPermissions{ AllowPermissions: []*pbproxystate.Permission{ { Principals: []*pbproxystate.Principal{ @@ -669,7 +670,7 @@ func TestMakeRBACNetworkAndHTTPFilters(t *testing.T) { testSourceIntention("cron", structs.IntentionActionAllow), testSourceIntention("*", structs.IntentionActionAllow), ), - v2L4TrafficPermissions: &pbproxystate.TrafficPermissions{ + v2TrafficPermissions: &pbproxystate.TrafficPermissions{ AllowPermissions: []*pbproxystate.Permission{ { Principals: []*pbproxystate.Principal{ @@ -694,7 +695,7 @@ func TestMakeRBACNetworkAndHTTPFilters(t *testing.T) { }, "v2-kitchen-sink": { intentionDefaultAllow: false, - v2L4TrafficPermissions: &pbproxystate.TrafficPermissions{ + v2TrafficPermissions: &pbproxystate.TrafficPermissions{ AllowPermissions: []*pbproxystate.Permission{ { Principals: []*pbproxystate.Principal{ @@ -732,19 +733,19 @@ func TestMakeRBACNetworkAndHTTPFilters(t *testing.T) { }, }, "v2-default-deny": { - intentionDefaultAllow: false, - v2L4TrafficPermissions: &pbproxystate.TrafficPermissions{}, + intentionDefaultAllow: false, + v2TrafficPermissions: &pbproxystate.TrafficPermissions{}, }, "v2-default-allow": { - intentionDefaultAllow: true, - v2L4TrafficPermissions: &pbproxystate.TrafficPermissions{}, + intentionDefaultAllow: true, + v2TrafficPermissions: &pbproxystate.TrafficPermissions{}, }, // This validates that we don't send xDS messages to Envoy that will fail validation. // Traffic permissions validations prevent this from being written to the IR, so the thing // that matters is that the snapshot is valid to Envoy. "v2-ignore-empty-permissions": { intentionDefaultAllow: false, - v2L4TrafficPermissions: &pbproxystate.TrafficPermissions{ + v2TrafficPermissions: &pbproxystate.TrafficPermissions{ DenyPermissions: []*pbproxystate.Permission{ {}, }, @@ -824,6 +825,22 @@ func TestMakeRBACNetworkAndHTTPFilters(t *testing.T) { ), testSourceIntention("*", structs.IntentionActionDeny), ), + v2TrafficPermissions: &pbproxystate.TrafficPermissions{ + AllowPermissions: []*pbproxystate.Permission{ + { + Principals: []*pbproxystate.Principal{ + { + Spiffe: makeSpiffe("web", nil), + }, + }, + DestinationRules: []*pbproxystate.DestinationRule{ + { + PathPrefix: "/", + }, + }, + }, + }, + }, }, "default-allow-deny-all-and-path-deny": { intentionDefaultAllow: true, @@ -1079,13 +1096,13 @@ func TestMakeRBACNetworkAndHTTPFilters(t *testing.T) { }) t.Run("v1 vs v2", func(t *testing.T) { - if tt.v2L4TrafficPermissions == nil { + if tt.v2TrafficPermissions == nil { return } - tt.v2L4TrafficPermissions.DefaultAllow = tt.intentionDefaultAllow + tt.v2TrafficPermissions.DefaultAllow = tt.intentionDefaultAllow - filters, err := xdsv2.MakeRBACNetworkFilters(tt.v2L4TrafficPermissions) + filters, err := xdsv2.MakeRBACNetworkFilters(tt.v2TrafficPermissions) require.NoError(t, err) var gotJSON string @@ -1103,18 +1120,41 @@ func TestMakeRBACNetworkAndHTTPFilters(t *testing.T) { }) t.Run("http filter", func(t *testing.T) { - if len(tt.v1Intentions) == 0 { - return - } - - filter, err := makeRBACHTTPFilter(tt.v1Intentions, tt.intentionDefaultAllow, testLocalInfo, testPeerTrustBundle, testJWTProviderConfigEntry) - require.NoError(t, err) t.Run("current", func(t *testing.T) { + if len(tt.v1Intentions) == 0 { + return + } + + filter, err := makeRBACHTTPFilter(tt.v1Intentions, tt.intentionDefaultAllow, testLocalInfo, testPeerTrustBundle, testJWTProviderConfigEntry) + require.NoError(t, err) gotJSON := protoToJSON(t, filter) require.JSONEq(t, goldenSimple(t, filepath.Join("rbac", name+"--httpfilter"), gotJSON), gotJSON) }) + + t.Run("v1 vs v2", func(t *testing.T) { + if tt.v2TrafficPermissions == nil { + return + } + + tt.v2TrafficPermissions.DefaultAllow = tt.intentionDefaultAllow + + filters, err := xdsv2.MakeRBACHTTPFilters(tt.v2TrafficPermissions) + require.NoError(t, err) + + var gotJSON string + if len(filters) == 1 { + gotJSON = protoToJSON(t, filters[0]) + } else { + // This is wrapped because protoToJSON won't encode an array of protobufs. + manager := &http_connection_managerv3.HttpConnectionManager{} + manager.HttpFilters = filters + gotJSON = protoToJSON(t, manager) + } + + require.JSONEq(t, goldenSimple(t, filepath.Join("rbac", name+"--httpfilter"), gotJSON), gotJSON) + }) }) }) } diff --git a/agent/xds/response/response.go b/agent/xds/response/response.go index cc6f132eb6..76c189bee7 100644 --- a/agent/xds/response/response.go +++ b/agent/xds/response/response.go @@ -78,3 +78,12 @@ func MakeEnvoyRegexMatch(patt string) *envoy_matcher_v3.RegexMatcher { Regex: patt, } } + +func MakeEnvoyStringMatcher(patt string) *envoy_matcher_v3.StringMatcher { + return &envoy_matcher_v3.StringMatcher{ + MatchPattern: &envoy_matcher_v3.StringMatcher_SafeRegex{ + SafeRegex: MakeEnvoyRegexMatch(patt), + }, + IgnoreCase: true, + } +} diff --git a/agent/xds/testdata/rbac/v2-default-allow--httpfilter.golden b/agent/xds/testdata/rbac/v2-default-allow--httpfilter.golden new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/agent/xds/testdata/rbac/v2-default-allow--httpfilter.golden @@ -0,0 +1 @@ +{} diff --git a/agent/xds/testdata/rbac/v2-default-deny--httpfilter.golden b/agent/xds/testdata/rbac/v2-default-deny--httpfilter.golden new file mode 100644 index 0000000000..290edfd0c5 --- /dev/null +++ b/agent/xds/testdata/rbac/v2-default-deny--httpfilter.golden @@ -0,0 +1,7 @@ +{ + "name": "envoy.filters.http.rbac", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC", + "rules": {} + } +} diff --git a/agent/xds/testdata/rbac/v2-ignore-empty-permissions--httpfilter.golden b/agent/xds/testdata/rbac/v2-ignore-empty-permissions--httpfilter.golden new file mode 100644 index 0000000000..536b0e04f7 --- /dev/null +++ b/agent/xds/testdata/rbac/v2-ignore-empty-permissions--httpfilter.golden @@ -0,0 +1,20 @@ +{ + "httpFilters": [ + { + "name": "envoy.filters.http.rbac", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC", + "rules": { + "action": "DENY" + } + } + }, + { + "name": "envoy.filters.http.rbac", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC", + "rules": {} + } + } + ] +} diff --git a/agent/xds/testdata/rbac/v2-kitchen-sink--httpfilter.golden b/agent/xds/testdata/rbac/v2-kitchen-sink--httpfilter.golden new file mode 100644 index 0000000000..a9c458e230 --- /dev/null +++ b/agent/xds/testdata/rbac/v2-kitchen-sink--httpfilter.golden @@ -0,0 +1,114 @@ +{ + "httpFilters": [ + { + "name": "envoy.filters.http.rbac", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC", + "rules": { + "action": "DENY", + "policies": { + "consul-intentions-layer4": { + "permissions": [ + { + "any": true + } + ], + "principals": [ + { + "authenticated": { + "principalName": { + "safeRegex": { + "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/db$" + } + } + } + }, + { + "authenticated": { + "principalName": { + "safeRegex": { + "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/cron$" + } + } + } + } + ] + } + } + } + } + }, + { + "name": "envoy.filters.http.rbac", + "typedConfig": { + "@type": "type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC", + "rules": { + "policies": { + "consul-intentions-layer4-0": { + "permissions": [ + { + "any": true + } + ], + "principals": [ + { + "authenticated": { + "principalName": { + "safeRegex": { + "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/api$" + } + } + } + }, + { + "andIds": { + "ids": [ + { + "authenticated": { + "principalName": { + "safeRegex": { + "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/[^/]+$" + } + } + } + }, + { + "notId": { + "authenticated": { + "principalName": { + "safeRegex": { + "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/unsafe$" + } + } + } + } + } + ] + } + } + ] + }, + "consul-intentions-layer4-1": { + "permissions": [ + { + "any": true + } + ], + "principals": [ + { + "authenticated": { + "principalName": { + "safeRegex": { + "regex": "^spiffe://test.consul/ns/default/dc/[^/]+/svc/web$" + } + } + } + } + ] + } + } + } + } + } + ] +} diff --git a/agent/xdsv2/listener_resources.go b/agent/xdsv2/listener_resources.go index c58107faea..9aa466fe14 100644 --- a/agent/xdsv2/listener_resources.go +++ b/agent/xdsv2/listener_resources.go @@ -392,9 +392,7 @@ func (pr *ProxyResources) makeL4Filters(l4 *pbproxystate.L4Destination) ([]*envo func (pr *ProxyResources) makeL7Filters(l7 *pbproxystate.L7Destination) ([]*envoy_listener_v3.Filter, error) { var envoyFilters []*envoy_listener_v3.Filter var httpConnMgr *envoy_http_v3.HttpConnectionManager - if l7 != nil { - // TODO: Intentions will be added in the future. if l7.MaxInboundConnections > 0 { connLimitFilter, err := makeEnvoyConnectionLimitFilter(l7.MaxInboundConnections) if err != nil { diff --git a/agent/xdsv2/rbac_resources.go b/agent/xdsv2/rbac_resources.go index df670782ce..dbe83eb903 100644 --- a/agent/xdsv2/rbac_resources.go +++ b/agent/xdsv2/rbac_resources.go @@ -5,6 +5,7 @@ package xdsv2 import ( "fmt" + "strings" envoy_listener_v3 "github.com/envoyproxy/go-control-plane/envoy/config/listener/v3" envoy_rbac_v3 "github.com/envoyproxy/go-control-plane/envoy/config/rbac/v3" @@ -20,11 +21,12 @@ import ( const ( baseL4PermissionKey = "consul-intentions-layer4" + baseL7PermissionKey = "consul-intentions-layer7" ) -// MakeL4RBAC returns the envoy deny and allow rules from the traffic permissions. After calling this function these +// MakeRBAC returns the envoy deny and allow rules from the traffic permissions. After calling this function these // rules can be put into a network rbac filter or http rbac filter depending on the local app port protocol. -func MakeL4RBAC(trafficPermissions *pbproxystate.TrafficPermissions) (deny *envoy_rbac_v3.RBAC, allow *envoy_rbac_v3.RBAC, err error) { +func MakeRBAC(trafficPermissions *pbproxystate.TrafficPermissions, makePolicies func([]*pbproxystate.Permission) map[string]*envoy_rbac_v3.Policy) (deny *envoy_rbac_v3.RBAC, allow *envoy_rbac_v3.RBAC, err error) { var denyRBAC *envoy_rbac_v3.RBAC var allowRBAC *envoy_rbac_v3.RBAC @@ -37,7 +39,7 @@ func MakeL4RBAC(trafficPermissions *pbproxystate.TrafficPermissions) (deny *envo Action: envoy_rbac_v3.RBAC_DENY, Policies: make(map[string]*envoy_rbac_v3.Policy), } - denyRBAC.Policies = makeRBACPolicies(trafficPermissions.DenyPermissions) + denyRBAC.Policies = makePolicies(trafficPermissions.DenyPermissions) } // Only include the allow RBAC when Consul is in default deny. @@ -47,7 +49,7 @@ func MakeL4RBAC(trafficPermissions *pbproxystate.TrafficPermissions) (deny *envo Policies: make(map[string]*envoy_rbac_v3.Policy), } - allowRBAC.Policies = makeRBACPolicies(trafficPermissions.AllowPermissions) + allowRBAC.Policies = makePolicies(trafficPermissions.AllowPermissions) } return denyRBAC, allowRBAC, nil @@ -57,7 +59,7 @@ func MakeL4RBAC(trafficPermissions *pbproxystate.TrafficPermissions) (deny *envo func MakeRBACNetworkFilters(trafficPermissions *pbproxystate.TrafficPermissions) ([]*envoy_listener_v3.Filter, error) { var filters []*envoy_listener_v3.Filter - deny, allow, err := MakeL4RBAC(trafficPermissions) + deny, allow, err := MakeRBAC(trafficPermissions, makeL4RBACPolicies) if err != nil { return nil, err } @@ -87,7 +89,7 @@ func MakeRBACNetworkFilters(trafficPermissions *pbproxystate.TrafficPermissions) func MakeRBACHTTPFilters(trafficPermissions *pbproxystate.TrafficPermissions) ([]*envoy_http_v3.HttpFilter, error) { var httpFilters []*envoy_http_v3.HttpFilter - deny, allow, err := MakeL4RBAC(trafficPermissions) + deny, allow, err := MakeRBAC(trafficPermissions, makeL7RBACPolicies) if err != nil { return nil, err } @@ -106,7 +108,6 @@ func MakeRBACHTTPFilters(trafficPermissions *pbproxystate.TrafficPermissions) ([ return nil, err } httpFilters = append(httpFilters, filter) - } return httpFilters, nil @@ -132,28 +133,26 @@ func makeRBACHTTPFilter(rbac *envoy_rbac_v3.RBAC) (*envoy_http_v3.HttpFilter, er return makeEnvoyHTTPFilter(envoyHTTPRBACFilterKey, cfg) } -func makeRBACPolicies(l4Permissions []*pbproxystate.Permission) map[string]*envoy_rbac_v3.Policy { - policyLabel := func(i int) string { - if len(l4Permissions) == 1 { - return baseL4PermissionKey - } - return fmt.Sprintf("%s-%d", baseL4PermissionKey, i) - } - +func makeL4RBACPolicies(l4Permissions []*pbproxystate.Permission) map[string]*envoy_rbac_v3.Policy { policies := make(map[string]*envoy_rbac_v3.Policy, len(l4Permissions)) for i, permission := range l4Permissions { - policy := makeRBACPolicy(permission) + if len(permission.DestinationRules) != 0 { + // This is an L7-only permission + // ports are split out for separate configuration before this point and L7 filters are configured separately + continue + } + policy := makeL4RBACPolicy(permission) if policy != nil { - policies[policyLabel(i)] = policy + policies[l4PolicyLabel(l4Permissions, i)] = policy } } return policies } -func makeRBACPolicy(p *pbproxystate.Permission) *envoy_rbac_v3.Policy { - if len(p.Principals) == 0 { +func makeL4RBACPolicy(p *pbproxystate.Permission) *envoy_rbac_v3.Policy { + if p == nil || len(p.Principals) == 0 { return nil } @@ -169,6 +168,197 @@ func makeRBACPolicy(p *pbproxystate.Permission) *envoy_rbac_v3.Policy { } } +func l4PolicyLabel(perms []*pbproxystate.Permission, i int) string { + if len(perms) == 1 { + return baseL4PermissionKey + } + return fmt.Sprintf("%s-%d", baseL4PermissionKey, i) +} + +func makeL7RBACPolicies(l7Permissions []*pbproxystate.Permission) map[string]*envoy_rbac_v3.Policy { + // sort permissions into those with L7-specific features and those without, to match labeling and behavior + // conventions in V1: https://github.com/hashicorp/consul/blob/4e451f23584473a7eaf7f123145ca85e0a31783a/agent/xds/rbac.go#L647 + // this is a somewhat unfortunate carry-over needed for testing v1 vs v2 final config + // and this will break with v1 intentions when multiple L4 permissions are used + var l4Perms []*pbproxystate.Permission + var l7Perms []*pbproxystate.Permission + for _, p := range l7Permissions { + if len(p.DestinationRules) > 0 { + l7Perms = append(l7Perms, p) + } else { + l4Perms = append(l4Perms, p) + } + } + + policies := make(map[string]*envoy_rbac_v3.Policy, len(l7Permissions)) + + // L7 policies first, then L4 per: https://github.com/hashicorp/consul/blob/4e451f23584473a7eaf7f123145ca85e0a31783a/agent/xds/rbac.go#L664 + for i, permission := range l7Perms { + policy := makeL7RBACPolicy(permission) + if policy != nil { + policies[fmt.Sprintf("%s-%d", baseL7PermissionKey, i)] = policy + } + } + for i, permission := range l4Perms { + policy := makeL4RBACPolicy(permission) + if policy != nil { + policies[l4PolicyLabel(l4Perms, i)] = policy + } + } + + return policies +} + +func makeL7RBACPolicy(p *pbproxystate.Permission) *envoy_rbac_v3.Policy { + if p == nil || len(p.Principals) == 0 { + return nil + } + + var principals []*envoy_rbac_v3.Principal + + for _, p := range p.Principals { + principals = append(principals, toEnvoyPrincipal(p)) + } + permissions := permissionsFromDestinationRules(p.DestinationRules) + return &envoy_rbac_v3.Policy{ + Principals: principals, + Permissions: permissions, + } +} + +func permissionsFromDestinationRules(drs []*pbproxystate.DestinationRule) []*envoy_rbac_v3.Permission { + var perms []*envoy_rbac_v3.Permission + + for _, dr := range drs { + // paths + switch { + case dr.PathExact != "": + perms = append(perms, &envoy_rbac_v3.Permission{ + Rule: &envoy_rbac_v3.Permission_UrlPath{ + UrlPath: &envoy_matcher_v3.PathMatcher{ + Rule: &envoy_matcher_v3.PathMatcher_Path{ + Path: &envoy_matcher_v3.StringMatcher{ + MatchPattern: &envoy_matcher_v3.StringMatcher_Exact{ + Exact: dr.PathExact, + }, + }, + }, + }, + }, + }) + case dr.PathPrefix != "": + perms = append(perms, &envoy_rbac_v3.Permission{ + Rule: &envoy_rbac_v3.Permission_UrlPath{ + UrlPath: &envoy_matcher_v3.PathMatcher{ + Rule: &envoy_matcher_v3.PathMatcher_Path{ + Path: &envoy_matcher_v3.StringMatcher{ + MatchPattern: &envoy_matcher_v3.StringMatcher_Prefix{ + Prefix: dr.PathPrefix, + }, + }, + }, + }, + }, + }) + case dr.PathRegex != "": + perms = append(perms, &envoy_rbac_v3.Permission{ + Rule: &envoy_rbac_v3.Permission_UrlPath{ + UrlPath: &envoy_matcher_v3.PathMatcher{ + Rule: &envoy_matcher_v3.PathMatcher_Path{ + Path: &envoy_matcher_v3.StringMatcher{ + MatchPattern: &envoy_matcher_v3.StringMatcher_SafeRegex{ + SafeRegex: response.MakeEnvoyRegexMatch(dr.PathRegex), + }, + }, + }, + }, + }, + }) + } + + // methods + if len(dr.Methods) > 0 { + methodHeaderRegex := strings.Join(dr.Methods, "|") + eh := &envoy_route_v3.HeaderMatcher{ + Name: ":method", + HeaderMatchSpecifier: &envoy_route_v3.HeaderMatcher_StringMatch{ + StringMatch: response.MakeEnvoyStringMatcher(methodHeaderRegex), + }, + } + perms = append(perms, &envoy_rbac_v3.Permission{ + Rule: &envoy_rbac_v3.Permission_Header{ + Header: eh, + }}) + } + + // headers + for _, hdr := range dr.DestinationRuleHeader { + eh := &envoy_route_v3.HeaderMatcher{ + Name: hdr.Name, + } + + switch { + case hdr.Exact != "": + eh.HeaderMatchSpecifier = &envoy_route_v3.HeaderMatcher_StringMatch{ + StringMatch: &envoy_matcher_v3.StringMatcher{ + MatchPattern: &envoy_matcher_v3.StringMatcher_Exact{ + Exact: hdr.Exact, + }, + IgnoreCase: false, + }, + } + case hdr.Regex != "": + eh.HeaderMatchSpecifier = &envoy_route_v3.HeaderMatcher_StringMatch{ + StringMatch: &envoy_matcher_v3.StringMatcher{ + MatchPattern: &envoy_matcher_v3.StringMatcher_SafeRegex{ + SafeRegex: response.MakeEnvoyRegexMatch(hdr.Regex), + }, + IgnoreCase: false, + }, + } + + case hdr.Prefix != "": + eh.HeaderMatchSpecifier = &envoy_route_v3.HeaderMatcher_StringMatch{ + StringMatch: &envoy_matcher_v3.StringMatcher{ + MatchPattern: &envoy_matcher_v3.StringMatcher_Prefix{ + Prefix: hdr.Prefix, + }, + IgnoreCase: false, + }, + } + + case hdr.Suffix != "": + eh.HeaderMatchSpecifier = &envoy_route_v3.HeaderMatcher_StringMatch{ + StringMatch: &envoy_matcher_v3.StringMatcher{ + MatchPattern: &envoy_matcher_v3.StringMatcher_Suffix{ + Suffix: hdr.Suffix, + }, + IgnoreCase: false, + }, + } + + case hdr.Present: + eh.HeaderMatchSpecifier = &envoy_route_v3.HeaderMatcher_PresentMatch{ + PresentMatch: true, + } + default: + continue // skip this impossible situation + } + + if hdr.Invert { + eh.InvertMatch = true + } + + perms = append(perms, &envoy_rbac_v3.Permission{ + Rule: &envoy_rbac_v3.Permission_Header{ + Header: eh, + }, + }) + } + } + return perms +} + func toEnvoyPrincipal(p *pbproxystate.Principal) *envoy_rbac_v3.Principal { includePrincipal := principal(p.Spiffe) diff --git a/agent/xdsv2/testdata/listeners/source/multiple-workload-addresses-with-specific-ports.golden b/agent/xdsv2/testdata/listeners/source/multiple-workload-addresses-with-specific-ports.golden index cb81777262..a86ab21bc9 100644 --- a/agent/xdsv2/testdata/listeners/source/multiple-workload-addresses-with-specific-ports.golden +++ b/agent/xdsv2/testdata/listeners/source/multiple-workload-addresses-with-specific-ports.golden @@ -62,7 +62,24 @@ "name": "envoy.filters.http.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC", - "rules": {} + "rules": { + "policies": { + "consul-intentions-layer4": { + "permissions": [{ + "any": true + }], + "principals": [{ + "authenticated": { + "principalName": { + "safeRegex": { + "regex":"^spiffe://foo.consul/ap/default/ns/default/identity/foo$" + } + } + } + }] + } + } + } } }, { @@ -152,7 +169,24 @@ "name": "envoy.filters.http.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC", - "rules": {} + "rules": { + "policies": { + "consul-intentions-layer4": { + "permissions": [{ + "any": true + }], + "principals": [{ + "authenticated": { + "principalName": { + "safeRegex": { + "regex":"^spiffe://foo.consul/ap/default/ns/default/identity/foo$" + } + } + } + }] + } + } + } } }, { @@ -240,7 +274,24 @@ "name": "envoy.filters.http.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC", - "rules": {} + "rules": { + "policies": { + "consul-intentions-layer4": { + "permissions": [{ + "any": true + }], + "principals": [{ + "authenticated": { + "principalName": { + "safeRegex": { + "regex":"^spiffe://foo.consul/ap/default/ns/default/identity/foo$" + } + } + } + }] + } + } + } } }, { @@ -303,7 +354,24 @@ "name": "envoy.filters.network.rbac", "typedConfig": { "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC", - "rules": {}, + "rules": { + "policies": { + "consul-intentions-layer4": { + "permissions": [{ + "any": true + }], + "principals": [{ + "authenticated": { + "principalName": { + "safeRegex": { + "regex":"^spiffe://foo.consul/ap/default/ns/default/identity/foo$" + } + } + } + }] + } + } + }, "statPrefix": "connect_authz" } }, diff --git a/internal/auth/internal/types/errors.go b/internal/auth/internal/types/errors.go index b11fac6304..81e7e502c7 100644 --- a/internal/auth/internal/types/errors.go +++ b/internal/auth/internal/types/errors.go @@ -11,6 +11,6 @@ var ( 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") + errHeaderRulesInvalid = errors.New("header rule must contain header name") ErrWildcardNotSupported = errors.New("traffic permissions without explicit destinations are not yet supported") - ErrL7NotSupported = errors.New("traffic permissions with L7 rules are not yet supported") ) diff --git a/internal/auth/internal/types/traffic_permissions.go b/internal/auth/internal/types/traffic_permissions.go index 6b03c362a2..32d9cd27a9 100644 --- a/internal/auth/internal/types/traffic_permissions.go +++ b/internal/auth/internal/types/traffic_permissions.go @@ -217,13 +217,6 @@ func validatePermission(p *pbauth.Permission, id *pbresource.ID, wrapErr func(er Wrapped: err, }) } - // TODO: remove this when L7 traffic permissions are implemented - if len(dest.PathExact) > 0 || len(dest.PathPrefix) > 0 || len(dest.PathRegex) > 0 || len(dest.Methods) > 0 || dest.Header != nil { - merr = multierror.Append(merr, wrapDestRuleErr(resource.ErrInvalidListElement{ - Name: "destination_rule", - Wrapped: ErrL7NotSupported, - })) - } 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) { @@ -232,6 +225,23 @@ func validatePermission(p *pbauth.Permission, id *pbresource.ID, wrapErr func(er Wrapped: errInvalidPrefixValues, })) } + if len(dest.Headers) > 0 { + for h, hdr := range dest.Headers { + wrapHeaderErr := func(err error) error { + return wrapDestRuleErr(resource.ErrInvalidListElement{ + Name: "destination_header_rules", + Index: h, + Wrapped: err, + }) + } + if len(hdr.Name) == 0 { + merr = multierror.Append(merr, wrapHeaderErr(resource.ErrInvalidListElement{ + Name: "destination_header_rule", + Wrapped: errHeaderRulesInvalid, + })) + } + } + } if len(dest.Exclude) > 0 { for e, excl := range dest.Exclude { wrapExclPermRuleErr := func(err error) error { @@ -241,13 +251,6 @@ func validatePermission(p *pbauth.Permission, id *pbresource.ID, wrapErr func(er Wrapped: err, }) } - // TODO: remove this when L7 traffic permissions are implemented - if len(excl.PathExact) > 0 || len(excl.PathPrefix) > 0 || len(excl.PathRegex) > 0 || len(excl.Methods) > 0 || excl.Header != nil { - merr = multierror.Append(merr, wrapDestRuleErr(resource.ErrInvalidListElement{ - Name: "exclude_permission_rules", - Wrapped: ErrL7NotSupported, - })) - } 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) { diff --git a/internal/auth/internal/types/traffic_permissions_test.go b/internal/auth/internal/types/traffic_permissions_test.go index 5f793813c4..ee24cc1417 100644 --- a/internal/auth/internal/types/traffic_permissions_test.go +++ b/internal/auth/internal/types/traffic_permissions_test.go @@ -92,76 +92,6 @@ func TestValidateTrafficPermissions(t *testing.T) { }, expectErr: `invalid element at index 0 of list "permissions": invalid element at index 0 of list "sources": invalid element at index 0 of list "source": permissions sources may not specify partitions, peers, and sameness_groups together`, }, - // TODO: remove when L7 traffic permissions are implemented - "l7-fields-path": { - tp: &pbauth.TrafficPermissions{ - Destination: &pbauth.Destination{ - IdentityName: "w1", - }, - Action: pbauth.Action_ACTION_ALLOW, - Permissions: []*pbauth.Permission{ - { - Sources: []*pbauth.Source{ - { - Partition: "ap1", - }, - }, - DestinationRules: []*pbauth.DestinationRule{ - { - PathExact: "wi2", - }, - }, - }, - }, - }, - expectErr: `invalid element at index 0 of list "permissions": invalid element at index 0 of list "destination_rules": invalid element at index 0 of list "destination_rule": traffic permissions with L7 rules are not yet supported`, - }, - "l7-fields-methods": { - tp: &pbauth.TrafficPermissions{ - Destination: &pbauth.Destination{ - IdentityName: "w1", - }, - Action: pbauth.Action_ACTION_ALLOW, - Permissions: []*pbauth.Permission{ - { - Sources: []*pbauth.Source{ - { - Partition: "ap1", - }, - }, - DestinationRules: []*pbauth.DestinationRule{ - { - Methods: []string{"PUT"}, - }, - }, - }, - }, - }, - expectErr: `invalid element at index 0 of list "permissions": invalid element at index 0 of list "destination_rules": invalid element at index 0 of list "destination_rule": traffic permissions with L7 rules are not yet supported`, - }, - "l7-fields-header": { - tp: &pbauth.TrafficPermissions{ - Destination: &pbauth.Destination{ - IdentityName: "w1", - }, - Action: pbauth.Action_ACTION_ALLOW, - Permissions: []*pbauth.Permission{ - { - Sources: []*pbauth.Source{ - { - Partition: "ap1", - }, - }, - DestinationRules: []*pbauth.DestinationRule{ - { - Header: &pbauth.DestinationRuleHeader{Name: "foo"}, - }, - }, - }, - }, - }, - expectErr: `invalid element at index 0 of list "permissions": invalid element at index 0 of list "destination_rules": invalid element at index 0 of list "destination_rule": traffic permissions with L7 rules are not yet supported`, - }, "source-has-same-tenancy-as-tp": { id: &pbresource.ID{ Tenancy: &pbresource.Tenancy{ diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/local_app.go b/internal/mesh/internal/controllers/sidecarproxy/builder/local_app.go index 8405b639c7..5ae549a4dd 100644 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/local_app.go +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/local_app.go @@ -6,9 +6,10 @@ package builder import ( "fmt" - pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" "google.golang.org/protobuf/types/known/wrapperspb" + pbmesh "github.com/hashicorp/consul/proto-public/pbmesh/v2beta1" + "github.com/hashicorp/consul/agent/connect" "github.com/hashicorp/consul/envoyextensions/xdscommon" pbauth "github.com/hashicorp/consul/proto-public/pbauth/v2beta1" @@ -90,35 +91,45 @@ func buildTrafficPermissions(globalDefaultAllow bool, trustDomain string, worklo for _, p := range computed.DenyPermissions { drsByPort := destinationRulesByPort(allPorts, p.DestinationRules) principals := makePrincipals(trustDomain, p) - for port := range drsByPort { - out[port].DenyPermissions = append(out[port].DenyPermissions, &pbproxystate.Permission{ - Principals: principals, - }) + for port, rules := range drsByPort { + if len(rules) > 0 { + out[port].DenyPermissions = append(out[port].DenyPermissions, &pbproxystate.Permission{ + Principals: principals, + DestinationRules: rules, + }) + } else { + out[port].DenyPermissions = append(out[port].DenyPermissions, &pbproxystate.Permission{ + Principals: principals, + }) + } } } for _, p := range computed.AllowPermissions { drsByPort := destinationRulesByPort(allPorts, p.DestinationRules) principals := makePrincipals(trustDomain, p) - for port := range drsByPort { + for port, rules := range drsByPort { if _, ok := out[port]; !ok { continue } - - out[port].AllowPermissions = append(out[port].AllowPermissions, &pbproxystate.Permission{ - Principals: principals, - }) + if len(rules) > 0 { + out[port].AllowPermissions = append(out[port].AllowPermissions, &pbproxystate.Permission{ + Principals: principals, + DestinationRules: rules, + }) + } else { + out[port].AllowPermissions = append(out[port].AllowPermissions, &pbproxystate.Permission{ + Principals: principals, + }) + } } } return out } -// TODO this is a placeholder until we add them to the IR. -type DestinationRule struct{} - -func destinationRulesByPort(allPorts []string, destinationRules []*pbauth.DestinationRule) map[string][]DestinationRule { - out := make(map[string][]DestinationRule) +func destinationRulesByPort(allPorts []string, destinationRules []*pbauth.DestinationRule) map[string][]*pbproxystate.DestinationRule { + out := make(map[string][]*pbproxystate.DestinationRule) if len(destinationRules) == 0 { for _, p := range allPorts { @@ -131,6 +142,10 @@ func destinationRulesByPort(allPorts []string, destinationRules []*pbauth.Destin for _, destinationRule := range destinationRules { ports, dr := convertDestinationRule(allPorts, destinationRule) for _, p := range ports { + if dr == nil { + out[p] = nil + continue + } out[p] = append(out[p], dr) } } @@ -139,7 +154,7 @@ func destinationRulesByPort(allPorts []string, destinationRules []*pbauth.Destin } //nolint:unparam -func convertDestinationRule(allPorts []string, dr *pbauth.DestinationRule) ([]string, DestinationRule) { +func convertDestinationRule(allPorts []string, dr *pbauth.DestinationRule) ([]string, *pbproxystate.DestinationRule) { ports := make(map[string]struct{}) if len(dr.PortNames) > 0 { for _, p := range dr.PortNames { @@ -162,7 +177,35 @@ func convertDestinationRule(allPorts []string, dr *pbauth.DestinationRule) ([]st out = append(out, p) } - return out, DestinationRule{} + if len(dr.String()) == 0 { + return out, nil + } + + psdr := &pbproxystate.DestinationRule{ + PathExact: dr.PathExact, + PathPrefix: dr.PathPrefix, + PathRegex: dr.PathRegex, + Methods: dr.Methods, + } + hrs := make([]*pbproxystate.DestinationRuleHeader, len(dr.Headers)) + for i, hr := range dr.Headers { + hrs[i] = &pbproxystate.DestinationRuleHeader{ + Name: hr.Name, + Present: hr.Present, + Exact: hr.Exact, + Prefix: hr.Prefix, + Suffix: hr.Suffix, + Regex: hr.Regex, + Invert: hr.Invert, + } + } + psdr.DestinationRuleHeader = hrs + + if len(psdr.String()) > 0 { + return out, psdr + } + + return out, nil } func makePrincipals(trustDomain string, perm *pbauth.Permission) []*pbproxystate.Principal { diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/local_app_test.go b/internal/mesh/internal/controllers/sidecarproxy/builder/local_app_test.go index f26ca706ed..b1399cfa23 100644 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/local_app_test.go +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/local_app_test.go @@ -9,9 +9,10 @@ import ( "testing" "time" - "github.com/stretchr/testify/require" "google.golang.org/protobuf/types/known/durationpb" + "github.com/stretchr/testify/require" + "github.com/hashicorp/consul/internal/resource/resourcetest" "github.com/hashicorp/consul/internal/testing/golden" pbauth "github.com/hashicorp/consul/proto-public/pbauth/v2beta1" @@ -103,8 +104,8 @@ func TestBuildLocalApp(t *testing.T) { for name, c := range cases { t.Run(resourcetest.AppendTenancyInfoSubtest(t.Name(), name, tenancy), func(t *testing.T) { - proxyTmpl := New(testProxyStateTemplateID(tenancy), testIdentityRef(tenancy), "foo.consul", "dc1", true, nil). - BuildLocalApp(c.workload, nil). + proxyTmpl := New(testProxyStateTemplateID(tenancy), testIdentityRef(tenancy), "foo.consul", "dc1", c.defaultAllow, nil). + BuildLocalApp(c.workload, c.ctp). Build() // sort routers because of test flakes where order was flip flopping. @@ -168,7 +169,7 @@ func TestBuildLocalApp_WithProxyConfiguration(t *testing.T) { }, }, }, - // source/local-and-inbound-connections shows that configuring LocalCOnnection + // source/local-and-inbound-connections shows that configuring LocalConnection // and InboundConnections in DynamicConfig will set fields on standard clusters and routes, // but will not set fields on exposed path clusters and routes. "source/local-and-inbound-connections": { @@ -247,7 +248,7 @@ func TestBuildLocalApp_WithProxyConfiguration(t *testing.T) { }, t) } -func TestBuildL4TrafficPermissions(t *testing.T) { +func TestBuildTrafficPermissions(t *testing.T) { resourcetest.RunWithTenancies(func(tenancy *pbresource.Tenancy) { testTrustDomain := "test.consul" @@ -498,6 +499,54 @@ func TestBuildL4TrafficPermissions(t *testing.T) { }, }, }, + "preserves default deny http rules": { + defaultAllow: false, + workloadPorts: map[string]*pbcatalog.WorkloadPort{ + "p2": { + Protocol: pbcatalog.Protocol_PROTOCOL_HTTP, + }, + }, + ctp: &pbauth.ComputedTrafficPermissions{ + AllowPermissions: []*pbauth.Permission{ + { + Sources: []*pbauth.Source{ + { + IdentityName: "foo", + Partition: tenancy.Partition, + Namespace: tenancy.Namespace, + }, + }, + DestinationRules: []*pbauth.DestinationRule{ + { + PortNames: []string{"p2"}, + Methods: []string{"GET"}, + PathExact: "/bar", + }, + }, + }, + }, + }, + expected: map[string]*pbproxystate.TrafficPermissions{ + "p2": { + DefaultAllow: false, + AllowPermissions: []*pbproxystate.Permission{ + { + Principals: []*pbproxystate.Principal{ + { + Spiffe: &pbproxystate.Spiffe{Regex: fmt.Sprintf("^spiffe://test.consul/ap/%s/ns/%s/identity/foo$", tenancy.Partition, tenancy.Namespace)}, + }, + }, + DestinationRules: []*pbproxystate.DestinationRule{ + { + PathExact: "/bar", + Methods: []string{"GET"}, + }, + }, + }, + }, + }, + }, + }, "kitchen sink": { defaultAllow: true, workloadPorts: map[string]*pbcatalog.WorkloadPort{ diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiple-workload-addresses-with-specific-ports-default-bar.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiple-workload-addresses-with-specific-ports-default-bar.golden index 9fb74bcac2..e9f966b463 100644 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiple-workload-addresses-with-specific-ports-default-bar.golden +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiple-workload-addresses-with-specific-ports-default-bar.golden @@ -115,7 +115,19 @@ }, "statPrefix": "public_listener", "staticRoute": true, - "trafficPermissions": {} + "trafficPermissions": { + "allowPermissions": [ + { + "principals": [ + { + "spiffe": { + "regex": "^spiffe://foo.consul/ap/default/ns/default/identity/foo$" + } + } + ] + } + ] + } }, "match": { "alpnProtocols": [ @@ -140,7 +152,19 @@ }, "statPrefix": "public_listener", "staticRoute": true, - "trafficPermissions": {} + "trafficPermissions": { + "allowPermissions": [ + { + "principals": [ + { + "spiffe": { + "regex": "^spiffe://foo.consul/ap/default/ns/default/identity/foo$" + } + } + ] + } + ] + } }, "match": { "alpnProtocols": [ @@ -166,7 +190,19 @@ }, "statPrefix": "public_listener", "staticRoute": true, - "trafficPermissions": {} + "trafficPermissions": { + "allowPermissions": [ + { + "principals": [ + { + "spiffe": { + "regex": "^spiffe://foo.consul/ap/default/ns/default/identity/foo$" + } + } + ] + } + ] + } }, "match": { "alpnProtocols": [ @@ -190,7 +226,19 @@ "name": "local_app:tcp" }, "statPrefix": "public_listener", - "trafficPermissions": {} + "trafficPermissions": { + "allowPermissions": [ + { + "principals": [ + { + "spiffe": { + "regex": "^spiffe://foo.consul/ap/default/ns/default/identity/foo$" + } + } + ] + } + ] + } }, "match": { "alpnProtocols": [ diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiple-workload-addresses-with-specific-ports-default-default.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiple-workload-addresses-with-specific-ports-default-default.golden index 70d0232467..7fbbf8485a 100644 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiple-workload-addresses-with-specific-ports-default-default.golden +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiple-workload-addresses-with-specific-ports-default-default.golden @@ -115,7 +115,19 @@ }, "statPrefix": "public_listener", "staticRoute": true, - "trafficPermissions": {} + "trafficPermissions": { + "allowPermissions": [ + { + "principals": [ + { + "spiffe": { + "regex": "^spiffe://foo.consul/ap/default/ns/default/identity/foo$" + } + } + ] + } + ] + } }, "match": { "alpnProtocols": [ @@ -140,7 +152,19 @@ }, "statPrefix": "public_listener", "staticRoute": true, - "trafficPermissions": {} + "trafficPermissions": { + "allowPermissions": [ + { + "principals": [ + { + "spiffe": { + "regex": "^spiffe://foo.consul/ap/default/ns/default/identity/foo$" + } + } + ] + } + ] + } }, "match": { "alpnProtocols": [ @@ -166,7 +190,19 @@ }, "statPrefix": "public_listener", "staticRoute": true, - "trafficPermissions": {} + "trafficPermissions": { + "allowPermissions": [ + { + "principals": [ + { + "spiffe": { + "regex": "^spiffe://foo.consul/ap/default/ns/default/identity/foo$" + } + } + ] + } + ] + } }, "match": { "alpnProtocols": [ @@ -190,7 +226,19 @@ "name": "local_app:tcp" }, "statPrefix": "public_listener", - "trafficPermissions": {} + "trafficPermissions": { + "allowPermissions": [ + { + "principals": [ + { + "spiffe": { + "regex": "^spiffe://foo.consul/ap/default/ns/default/identity/foo$" + } + } + ] + } + ] + } }, "match": { "alpnProtocols": [ diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiple-workload-addresses-with-specific-ports-foo-bar.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiple-workload-addresses-with-specific-ports-foo-bar.golden index 053dab78e2..5dc855460b 100644 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiple-workload-addresses-with-specific-ports-foo-bar.golden +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiple-workload-addresses-with-specific-ports-foo-bar.golden @@ -115,7 +115,19 @@ }, "statPrefix": "public_listener", "staticRoute": true, - "trafficPermissions": {} + "trafficPermissions": { + "allowPermissions": [ + { + "principals": [ + { + "spiffe": { + "regex": "^spiffe://foo.consul/ap/default/ns/default/identity/foo$" + } + } + ] + } + ] + } }, "match": { "alpnProtocols": [ @@ -140,7 +152,19 @@ }, "statPrefix": "public_listener", "staticRoute": true, - "trafficPermissions": {} + "trafficPermissions": { + "allowPermissions": [ + { + "principals": [ + { + "spiffe": { + "regex": "^spiffe://foo.consul/ap/default/ns/default/identity/foo$" + } + } + ] + } + ] + } }, "match": { "alpnProtocols": [ @@ -166,7 +190,19 @@ }, "statPrefix": "public_listener", "staticRoute": true, - "trafficPermissions": {} + "trafficPermissions": { + "allowPermissions": [ + { + "principals": [ + { + "spiffe": { + "regex": "^spiffe://foo.consul/ap/default/ns/default/identity/foo$" + } + } + ] + } + ] + } }, "match": { "alpnProtocols": [ @@ -190,7 +226,19 @@ "name": "local_app:tcp" }, "statPrefix": "public_listener", - "trafficPermissions": {} + "trafficPermissions": { + "allowPermissions": [ + { + "principals": [ + { + "spiffe": { + "regex": "^spiffe://foo.consul/ap/default/ns/default/identity/foo$" + } + } + ] + } + ] + } }, "match": { "alpnProtocols": [ diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiple-workload-addresses-with-specific-ports-foo-default.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiple-workload-addresses-with-specific-ports-foo-default.golden index cce0e46779..fd3f8dd78c 100644 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiple-workload-addresses-with-specific-ports-foo-default.golden +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiple-workload-addresses-with-specific-ports-foo-default.golden @@ -115,7 +115,19 @@ }, "statPrefix": "public_listener", "staticRoute": true, - "trafficPermissions": {} + "trafficPermissions": { + "allowPermissions": [ + { + "principals": [ + { + "spiffe": { + "regex": "^spiffe://foo.consul/ap/default/ns/default/identity/foo$" + } + } + ] + } + ] + } }, "match": { "alpnProtocols": [ @@ -140,7 +152,19 @@ }, "statPrefix": "public_listener", "staticRoute": true, - "trafficPermissions": {} + "trafficPermissions": { + "allowPermissions": [ + { + "principals": [ + { + "spiffe": { + "regex": "^spiffe://foo.consul/ap/default/ns/default/identity/foo$" + } + } + ] + } + ] + } }, "match": { "alpnProtocols": [ @@ -166,7 +190,19 @@ }, "statPrefix": "public_listener", "staticRoute": true, - "trafficPermissions": {} + "trafficPermissions": { + "allowPermissions": [ + { + "principals": [ + { + "spiffe": { + "regex": "^spiffe://foo.consul/ap/default/ns/default/identity/foo$" + } + } + ] + } + ] + } }, "match": { "alpnProtocols": [ @@ -190,7 +226,19 @@ "name": "local_app:tcp" }, "statPrefix": "public_listener", - "trafficPermissions": {} + "trafficPermissions": { + "allowPermissions": [ + { + "principals": [ + { + "spiffe": { + "regex": "^spiffe://foo.consul/ap/default/ns/default/identity/foo$" + } + } + ] + } + ] + } }, "match": { "alpnProtocols": [ diff --git a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiple-workload-addresses-with-specific-ports.golden b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiple-workload-addresses-with-specific-ports.golden index 70d0232467..7fbbf8485a 100644 --- a/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiple-workload-addresses-with-specific-ports.golden +++ b/internal/mesh/internal/controllers/sidecarproxy/builder/testdata/source/multiple-workload-addresses-with-specific-ports.golden @@ -115,7 +115,19 @@ }, "statPrefix": "public_listener", "staticRoute": true, - "trafficPermissions": {} + "trafficPermissions": { + "allowPermissions": [ + { + "principals": [ + { + "spiffe": { + "regex": "^spiffe://foo.consul/ap/default/ns/default/identity/foo$" + } + } + ] + } + ] + } }, "match": { "alpnProtocols": [ @@ -140,7 +152,19 @@ }, "statPrefix": "public_listener", "staticRoute": true, - "trafficPermissions": {} + "trafficPermissions": { + "allowPermissions": [ + { + "principals": [ + { + "spiffe": { + "regex": "^spiffe://foo.consul/ap/default/ns/default/identity/foo$" + } + } + ] + } + ] + } }, "match": { "alpnProtocols": [ @@ -166,7 +190,19 @@ }, "statPrefix": "public_listener", "staticRoute": true, - "trafficPermissions": {} + "trafficPermissions": { + "allowPermissions": [ + { + "principals": [ + { + "spiffe": { + "regex": "^spiffe://foo.consul/ap/default/ns/default/identity/foo$" + } + } + ] + } + ] + } }, "match": { "alpnProtocols": [ @@ -190,7 +226,19 @@ "name": "local_app:tcp" }, "statPrefix": "public_listener", - "trafficPermissions": {} + "trafficPermissions": { + "allowPermissions": [ + { + "principals": [ + { + "spiffe": { + "regex": "^spiffe://foo.consul/ap/default/ns/default/identity/foo$" + } + } + ] + } + ] + } }, "match": { "alpnProtocols": [ diff --git a/internal/mesh/internal/controllers/xds/testdata/source/multiple-workload-addresses-with-specific-ports.golden b/internal/mesh/internal/controllers/xds/testdata/source/multiple-workload-addresses-with-specific-ports.golden index b67d034c7e..fc5f812a6e 100644 --- a/internal/mesh/internal/controllers/xds/testdata/source/multiple-workload-addresses-with-specific-ports.golden +++ b/internal/mesh/internal/controllers/xds/testdata/source/multiple-workload-addresses-with-specific-ports.golden @@ -120,7 +120,19 @@ }, "statPrefix": "public_listener", "staticRoute": true, - "trafficPermissions": {} + "trafficPermissions": { + "allowPermissions": [ + { + "principals": [ + { + "spiffe": { + "regex": "^spiffe://foo.consul/ap/default/ns/default/identity/foo$" + } + } + ] + } + ] + } }, "match": { "alpnProtocols": [ @@ -145,7 +157,19 @@ }, "statPrefix": "public_listener", "staticRoute": true, - "trafficPermissions": {} + "trafficPermissions": { + "allowPermissions": [ + { + "principals": [ + { + "spiffe": { + "regex": "^spiffe://foo.consul/ap/default/ns/default/identity/foo$" + } + } + ] + } + ] + } }, "match": { "alpnProtocols": [ @@ -171,7 +195,19 @@ }, "statPrefix": "public_listener", "staticRoute": true, - "trafficPermissions": {} + "trafficPermissions": { + "allowPermissions": [ + { + "principals": [ + { + "spiffe": { + "regex": "^spiffe://foo.consul/ap/default/ns/default/identity/foo$" + } + } + ] + } + ] + } }, "match": { "alpnProtocols": [ @@ -195,7 +231,19 @@ "name": "local_app:tcp" }, "statPrefix": "public_listener", - "trafficPermissions": {} + "trafficPermissions": { + "allowPermissions": [ + { + "principals": [ + { + "spiffe": { + "regex": "^spiffe://foo.consul/ap/default/ns/default/identity/foo$" + } + } + ] + } + ] + } }, "match": { "alpnProtocols": [ diff --git a/proto-public/pbauth/v2beta1/traffic_permissions.pb.go b/proto-public/pbauth/v2beta1/traffic_permissions.pb.go index e6708a3f73..c1d489c114 100644 --- a/proto-public/pbauth/v2beta1/traffic_permissions.pb.go +++ b/proto-public/pbauth/v2beta1/traffic_permissions.pb.go @@ -554,9 +554,9 @@ type DestinationRule struct { PathRegex string `protobuf:"bytes,3,opt,name=path_regex,json=pathRegex,proto3" json:"path_regex,omitempty"` // Methods is the list of HTTP methods. If no methods are specified, // this rule will apply to all methods. - Methods []string `protobuf:"bytes,4,rep,name=methods,proto3" json:"methods,omitempty"` - Header *DestinationRuleHeader `protobuf:"bytes,5,opt,name=header,proto3" json:"header,omitempty"` - PortNames []string `protobuf:"bytes,6,rep,name=port_names,json=portNames,proto3" json:"port_names,omitempty"` + Methods []string `protobuf:"bytes,4,rep,name=methods,proto3" json:"methods,omitempty"` + Headers []*DestinationRuleHeader `protobuf:"bytes,5,rep,name=headers,proto3" json:"headers,omitempty"` + PortNames []string `protobuf:"bytes,6,rep,name=port_names,json=portNames,proto3" json:"port_names,omitempty"` // Exclude contains a list of rules to exclude when evaluating rules for the incoming connection. Exclude []*ExcludePermissionRule `protobuf:"bytes,7,rep,name=exclude,proto3" json:"exclude,omitempty"` } @@ -621,9 +621,9 @@ func (x *DestinationRule) GetMethods() []string { return nil } -func (x *DestinationRule) GetHeader() *DestinationRuleHeader { +func (x *DestinationRule) GetHeaders() []*DestinationRuleHeader { if x != nil { - return x.Header + return x.Headers } return nil } @@ -651,8 +651,8 @@ type ExcludePermissionRule struct { PathPrefix string `protobuf:"bytes,2,opt,name=path_prefix,json=pathPrefix,proto3" json:"path_prefix,omitempty"` PathRegex string `protobuf:"bytes,3,opt,name=path_regex,json=pathRegex,proto3" json:"path_regex,omitempty"` // Methods is the list of HTTP methods. - Methods []string `protobuf:"bytes,4,rep,name=methods,proto3" json:"methods,omitempty"` - Header *DestinationRuleHeader `protobuf:"bytes,5,opt,name=header,proto3" json:"header,omitempty"` + Methods []string `protobuf:"bytes,4,rep,name=methods,proto3" json:"methods,omitempty"` + Headers []*DestinationRuleHeader `protobuf:"bytes,5,rep,name=headers,proto3" json:"headers,omitempty"` // PortNames is a list of workload ports to apply this rule to. The ports specified here // must be the ports used in the connection. PortNames []string `protobuf:"bytes,6,rep,name=port_names,json=portNames,proto3" json:"port_names,omitempty"` @@ -718,9 +718,9 @@ func (x *ExcludePermissionRule) GetMethods() []string { return nil } -func (x *ExcludePermissionRule) GetHeader() *DestinationRuleHeader { +func (x *ExcludePermissionRule) GetHeaders() []*DestinationRuleHeader { if x != nil { - return x.Header + return x.Headers } return nil } @@ -914,7 +914,7 @@ var file_pbauth_v2beta1_traffic_permissions_proto_rawDesc = []byte{ 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, + 0x73, 0x47, 0x72, 0x6f, 0x75, 0x70, 0x22, 0xc9, 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, @@ -923,69 +923,69 @@ var file_pbauth_v2beta1_traffic_permissions_proto_rawDesc = []byte{ 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, + 0x6f, 0x64, 0x73, 0x12, 0x4e, 0x0a, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x18, 0x05, + 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, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x52, 0x75, 0x6c, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x07, 0x68, 0x65, 0x61, 0x64, + 0x65, 0x72, 0x73, 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, 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, + 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, 0xff, 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, 0x4e, 0x0a, 0x07, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, + 0x18, 0x05, 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, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, + 0x6f, 0x6e, 0x52, 0x75, 0x6c, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x07, 0x68, 0x65, + 0x61, 0x64, 0x65, 0x72, 0x73, 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 ( @@ -1026,9 +1026,9 @@ var file_pbauth_v2beta1_traffic_permissions_proto_depIdxs = []int32{ 6, // 7: hashicorp.consul.auth.v2beta1.Permission.sources:type_name -> hashicorp.consul.auth.v2beta1.Source 8, // 8: hashicorp.consul.auth.v2beta1.Permission.destination_rules:type_name -> hashicorp.consul.auth.v2beta1.DestinationRule 7, // 9: hashicorp.consul.auth.v2beta1.Source.exclude:type_name -> hashicorp.consul.auth.v2beta1.ExcludeSource - 10, // 10: hashicorp.consul.auth.v2beta1.DestinationRule.header:type_name -> hashicorp.consul.auth.v2beta1.DestinationRuleHeader + 10, // 10: hashicorp.consul.auth.v2beta1.DestinationRule.headers:type_name -> hashicorp.consul.auth.v2beta1.DestinationRuleHeader 9, // 11: hashicorp.consul.auth.v2beta1.DestinationRule.exclude:type_name -> hashicorp.consul.auth.v2beta1.ExcludePermissionRule - 10, // 12: hashicorp.consul.auth.v2beta1.ExcludePermissionRule.header:type_name -> hashicorp.consul.auth.v2beta1.DestinationRuleHeader + 10, // 12: hashicorp.consul.auth.v2beta1.ExcludePermissionRule.headers:type_name -> hashicorp.consul.auth.v2beta1.DestinationRuleHeader 13, // [13:13] is the sub-list for method output_type 13, // [13:13] is the sub-list for method input_type 13, // [13:13] is the sub-list for extension type_name diff --git a/proto-public/pbauth/v2beta1/traffic_permissions.proto b/proto-public/pbauth/v2beta1/traffic_permissions.proto index c30cad1c4d..3b6ba61dbd 100644 --- a/proto-public/pbauth/v2beta1/traffic_permissions.proto +++ b/proto-public/pbauth/v2beta1/traffic_permissions.proto @@ -101,7 +101,7 @@ message DestinationRule { // Methods is the list of HTTP methods. If no methods are specified, // this rule will apply to all methods. repeated string methods = 4; - DestinationRuleHeader header = 5; + repeated DestinationRuleHeader headers = 5; repeated string port_names = 6; // Exclude contains a list of rules to exclude when evaluating rules for the incoming connection. repeated ExcludePermissionRule exclude = 7; @@ -114,7 +114,7 @@ message ExcludePermissionRule { // Methods is the list of HTTP methods. repeated string methods = 4; - DestinationRuleHeader header = 5; + repeated DestinationRuleHeader headers = 5; // PortNames is a list of workload ports to apply this rule to. The ports specified here // must be the ports used in the connection. diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/traffic_permissions.pb.binary.go b/proto-public/pbmesh/v2beta1/pbproxystate/traffic_permissions.pb.binary.go index 403b64f469..ca4199c72a 100644 --- a/proto-public/pbmesh/v2beta1/pbproxystate/traffic_permissions.pb.binary.go +++ b/proto-public/pbmesh/v2beta1/pbproxystate/traffic_permissions.pb.binary.go @@ -46,3 +46,23 @@ func (msg *Spiffe) MarshalBinary() ([]byte, error) { func (msg *Spiffe) UnmarshalBinary(b []byte) error { return proto.Unmarshal(b, msg) } + +// MarshalBinary implements encoding.BinaryMarshaler +func (msg *DestinationRule) MarshalBinary() ([]byte, error) { + return proto.Marshal(msg) +} + +// UnmarshalBinary implements encoding.BinaryUnmarshaler +func (msg *DestinationRule) UnmarshalBinary(b []byte) error { + return proto.Unmarshal(b, msg) +} + +// MarshalBinary implements encoding.BinaryMarshaler +func (msg *DestinationRuleHeader) MarshalBinary() ([]byte, error) { + return proto.Marshal(msg) +} + +// UnmarshalBinary implements encoding.BinaryUnmarshaler +func (msg *DestinationRuleHeader) UnmarshalBinary(b []byte) error { + return proto.Unmarshal(b, msg) +} diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/traffic_permissions.pb.go b/proto-public/pbmesh/v2beta1/pbproxystate/traffic_permissions.pb.go index adbccab0eb..d6bb8cc435 100644 --- a/proto-public/pbmesh/v2beta1/pbproxystate/traffic_permissions.pb.go +++ b/proto-public/pbmesh/v2beta1/pbproxystate/traffic_permissions.pb.go @@ -95,6 +95,9 @@ type Permission struct { unknownFields protoimpl.UnknownFields Principals []*Principal `protobuf:"bytes,1,rep,name=principals,proto3" json:"principals,omitempty"` + // In the case of multiple ports, the sidecar proxy controller is responsible for filtering + // per-port permissions. + DestinationRules []*DestinationRule `protobuf:"bytes,2,rep,name=destination_rules,json=destinationRules,proto3" json:"destination_rules,omitempty"` } func (x *Permission) Reset() { @@ -136,6 +139,13 @@ func (x *Permission) GetPrincipals() []*Principal { return nil } +func (x *Permission) GetDestinationRules() []*DestinationRule { + if x != nil { + return x.DestinationRules + } + return nil +} + type Principal struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -249,6 +259,180 @@ func (x *Spiffe) GetXfccRegex() string { return "" } +type DestinationRule struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + PathExact string `protobuf:"bytes,1,opt,name=path_exact,json=pathExact,proto3" json:"path_exact,omitempty"` + PathPrefix string `protobuf:"bytes,2,opt,name=path_prefix,json=pathPrefix,proto3" json:"path_prefix,omitempty"` + PathRegex string `protobuf:"bytes,3,opt,name=path_regex,json=pathRegex,proto3" json:"path_regex,omitempty"` + Methods []string `protobuf:"bytes,4,rep,name=methods,proto3" json:"methods,omitempty"` + DestinationRuleHeader []*DestinationRuleHeader `protobuf:"bytes,5,rep,name=destination_rule_header,json=destinationRuleHeader,proto3" json:"destination_rule_header,omitempty"` +} + +func (x *DestinationRule) Reset() { + *x = DestinationRule{} + if protoimpl.UnsafeEnabled { + mi := &file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DestinationRule) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DestinationRule) ProtoMessage() {} + +func (x *DestinationRule) ProtoReflect() protoreflect.Message { + mi := &file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_msgTypes[4] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DestinationRule.ProtoReflect.Descriptor instead. +func (*DestinationRule) Descriptor() ([]byte, []int) { + return file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_rawDescGZIP(), []int{4} +} + +func (x *DestinationRule) GetPathExact() string { + if x != nil { + return x.PathExact + } + return "" +} + +func (x *DestinationRule) GetPathPrefix() string { + if x != nil { + return x.PathPrefix + } + return "" +} + +func (x *DestinationRule) GetPathRegex() string { + if x != nil { + return x.PathRegex + } + return "" +} + +func (x *DestinationRule) GetMethods() []string { + if x != nil { + return x.Methods + } + return nil +} + +func (x *DestinationRule) GetDestinationRuleHeader() []*DestinationRuleHeader { + if x != nil { + return x.DestinationRuleHeader + } + return nil +} + +type DestinationRuleHeader struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Present bool `protobuf:"varint,2,opt,name=present,proto3" json:"present,omitempty"` + Exact string `protobuf:"bytes,3,opt,name=exact,proto3" json:"exact,omitempty"` + Prefix string `protobuf:"bytes,4,opt,name=prefix,proto3" json:"prefix,omitempty"` + Suffix string `protobuf:"bytes,5,opt,name=suffix,proto3" json:"suffix,omitempty"` + Regex string `protobuf:"bytes,6,opt,name=regex,proto3" json:"regex,omitempty"` + Invert bool `protobuf:"varint,7,opt,name=invert,proto3" json:"invert,omitempty"` +} + +func (x *DestinationRuleHeader) Reset() { + *x = DestinationRuleHeader{} + if protoimpl.UnsafeEnabled { + mi := &file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *DestinationRuleHeader) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*DestinationRuleHeader) ProtoMessage() {} + +func (x *DestinationRuleHeader) ProtoReflect() protoreflect.Message { + mi := &file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_msgTypes[5] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use DestinationRuleHeader.ProtoReflect.Descriptor instead. +func (*DestinationRuleHeader) Descriptor() ([]byte, []int) { + return file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_rawDescGZIP(), []int{5} +} + +func (x *DestinationRuleHeader) GetName() string { + if x != nil { + return x.Name + } + return "" +} + +func (x *DestinationRuleHeader) GetPresent() bool { + if x != nil { + return x.Present + } + return false +} + +func (x *DestinationRuleHeader) GetExact() string { + if x != nil { + return x.Exact + } + return "" +} + +func (x *DestinationRuleHeader) GetPrefix() string { + if x != nil { + return x.Prefix + } + return "" +} + +func (x *DestinationRuleHeader) GetSuffix() string { + if x != nil { + return x.Suffix + } + return "" +} + +func (x *DestinationRuleHeader) GetRegex() string { + if x != nil { + return x.Regex + } + return "" +} + +func (x *DestinationRuleHeader) GetInvert() bool { + if x != nil { + return x.Invert + } + return false +} + var File_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto protoreflect.FileDescriptor var file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_rawDesc = []byte{ @@ -274,51 +458,86 @@ var file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_rawDesc = []byte{ 0x6e, 0x52, 0x0f, 0x64, 0x65, 0x6e, 0x79, 0x50, 0x65, 0x72, 0x6d, 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x23, 0x0a, 0x0d, 0x64, 0x65, 0x66, 0x61, 0x75, 0x6c, 0x74, 0x5f, 0x61, 0x6c, 0x6c, 0x6f, 0x77, 0x18, 0x04, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0c, 0x64, 0x65, 0x66, 0x61, 0x75, - 0x6c, 0x74, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x22, 0x63, 0x0a, 0x0a, 0x50, 0x65, 0x72, 0x6d, 0x69, - 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x55, 0x0a, 0x0a, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, - 0x61, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x68, 0x61, 0x73, 0x68, - 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, - 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, - 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, - 0x52, 0x0a, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x22, 0xb4, 0x01, 0x0a, - 0x09, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x12, 0x4a, 0x0a, 0x06, 0x73, 0x70, - 0x69, 0x66, 0x66, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x68, 0x61, 0x73, + 0x6c, 0x74, 0x41, 0x6c, 0x6c, 0x6f, 0x77, 0x22, 0xcd, 0x01, 0x0a, 0x0a, 0x50, 0x65, 0x72, 0x6d, + 0x69, 0x73, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x55, 0x0a, 0x0a, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, + 0x70, 0x61, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, - 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x53, 0x70, 0x69, 0x66, 0x66, 0x65, 0x52, 0x06, - 0x73, 0x70, 0x69, 0x66, 0x66, 0x65, 0x12, 0x5b, 0x0a, 0x0f, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, - 0x65, 0x5f, 0x73, 0x70, 0x69, 0x66, 0x66, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x32, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, - 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, - 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x53, 0x70, 0x69, - 0x66, 0x66, 0x65, 0x52, 0x0e, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x53, 0x70, 0x69, 0x66, - 0x66, 0x65, 0x73, 0x22, 0x3d, 0x0a, 0x06, 0x53, 0x70, 0x69, 0x66, 0x66, 0x65, 0x12, 0x14, 0x0a, - 0x05, 0x72, 0x65, 0x67, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x72, 0x65, - 0x67, 0x65, 0x78, 0x12, 0x1d, 0x0a, 0x0a, 0x78, 0x66, 0x63, 0x63, 0x5f, 0x72, 0x65, 0x67, 0x65, - 0x78, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x78, 0x66, 0x63, 0x63, 0x52, 0x65, 0x67, - 0x65, 0x78, 0x42, 0xdd, 0x02, 0x0a, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, + 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x50, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, + 0x6c, 0x52, 0x0a, 0x70, 0x72, 0x69, 0x6e, 0x63, 0x69, 0x70, 0x61, 0x6c, 0x73, 0x12, 0x68, 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, 0x3b, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, - 0x73, 0x74, 0x61, 0x74, 0x65, 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, 0x44, 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, 0x6d, 0x65, 0x73, - 0x68, 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, - 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0xa2, 0x02, 0x05, 0x48, 0x43, 0x4d, 0x56, 0x50, 0xaa, 0x02, - 0x2a, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, - 0x6c, 0x2e, 0x4d, 0x65, 0x73, 0x68, 0x2e, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, - 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0xca, 0x02, 0x2a, 0x48, 0x61, - 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, - 0x65, 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x50, 0x62, 0x70, 0x72, - 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0xe2, 0x02, 0x36, 0x48, 0x61, 0x73, 0x68, 0x69, - 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, - 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x50, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, - 0x61, 0xea, 0x02, 0x2e, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, - 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x4d, 0x65, 0x73, 0x68, 0x3a, 0x3a, 0x56, 0x32, 0x62, - 0x65, 0x74, 0x61, 0x31, 0x3a, 0x3a, 0x50, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, - 0x74, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x73, 0x74, 0x61, 0x74, 0x65, 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, 0xb4, 0x01, 0x0a, 0x09, 0x50, 0x72, 0x69, 0x6e, + 0x63, 0x69, 0x70, 0x61, 0x6c, 0x12, 0x4a, 0x0a, 0x06, 0x73, 0x70, 0x69, 0x66, 0x66, 0x65, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, + 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, + 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x2e, 0x53, 0x70, 0x69, 0x66, 0x66, 0x65, 0x52, 0x06, 0x73, 0x70, 0x69, 0x66, 0x66, + 0x65, 0x12, 0x5b, 0x0a, 0x0f, 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x5f, 0x73, 0x70, 0x69, + 0x66, 0x66, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x68, 0x61, 0x73, + 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, + 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, + 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x53, 0x70, 0x69, 0x66, 0x66, 0x65, 0x52, 0x0e, + 0x65, 0x78, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x53, 0x70, 0x69, 0x66, 0x66, 0x65, 0x73, 0x22, 0x3d, + 0x0a, 0x06, 0x53, 0x70, 0x69, 0x66, 0x66, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x65, 0x67, 0x65, + 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x72, 0x65, 0x67, 0x65, 0x78, 0x12, 0x1d, + 0x0a, 0x0a, 0x78, 0x66, 0x63, 0x63, 0x5f, 0x72, 0x65, 0x67, 0x65, 0x78, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x09, 0x78, 0x66, 0x63, 0x63, 0x52, 0x65, 0x67, 0x65, 0x78, 0x22, 0x85, 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, 0x79, 0x0a, 0x17, 0x64, 0x65, + 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x72, 0x75, 0x6c, 0x65, 0x5f, 0x68, + 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x41, 0x2e, 0x68, 0x61, + 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, + 0x65, 0x73, 0x68, 0x2e, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, + 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2e, 0x44, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x75, 0x6c, 0x65, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x52, 0x15, + 0x64, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x75, 0x6c, 0x65, 0x48, + 0x65, 0x61, 0x64, 0x65, 0x72, 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, 0x42, 0xdd, 0x02, 0x0a, 0x2e, 0x63, 0x6f, 0x6d, 0x2e, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, + 0x6f, 0x72, 0x70, 0x2e, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, + 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, + 0x74, 0x61, 0x74, 0x65, 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, + 0x44, 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, 0x6d, 0x65, 0x73, 0x68, + 0x2f, 0x76, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2f, 0x70, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, + 0x73, 0x74, 0x61, 0x74, 0x65, 0xa2, 0x02, 0x05, 0x48, 0x43, 0x4d, 0x56, 0x50, 0xaa, 0x02, 0x2a, + 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, + 0x2e, 0x4d, 0x65, 0x73, 0x68, 0x2e, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x2e, 0x50, 0x62, + 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0xca, 0x02, 0x2a, 0x48, 0x61, 0x73, + 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x65, + 0x73, 0x68, 0x5c, 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x50, 0x62, 0x70, 0x72, 0x6f, + 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, 0x65, 0xe2, 0x02, 0x36, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, + 0x6f, 0x72, 0x70, 0x5c, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6c, 0x5c, 0x4d, 0x65, 0x73, 0x68, 0x5c, + 0x56, 0x32, 0x62, 0x65, 0x74, 0x61, 0x31, 0x5c, 0x50, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x5c, 0x47, 0x50, 0x42, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0xea, 0x02, 0x2e, 0x48, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f, 0x72, 0x70, 0x3a, 0x3a, 0x43, 0x6f, + 0x6e, 0x73, 0x75, 0x6c, 0x3a, 0x3a, 0x4d, 0x65, 0x73, 0x68, 0x3a, 0x3a, 0x56, 0x32, 0x62, 0x65, + 0x74, 0x61, 0x31, 0x3a, 0x3a, 0x50, 0x62, 0x70, 0x72, 0x6f, 0x78, 0x79, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -333,24 +552,28 @@ func file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_rawDescGZIP() [] return file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_rawDescData } -var file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_msgTypes = make([]protoimpl.MessageInfo, 4) +var file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_msgTypes = make([]protoimpl.MessageInfo, 6) var file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_goTypes = []interface{}{ - (*TrafficPermissions)(nil), // 0: hashicorp.consul.mesh.v2beta1.pbproxystate.TrafficPermissions - (*Permission)(nil), // 1: hashicorp.consul.mesh.v2beta1.pbproxystate.Permission - (*Principal)(nil), // 2: hashicorp.consul.mesh.v2beta1.pbproxystate.Principal - (*Spiffe)(nil), // 3: hashicorp.consul.mesh.v2beta1.pbproxystate.Spiffe + (*TrafficPermissions)(nil), // 0: hashicorp.consul.mesh.v2beta1.pbproxystate.TrafficPermissions + (*Permission)(nil), // 1: hashicorp.consul.mesh.v2beta1.pbproxystate.Permission + (*Principal)(nil), // 2: hashicorp.consul.mesh.v2beta1.pbproxystate.Principal + (*Spiffe)(nil), // 3: hashicorp.consul.mesh.v2beta1.pbproxystate.Spiffe + (*DestinationRule)(nil), // 4: hashicorp.consul.mesh.v2beta1.pbproxystate.DestinationRule + (*DestinationRuleHeader)(nil), // 5: hashicorp.consul.mesh.v2beta1.pbproxystate.DestinationRuleHeader } var file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_depIdxs = []int32{ 1, // 0: hashicorp.consul.mesh.v2beta1.pbproxystate.TrafficPermissions.allow_permissions:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.Permission 1, // 1: hashicorp.consul.mesh.v2beta1.pbproxystate.TrafficPermissions.deny_permissions:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.Permission 2, // 2: hashicorp.consul.mesh.v2beta1.pbproxystate.Permission.principals:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.Principal - 3, // 3: hashicorp.consul.mesh.v2beta1.pbproxystate.Principal.spiffe:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.Spiffe - 3, // 4: hashicorp.consul.mesh.v2beta1.pbproxystate.Principal.exclude_spiffes:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.Spiffe - 5, // [5:5] is the sub-list for method output_type - 5, // [5:5] is the sub-list for method input_type - 5, // [5:5] is the sub-list for extension type_name - 5, // [5:5] is the sub-list for extension extendee - 0, // [0:5] is the sub-list for field type_name + 4, // 3: hashicorp.consul.mesh.v2beta1.pbproxystate.Permission.destination_rules:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.DestinationRule + 3, // 4: hashicorp.consul.mesh.v2beta1.pbproxystate.Principal.spiffe:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.Spiffe + 3, // 5: hashicorp.consul.mesh.v2beta1.pbproxystate.Principal.exclude_spiffes:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.Spiffe + 5, // 6: hashicorp.consul.mesh.v2beta1.pbproxystate.DestinationRule.destination_rule_header:type_name -> hashicorp.consul.mesh.v2beta1.pbproxystate.DestinationRuleHeader + 7, // [7:7] is the sub-list for method output_type + 7, // [7:7] is the sub-list for method input_type + 7, // [7:7] is the sub-list for extension type_name + 7, // [7:7] is the sub-list for extension extendee + 0, // [0:7] is the sub-list for field type_name } func init() { file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_init() } @@ -407,6 +630,30 @@ func file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_init() { return nil } } + file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DestinationRule); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*DestinationRuleHeader); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } } type x struct{} out := protoimpl.TypeBuilder{ @@ -414,7 +661,7 @@ func file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_pbmesh_v2beta1_pbproxystate_traffic_permissions_proto_rawDesc, NumEnums: 0, - NumMessages: 4, + NumMessages: 6, NumExtensions: 0, NumServices: 0, }, diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/traffic_permissions.proto b/proto-public/pbmesh/v2beta1/pbproxystate/traffic_permissions.proto index ea7937aba2..0d04c09355 100644 --- a/proto-public/pbmesh/v2beta1/pbproxystate/traffic_permissions.proto +++ b/proto-public/pbmesh/v2beta1/pbproxystate/traffic_permissions.proto @@ -17,9 +17,9 @@ message TrafficPermissions { message Permission { repeated Principal principals = 1; - // We don't need destination rules here yet because they either apply to L7 features or multi-ports. // In the case of multiple ports, the sidecar proxy controller is responsible for filtering // per-port permissions. + repeated DestinationRule destination_rules = 2; } message Principal { @@ -35,3 +35,21 @@ message Spiffe { // It is currently unused, but considering this is important for to avoid breaking changes. string xfcc_regex = 2; } + +message DestinationRule { + string path_exact = 1; + string path_prefix = 2; + string path_regex = 3; + repeated string methods = 4; + repeated DestinationRuleHeader destination_rule_header = 5; +} + +message DestinationRuleHeader { + string name = 1; + bool present = 2; + string exact = 3; + string prefix = 4; + string suffix = 5; + string regex = 6; + bool invert = 7; +} diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/traffic_permissions_deepcopy.gen.go b/proto-public/pbmesh/v2beta1/pbproxystate/traffic_permissions_deepcopy.gen.go index b45d2a7926..170a169211 100644 --- a/proto-public/pbmesh/v2beta1/pbproxystate/traffic_permissions_deepcopy.gen.go +++ b/proto-public/pbmesh/v2beta1/pbproxystate/traffic_permissions_deepcopy.gen.go @@ -88,3 +88,45 @@ func (in *Spiffe) DeepCopy() *Spiffe { func (in *Spiffe) DeepCopyInterface() interface{} { return in.DeepCopy() } + +// DeepCopyInto supports using DestinationRule within kubernetes types, where deepcopy-gen is used. +func (in *DestinationRule) DeepCopyInto(out *DestinationRule) { + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DestinationRule. Required by controller-gen. +func (in *DestinationRule) DeepCopy() *DestinationRule { + if in == nil { + return nil + } + out := new(DestinationRule) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new DestinationRule. Required by controller-gen. +func (in *DestinationRule) DeepCopyInterface() interface{} { + return in.DeepCopy() +} + +// DeepCopyInto supports using DestinationRuleHeader within kubernetes types, where deepcopy-gen is used. +func (in *DestinationRuleHeader) DeepCopyInto(out *DestinationRuleHeader) { + proto.Reset(out) + proto.Merge(out, proto.Clone(in)) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DestinationRuleHeader. Required by controller-gen. +func (in *DestinationRuleHeader) DeepCopy() *DestinationRuleHeader { + if in == nil { + return nil + } + out := new(DestinationRuleHeader) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInterface is an autogenerated deepcopy function, copying the receiver, creating a new DestinationRuleHeader. Required by controller-gen. +func (in *DestinationRuleHeader) DeepCopyInterface() interface{} { + return in.DeepCopy() +} diff --git a/proto-public/pbmesh/v2beta1/pbproxystate/traffic_permissions_json.gen.go b/proto-public/pbmesh/v2beta1/pbproxystate/traffic_permissions_json.gen.go index 3651fcabca..3692fe2a36 100644 --- a/proto-public/pbmesh/v2beta1/pbproxystate/traffic_permissions_json.gen.go +++ b/proto-public/pbmesh/v2beta1/pbproxystate/traffic_permissions_json.gen.go @@ -49,6 +49,28 @@ func (this *Spiffe) UnmarshalJSON(b []byte) error { return TrafficPermissionsUnmarshaler.Unmarshal(b, this) } +// MarshalJSON is a custom marshaler for DestinationRule +func (this *DestinationRule) MarshalJSON() ([]byte, error) { + str, err := TrafficPermissionsMarshaler.Marshal(this) + return []byte(str), err +} + +// UnmarshalJSON is a custom unmarshaler for DestinationRule +func (this *DestinationRule) UnmarshalJSON(b []byte) error { + return TrafficPermissionsUnmarshaler.Unmarshal(b, this) +} + +// MarshalJSON is a custom marshaler for DestinationRuleHeader +func (this *DestinationRuleHeader) MarshalJSON() ([]byte, error) { + str, err := TrafficPermissionsMarshaler.Marshal(this) + return []byte(str), err +} + +// UnmarshalJSON is a custom unmarshaler for DestinationRuleHeader +func (this *DestinationRuleHeader) UnmarshalJSON(b []byte) error { + return TrafficPermissionsUnmarshaler.Unmarshal(b, this) +} + var ( TrafficPermissionsMarshaler = &protojson.MarshalOptions{} TrafficPermissionsUnmarshaler = &protojson.UnmarshalOptions{DiscardUnknown: false}