diff --git a/api/protos/aggregation/v1/aggregation.proto b/api/protos/aggregation/v1/aggregation.proto index 68397610..16594e41 100644 --- a/api/protos/aggregation/v1/aggregation.proto +++ b/api/protos/aggregation/v1/aggregation.proto @@ -32,6 +32,7 @@ message KeyerConfiguration { repeated Fragment fragments = 1 [(validate.rules).repeated.min_items = 1]; } +// [#next-free-field: 4] message StringMatch { oneof type { option (validate.required) = true; @@ -46,6 +47,12 @@ message StringMatch { } } +// [#next-free-field: 2] +message BoolMatch { + bool value_match = 1; +} + +// [#next-free-field: 4] message LocalityMatch { StringMatch region = 1; @@ -54,6 +61,31 @@ message LocalityMatch { StringMatch sub_zone = 3; } +// [#next-free-field: 2] +message PathSegment { + string key = 1 [(validate.rules).string.min_len = 1]; +} + +// [#next-free-field: 3] +message StructValueMatch { + // TODO: we have to match every single type described in + // https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#google.protobuf.Value. + oneof match { + option (validate.required) = true; + + StringMatch string_match = 1; + + BoolMatch bool_match = 2; + } +} + +// [#next-free-field: 3] +message NodeMetadataMatch { + repeated PathSegment path = 1 [(validate.rules).repeated.min_items = 1]; + + StructValueMatch match = 2 [(validate.rules).message.required = true]; +} + // This is a recursive structure which allows complex nested match // configurations to be built using various logical operators. // [#next-free-field: 7] @@ -68,7 +100,7 @@ message MatchPredicate { } // Match on a field in Envoy's request node. - // [#next-free-field: 4] + // [#next-free-field: 5] message RequestNodeMatch { oneof type { option (validate.required) = true; @@ -78,6 +110,8 @@ message MatchPredicate { StringMatch cluster_match = 2; LocalityMatch locality_match = 3; + + NodeMetadataMatch node_metadata_match = 4; } } @@ -120,8 +154,8 @@ message MatchPredicate { // [#next-free-field: 5] message ResultPredicate { + // [#next-free-field: 3] message ResultAction { - // TODO potentially use "safe regex" // https://github.com/envoyproxy/envoy/blob/10f756efa17e56c8d4d1033be7b4286410db4e01/api/envoy/type/matcher/v3/regex.proto // [#next-free-field: 3] @@ -152,12 +186,20 @@ message ResultPredicate { ResultAction subzone_action = 3; } + // [#next-free-field: 3] + message NodeMetadataAction { + repeated PathSegment path = 1 [(validate.rules).repeated.min_items = 1]; + + ResultAction action = 2 [(validate.rules).message.required = true]; + } + + // [#next-free-field: 2] message AndResult { repeated ResultPredicate result_predicates = 1 [(validate.rules).repeated.min_items = 2]; } // Rules for generating the resulting fragment from a Envoy request node. - // [#next-free-field: 4] + // [#next-free-field: 5] message RequestNodeFragment { oneof action { @@ -166,6 +208,7 @@ message ResultPredicate { ResultAction id_action = 1; ResultAction cluster_action = 2; LocalityResultAction locality_action = 3; + NodeMetadataAction node_metadata_action = 4; } } diff --git a/internal/app/mapper/mapper.go b/internal/app/mapper/mapper.go index 9f38f5cc..9144d86f 100644 --- a/internal/app/mapper/mapper.go +++ b/internal/app/mapper/mapper.go @@ -9,6 +9,7 @@ import ( v3 "github.com/envoyproxy/go-control-plane/pkg/resource/v3" "github.com/envoyproxy/xds-relay/internal/app/metrics" "github.com/envoyproxy/xds-relay/internal/app/transport" + "google.golang.org/protobuf/types/known/structpb" "github.com/uber-go/tally" @@ -155,6 +156,11 @@ func isNodeMatch(matchPredicate *matchPredicate, req transport.Request) (bool, e return compareLocality(localityMatch, req.GetLocality()) } + nodeMetadataMatch := predicate.GetNodeMetadataMatch() + if nodeMetadataMatch != nil { + return compareNodeMetadata(nodeMetadataMatch, req.GetNodeMetadata()) + } + return false, fmt.Errorf("RequestNodeMatch is invalid") } @@ -287,6 +293,9 @@ func getResultFromRequestNodePredicate(predicate *resultPredicate, req transport resultFragment, err = getResultFragmentFromAction(req.GetCluster(), requestNodeFragment.GetClusterAction()) } else if requestNodeFragment.GetLocalityAction() != nil { resultFragment, err = getFragmentFromLocalityAction(req.GetLocality(), requestNodeFragment.GetLocalityAction()) + } else if requestNodeFragment.GetNodeMetadataAction() != nil { + resultFragment, err = getFragmentFromNodeMetadataAction(req.GetNodeMetadata(), + requestNodeFragment.GetNodeMetadataAction()) } if err != nil { @@ -439,6 +448,27 @@ func getFragmentFromLocalityAction( return strings.Join(matches, "|"), nil } +func getFragmentFromNodeMetadataAction( + nodeMetadata *structpb.Struct, + action *aggregationv1.ResultPredicate_NodeMetadataAction) (string, error) { + // Traverse to the right node + var value *structpb.Value = nil + var ok bool + for _, segment := range action.GetPath() { + fields := nodeMetadata.GetFields() + value, ok = fields[segment.Key] + if !ok { + // TODO what to do if the key doesn't map to a valid struct field? + return "", fmt.Errorf("Path to key is inexistent") + } + nodeMetadata = value.GetStructValue() + } + + // TODO: We need to stringify values other than strings (bool, integers, etc) before + // extracting the fragment via a call to getResultFragmentFromAction. + return getResultFragmentFromAction(value.GetStringValue(), action.GetAction()) +} + func compareString(stringMatch *aggregationv1.StringMatch, nodeValue string) (bool, error) { if nodeValue == "" { return false, fmt.Errorf("MatchPredicate Node field cannot be empty") @@ -460,6 +490,10 @@ func compareString(stringMatch *aggregationv1.StringMatch, nodeValue string) (bo return false, nil } +func compareBool(boolMatch *aggregationv1.BoolMatch, boolValue bool) bool { + return boolMatch.ValueMatch == boolValue +} + func compareLocality(localityMatch *aggregationv1.LocalityMatch, reqNodeLocality *transport.Locality) (bool, error) { if reqNodeLocality == nil { @@ -493,3 +527,38 @@ func compareLocality(localityMatch *aggregationv1.LocalityMatch, return regionMatch && zoneMatch && subZoneMatch, nil } + +func compareNodeMetadata(nodeMetadataMatch *aggregationv1.NodeMetadataMatch, + nodeMetadata *structpb.Struct) (bool, error) { + if nodeMetadata == nil { + return false, fmt.Errorf("Metadata Node field cannot be empty") + } + + var value *structpb.Value = nil + var ok bool + for _, segment := range nodeMetadataMatch.GetPath() { + // Starting from the second iteration, make sure that we're dealing with structs + if value != nil { + if value.GetStructValue() != nil { + nodeMetadata = value.GetStructValue() + } else { + // TODO: signal that the field is not a struct + return false, nil + } + } + fields := nodeMetadata.GetFields() + value, ok = fields[segment.Key] + if !ok { + return false, nil + } + } + + // TODO: implement the other structpb.Value types. + if nodeMetadataMatch.Match.GetStringMatch() != nil { + return compareString(nodeMetadataMatch.Match.GetStringMatch(), value.GetStringValue()) + } else if nodeMetadataMatch.Match.GetBoolMatch() != nil { + return compareBool(nodeMetadataMatch.Match.GetBoolMatch(), value.GetBoolValue()), nil + } else { + return false, fmt.Errorf("Invalid NodeMetadata Match") + } +} diff --git a/internal/app/mapper/mapper_test.go b/internal/app/mapper/mapper_test.go index b55e296b..bccda413 100644 --- a/internal/app/mapper/mapper_test.go +++ b/internal/app/mapper/mapper_test.go @@ -11,6 +11,7 @@ import ( . "github.com/onsi/ginkgo" . "github.com/onsi/ginkgo/extensions/table" . "github.com/onsi/gomega" + "google.golang.org/protobuf/types/known/structpb" ) type KeyerConfiguration = aggregationv1.KeyerConfiguration @@ -20,6 +21,10 @@ type MatchPredicate = aggregationv1.MatchPredicate type ResultPredicate = aggregationv1.ResultPredicate type LocalityResultAction = aggregationv1.ResultPredicate_LocalityResultAction type StringMatch = aggregationv1.StringMatch +type BoolMatch = aggregationv1.BoolMatch +type Struct = structpb.Struct +type Value = structpb.Value +type StringValue = structpb.Value_StringValue const ( clusterTypeURL = "type.googleapis.com/envoy.api.v2.Cluster" @@ -100,6 +105,33 @@ var positiveTests = []TableEntry{ stringFragment, }, }, + { + Description: "RequestNodeMatch with single level node metadata bool exact match", + Parameters: []interface{}{ + getRequestNodeMetadataBoolMatch([]string{"bool-field"}, getBoolMatch(true)), + getResultStringFragment(), + clusterTypeURL, + stringFragment, + }, + }, + { + Description: "RequestNodeMatch with nested level node metadata exact match", + Parameters: []interface{}{ + getRequestNodeMetadataStringMatch([]string{"nested-field", "f2"}, getExactMatch("v2")), + getResultStringFragment(), + clusterTypeURL, + stringFragment, + }, + }, + { + Description: "RequestNodeMatch with nested level bool node metadata exact match", + Parameters: []interface{}{ + getRequestNodeMetadataBoolMatch([]string{"nested-field", "nested-bool-field"}, getBoolMatch(false)), + getResultStringFragment(), + clusterTypeURL, + stringFragment, + }, + }, { Description: "RequestNodeMatch with node id regex match", Parameters: []interface{}{ @@ -118,6 +150,24 @@ var positiveTests = []TableEntry{ stringFragment, }, }, + { + Description: "RequestNodeMatch with single level node metadata regex match", + Parameters: []interface{}{ + getRequestNodeMetadataStringMatch([]string{"f1"}, getRegexMatch("v.")), + getResultStringFragment(), + clusterTypeURL, + stringFragment, + }, + }, + { + Description: "RequestNodeMatch with nested level node metadata regex match", + Parameters: []interface{}{ + getRequestNodeMetadataStringMatch([]string{"nested-field", "f2"}, getRegexMatch(".2")), + getResultStringFragment(), + clusterTypeURL, + stringFragment, + }, + }, { Description: "AndMatch RequestNodeMatch", Parameters: []interface{}{ @@ -362,6 +412,34 @@ var positiveTests = []TableEntry{ fmt.Sprintf("%s|%s", nodezone, nodesubzone), }, }, + { + Description: "AnyMatch With Exact Metadata - single level", + Parameters: []interface{}{ + getAnyMatch(true), + getResultRequestNodeMetadataFragment( + &aggregationv1.ResultPredicate_NodeMetadataAction{ + Path: buildPath([]string{"f1"}), + Action: getExactAction(), + }, + ), + clusterTypeURL, + "v1", + }, + }, + { + Description: "AnyMatch With Exact Metadata - nested one level", + Parameters: []interface{}{ + getAnyMatch(true), + getResultRequestNodeMetadataFragment( + &aggregationv1.ResultPredicate_NodeMetadataAction{ + Path: buildPath([]string{"nested-field", "f2"}), + Action: getExactAction(), + }, + ), + clusterTypeURL, + "v2", + }, + }, { Description: "AnyMatch With Regex Locality region, zone, and subzone match", Parameters: []interface{}{ @@ -419,6 +497,34 @@ var positiveTests = []TableEntry{ "zone2|subzero", }, }, + { + Description: "AnyMatch With Regex Metadata - single level", + Parameters: []interface{}{ + getAnyMatch(true), + getResultRequestNodeMetadataFragment( + &aggregationv1.ResultPredicate_NodeMetadataAction{ + Path: buildPath([]string{"f1"}), + Action: getRegexAction("v(.)", "version-$1"), + }, + ), + clusterTypeURL, + "version-1", + }, + }, + { + Description: "AnyMatch With Regex Metadata - nested level", + Parameters: []interface{}{ + getAnyMatch(true), + getResultRequestNodeMetadataFragment( + &aggregationv1.ResultPredicate_NodeMetadataAction{ + Path: buildPath([]string{"nested-field", "f2"}), + Action: getRegexAction("v(.)", "version-$1"), + }, + ), + clusterTypeURL, + "version-2", + }, + }, { Description: "AnyMatch With result concatenation", Parameters: []interface{}{ @@ -565,6 +671,30 @@ var negativeTests = []TableEntry{ getDiscoveryRequest(), }, }, + { + Description: "RequestNodeMatch with node metadata single level does not match", + Parameters: []interface{}{ + getRequestNodeMetadataStringMatch([]string{"f1"}, getExactMatch("v1-notmatch")), + getResultStringFragment(), + getDiscoveryRequest(), + }, + }, + { + Description: "RequestNodeMatch with node metadata two levels does not match", + Parameters: []interface{}{ + getRequestNodeMetadataStringMatch([]string{"nested-field", "f2"}, getExactMatch("v2-notmatch")), + getResultStringFragment(), + getDiscoveryRequest(), + }, + }, + { + Description: "RequestNodeMatch with node metadata two levels and inexistent key does not match", + Parameters: []interface{}{ + getRequestNodeMetadataStringMatch([]string{"inexistent-key-1", "inexistent-key-2"}, getExactMatch("v2-notmatch")), + getResultStringFragment(), + getDiscoveryRequest(), + }, + }, { Description: "RequestNodeMatch with node id regex does not match", Parameters: []interface{}{ @@ -605,12 +735,28 @@ var negativeTests = []TableEntry{ getDiscoveryRequest(), }, }, + { + Description: "RequestNodeMatch with node metadata single level regex does not match", + Parameters: []interface{}{ + getRequestNodeMetadataStringMatch([]string{"f1"}, getRegexMatch("mismatch")), + getResultStringFragment(), + getDiscoveryRequest(), + }, + }, + { + Description: "RequestNodeMatch with node metadata two levels regex does not match", + Parameters: []interface{}{ + getRequestNodeMetadataStringMatch([]string{"nested-field", "f2"}, getRegexMatch("mismatch")), + getResultStringFragment(), + getDiscoveryRequest(), + }, + }, { Description: "RequestNodeMatch with exact match request node id mismatch", Parameters: []interface{}{ getRequestNodeIDExactMatch(nodeid), getResultStringFragment(), - getDiscoveryRequestWithNode(getNode("mismatch", nodecluster, noderegion, nodezone, nodesubzone)), + getDiscoveryRequestWithNode(getNode("mismatch", nodecluster, noderegion, nodezone, nodesubzone, nil)), }, }, { @@ -618,7 +764,7 @@ var negativeTests = []TableEntry{ Parameters: []interface{}{ getRequestNodeIDRegexMatch(nodeid), getResultStringFragment(), - getDiscoveryRequestWithNode(getNode("mismatch", nodecluster, noderegion, nodezone, nodesubzone)), + getDiscoveryRequestWithNode(getNode("mismatch", nodecluster, noderegion, nodezone, nodesubzone, nil)), }, }, { @@ -626,7 +772,7 @@ var negativeTests = []TableEntry{ Parameters: []interface{}{ getRequestNodeClusterExactMatch(nodecluster), getResultStringFragment(), - getDiscoveryRequestWithNode(getNode(nodeid, "mismatch", noderegion, nodezone, nodesubzone)), + getDiscoveryRequestWithNode(getNode(nodeid, "mismatch", noderegion, nodezone, nodesubzone, nil)), }, }, { @@ -634,7 +780,7 @@ var negativeTests = []TableEntry{ Parameters: []interface{}{ getRequestNodeClusterRegexMatch(nodecluster), getResultStringFragment(), - getDiscoveryRequestWithNode(getNode(nodeid, "mismatch", noderegion, nodezone, nodesubzone)), + getDiscoveryRequestWithNode(getNode(nodeid, "mismatch", noderegion, nodezone, nodesubzone, nil)), }, }, { @@ -642,7 +788,7 @@ var negativeTests = []TableEntry{ Parameters: []interface{}{ getRequestNodeLocality(getExactMatch(noderegion), getExactMatch(nodezone), getExactMatch(nodesubzone)), getResultStringFragment(), - getDiscoveryRequestWithNode(getNode(nodeid, nodecluster, "mismatch", nodezone, nodesubzone)), + getDiscoveryRequestWithNode(getNode(nodeid, nodecluster, "mismatch", nodezone, nodesubzone, nil)), }, }, { @@ -650,7 +796,7 @@ var negativeTests = []TableEntry{ Parameters: []interface{}{ getRequestNodeLocality(getExactMatch(noderegion), getExactMatch(nodezone), getExactMatch(nodesubzone)), getResultStringFragment(), - getDiscoveryRequestWithNode(getNode(nodeid, nodecluster, noderegion, "mismatch", nodesubzone)), + getDiscoveryRequestWithNode(getNode(nodeid, nodecluster, noderegion, "mismatch", nodesubzone, nil)), }, }, { @@ -658,16 +804,47 @@ var negativeTests = []TableEntry{ Parameters: []interface{}{ getRequestNodeLocality(getExactMatch(noderegion), getExactMatch(nodezone), getExactMatch(nodesubzone)), getResultStringFragment(), - getDiscoveryRequestWithNode(getNode(nodeid, nodecluster, noderegion, nodezone, "mismatch")), + getDiscoveryRequestWithNode(getNode(nodeid, nodecluster, noderegion, nodezone, "mismatch", nil)), + }, + }, + { + Description: "RequestNodeMatch with exact match request node metadata mismatch - single level", + Parameters: []interface{}{ + getRequestNodeMetadataStringMatch([]string{"f1"}, getExactMatch("v1")), + getResultStringFragment(), + getDiscoveryRequestWithNode(getNode(nodeid, nodecluster, noderegion, nodezone, nodesubzone, &Struct{ + Fields: map[string]*Value{ + "f1": {Kind: &StringValue{StringValue: "mismatch"}}, + }, + }, + )), + }, + }, + { + Description: "RequestNodeMatch with exact match request node metadata mismatch - nested level", + Parameters: []interface{}{ + getRequestNodeMetadataStringMatch([]string{"nested-field", "f2"}, getExactMatch("v2")), + getResultStringFragment(), + getDiscoveryRequestWithNode(getNode(nodeid, nodecluster, noderegion, nodezone, nodesubzone, &Struct{ + Fields: map[string]*Value{ + "nested-field": {Kind: &structpb.Value_StructValue{ + StructValue: &Struct{ + Fields: map[string]*Value{ + "f2": {Kind: &StringValue{StringValue: "mismatch"}}, + }, + }, + }}, + }, + }, + )), }, }, - { Description: "RequestNodeMatch with regex match request node region mismatch", Parameters: []interface{}{ getRequestNodeLocality(getRegexMatch(noderegion), getExactMatch(nodezone), getExactMatch(nodesubzone)), getResultStringFragment(), - getDiscoveryRequestWithNode(getNode(nodeid, nodecluster, "mismatch", nodezone, nodesubzone)), + getDiscoveryRequestWithNode(getNode(nodeid, nodecluster, "mismatch", nodezone, nodesubzone, nil)), }, }, { @@ -675,7 +852,7 @@ var negativeTests = []TableEntry{ Parameters: []interface{}{ getRequestNodeLocality(getExactMatch(noderegion), getRegexMatch(nodezone), getExactMatch(nodesubzone)), getResultStringFragment(), - getDiscoveryRequestWithNode(getNode(nodeid, nodecluster, noderegion, "mismatch", nodesubzone)), + getDiscoveryRequestWithNode(getNode(nodeid, nodecluster, noderegion, "mismatch", nodesubzone, nil)), }, }, { @@ -683,10 +860,9 @@ var negativeTests = []TableEntry{ Parameters: []interface{}{ getRequestNodeLocality(getExactMatch(noderegion), getExactMatch(nodezone), getRegexMatch(nodesubzone)), getResultStringFragment(), - getDiscoveryRequestWithNode(getNode(nodeid, nodecluster, noderegion, nodezone, "mismatch")), + getDiscoveryRequestWithNode(getNode(nodeid, nodecluster, noderegion, nodezone, "mismatch", nil)), }, }, - { Description: "AndMatch RequestNodeMatch does not match first predicate", Parameters: []interface{}{ @@ -922,7 +1098,7 @@ var emptyFragmentErrorCases = []TableEntry{ Parameters: []interface{}{ getRequestNodeIDExactMatch(nodeid), getResultRequestNodeIDFragment(getExactAction()), - getDiscoveryRequestWithNode(getNode("", nodecluster, noderegion, nodezone, nodesubzone)), + getDiscoveryRequestWithNode(getNode("", nodecluster, noderegion, nodezone, nodesubzone, nil)), "MatchPredicate Node field cannot be empty", }, }, @@ -931,7 +1107,7 @@ var emptyFragmentErrorCases = []TableEntry{ Parameters: []interface{}{ getRequestNodeClusterExactMatch(nodecluster), getResultRequestNodeIDFragment(getExactAction()), - getDiscoveryRequestWithNode(getNode(nodeid, "", noderegion, nodezone, nodesubzone)), + getDiscoveryRequestWithNode(getNode(nodeid, "", noderegion, nodezone, nodesubzone, nil)), "MatchPredicate Node field cannot be empty", }, }, @@ -942,7 +1118,7 @@ var emptyFragmentErrorCases = []TableEntry{ getResultRequestNodeLocalityFragment(&aggregationv1.ResultPredicate_LocalityResultAction{ RegionAction: getExactAction(), }), - getDiscoveryRequestWithNode(getNode(nodeid, nodecluster, "", nodezone, nodesubzone)), + getDiscoveryRequestWithNode(getNode(nodeid, nodecluster, "", nodezone, nodesubzone, nil)), "RequestNodeFragment exact match resulted in an empty fragment", }, }, @@ -953,7 +1129,7 @@ var emptyFragmentErrorCases = []TableEntry{ getResultRequestNodeLocalityFragment(&aggregationv1.ResultPredicate_LocalityResultAction{ ZoneAction: getExactAction(), }), - getDiscoveryRequestWithNode(getNode(nodeid, nodecluster, noderegion, "", nodesubzone)), + getDiscoveryRequestWithNode(getNode(nodeid, nodecluster, noderegion, "", nodesubzone, nil)), "RequestNodeFragment exact match resulted in an empty fragment", }, }, @@ -964,7 +1140,7 @@ var emptyFragmentErrorCases = []TableEntry{ getResultRequestNodeLocalityFragment(&aggregationv1.ResultPredicate_LocalityResultAction{ SubzoneAction: getExactAction(), }), - getDiscoveryRequestWithNode(getNode(nodeid, nodecluster, noderegion, nodezone, "")), + getDiscoveryRequestWithNode(getNode(nodeid, nodecluster, noderegion, nodezone, "", nil)), "RequestNodeFragment exact match resulted in an empty fragment", }, }, @@ -973,7 +1149,7 @@ var emptyFragmentErrorCases = []TableEntry{ Parameters: []interface{}{ getAnyMatch(true), getResultRequestNodeIDFragment(getExactAction()), - getDiscoveryRequestWithNode(getNode("", nodecluster, noderegion, nodezone, nodesubzone)), + getDiscoveryRequestWithNode(getNode("", nodecluster, noderegion, nodezone, nodesubzone, nil)), "RequestNodeFragment exact match resulted in an empty fragment", }, }, @@ -982,7 +1158,7 @@ var emptyFragmentErrorCases = []TableEntry{ Parameters: []interface{}{ getAnyMatch(true), getResultRequestNodeClusterFragment(getExactAction()), - getDiscoveryRequestWithNode(getNode(nodeid, "", noderegion, nodezone, nodesubzone)), + getDiscoveryRequestWithNode(getNode(nodeid, "", noderegion, nodezone, nodesubzone, nil)), "RequestNodeFragment exact match resulted in an empty fragment", }, }, @@ -993,7 +1169,7 @@ var emptyFragmentErrorCases = []TableEntry{ getResultRequestNodeLocalityFragment(&aggregationv1.ResultPredicate_LocalityResultAction{ RegionAction: getExactAction(), }), - getDiscoveryRequestWithNode(getNode(nodeid, nodecluster, "", nodezone, nodesubzone)), + getDiscoveryRequestWithNode(getNode(nodeid, nodecluster, "", nodezone, nodesubzone, nil)), "RequestNodeFragment exact match resulted in an empty fragment", }, }, @@ -1004,7 +1180,7 @@ var emptyFragmentErrorCases = []TableEntry{ getResultRequestNodeLocalityFragment(&aggregationv1.ResultPredicate_LocalityResultAction{ ZoneAction: getExactAction(), }), - getDiscoveryRequestWithNode(getNode(nodeid, nodecluster, noderegion, "", nodesubzone)), + getDiscoveryRequestWithNode(getNode(nodeid, nodecluster, noderegion, "", nodesubzone, nil)), "RequestNodeFragment exact match resulted in an empty fragment", }, }, @@ -1015,7 +1191,7 @@ var emptyFragmentErrorCases = []TableEntry{ getResultRequestNodeLocalityFragment(&aggregationv1.ResultPredicate_LocalityResultAction{ SubzoneAction: getExactAction(), }), - getDiscoveryRequestWithNode(getNode(nodeid, nodecluster, noderegion, nodezone, "")), + getDiscoveryRequestWithNode(getNode(nodeid, nodecluster, noderegion, nodezone, "", nil)), "RequestNodeFragment exact match resulted in an empty fragment", }, }, @@ -1075,7 +1251,7 @@ var emptyFragmentErrorCases = []TableEntry{ Parameters: []interface{}{ getAnyMatch(true), getResourceNameFragment(-1, getExactAction()), - getDiscoveryRequestWithNode(getNode(nodeid, nodecluster, "", nodezone, nodesubzone)), + getDiscoveryRequestWithNode(getNode(nodeid, nodecluster, "", nodezone, nodesubzone, nil)), "ResourceNamesFragment.Element cannot be negative or larger than length", }, }, @@ -1084,7 +1260,7 @@ var emptyFragmentErrorCases = []TableEntry{ Parameters: []interface{}{ getAnyMatch(true), getResourceNameFragment(10, getExactAction()), - getDiscoveryRequestWithNode(getNode(nodeid, nodecluster, "", nodezone, nodesubzone)), + getDiscoveryRequestWithNode(getNode(nodeid, nodecluster, "", nodezone, nodesubzone, nil)), "ResourceNamesFragment.Element cannot be negative or larger than length", }, }, @@ -1361,6 +1537,12 @@ func getRequestNodeClusterRegexMatch(regex string) *MatchPredicate { } } +func getBoolMatch(value bool) *BoolMatch { + return &aggregationv1.BoolMatch{ + ValueMatch: value, + } +} + func getExactMatch(exact string) *StringMatch { return &aggregationv1.StringMatch{ Type: &aggregationv1.StringMatch_ExactMatch{ @@ -1393,6 +1575,56 @@ func getRequestNodeLocality(region *StringMatch, zone *StringMatch, subZone *Str } } +func getRequestNodeMetadataStringMatch(segments []string, stringMatch *StringMatch) *MatchPredicate { + pathSegments := buildPath(segments) + return &MatchPredicate{ + Type: &aggregationv1.MatchPredicate_RequestNodeMatch_{ + RequestNodeMatch: &aggregationv1.MatchPredicate_RequestNodeMatch{ + Type: &aggregationv1.MatchPredicate_RequestNodeMatch_NodeMetadataMatch{ + NodeMetadataMatch: &aggregationv1.NodeMetadataMatch{ + Path: pathSegments, + Match: &aggregationv1.StructValueMatch{ + Match: &aggregationv1.StructValueMatch_StringMatch{ + StringMatch: stringMatch, + }, + }, + }, + }, + }, + }, + } +} + +func getRequestNodeMetadataBoolMatch(segments []string, boolMatch *BoolMatch) *MatchPredicate { + pathSegments := buildPath(segments) + return &MatchPredicate{ + Type: &aggregationv1.MatchPredicate_RequestNodeMatch_{ + RequestNodeMatch: &aggregationv1.MatchPredicate_RequestNodeMatch{ + Type: &aggregationv1.MatchPredicate_RequestNodeMatch_NodeMetadataMatch{ + NodeMetadataMatch: &aggregationv1.NodeMetadataMatch{ + Path: pathSegments, + Match: &aggregationv1.StructValueMatch{ + Match: &aggregationv1.StructValueMatch_BoolMatch{ + BoolMatch: boolMatch, + }, + }, + }, + }, + }, + }, + } +} + +func buildPath(segments []string) []*aggregationv1.PathSegment { + pathSegments := make([]*aggregationv1.PathSegment, len(segments)) + for i, s := range segments { + pathSegments[i] = &aggregationv1.PathSegment{ + Key: s, + } + } + return pathSegments +} + func getRequestNodeAndMatch(predicates []*MatchPredicate) *MatchPredicate { return &MatchPredicate{ Type: &aggregationv1.MatchPredicate_AndMatch{ @@ -1550,6 +1782,18 @@ func getResultRequestNodeLocalityFragment(action *aggregationv1.ResultPredicate_ } } +func getResultRequestNodeMetadataFragment(action *aggregationv1.ResultPredicate_NodeMetadataAction) *resultPredicate { + return &ResultPredicate{ + Type: &aggregationv1.ResultPredicate_RequestNodeFragment_{ + RequestNodeFragment: &aggregationv1.ResultPredicate_RequestNodeFragment{ + Action: &aggregationv1.ResultPredicate_RequestNodeFragment_NodeMetadataAction{ + NodeMetadataAction: action, + }, + }, + }, + } +} + func getExactAction() *aggregationv1.ResultPredicate_ResultAction { return &aggregationv1.ResultPredicate_ResultAction{ Action: &aggregationv1.ResultPredicate_ResultAction_Exact{ @@ -1570,7 +1814,7 @@ func getRegexAction(pattern string, replace string) *aggregationv1.ResultPredica } func getDiscoveryRequest() *v2.DiscoveryRequest { - return getDiscoveryRequestWithNode(getNode(nodeid, nodecluster, noderegion, nodezone, nodesubzone)) + return getDiscoveryRequestWithNode(getNode(nodeid, nodecluster, noderegion, nodezone, nodesubzone, getNodeMetatada())) } func getDiscoveryRequestWithNode(node *core.Node) *v2.DiscoveryRequest { @@ -1582,7 +1826,8 @@ func getDiscoveryRequestWithNode(node *core.Node) *v2.DiscoveryRequest { } } -func getNode(id string, cluster string, region string, zone string, subzone string) *core.Node { +func getNode(id string, cluster string, region string, zone string, subzone string, + nodeMetadata *structpb.Struct) *core.Node { return &core.Node{ Id: id, Cluster: cluster, @@ -1591,5 +1836,23 @@ func getNode(id string, cluster string, region string, zone string, subzone stri Zone: zone, SubZone: subzone, }, + Metadata: nodeMetadata, + } +} + +func getNodeMetatada() *structpb.Struct { + return &Struct{ + Fields: map[string]*Value{ + "bool-field": {Kind: &structpb.Value_BoolValue{BoolValue: true}}, + "f1": {Kind: &StringValue{StringValue: "v1"}}, + "nested-field": {Kind: &structpb.Value_StructValue{ + StructValue: &Struct{ + Fields: map[string]*Value{ + "f2": {Kind: &StringValue{StringValue: "v2"}}, + "nested-bool-field": {Kind: &structpb.Value_BoolValue{BoolValue: false}}, + }, + }, + }}, + }, } } diff --git a/pkg/api/aggregation/v1/aggregation.pb.go b/pkg/api/aggregation/v1/aggregation.pb.go index de824677..b64f3ebb 100644 --- a/pkg/api/aggregation/v1/aggregation.pb.go +++ b/pkg/api/aggregation/v1/aggregation.pb.go @@ -75,6 +75,7 @@ func (x *KeyerConfiguration) GetFragments() []*KeyerConfiguration_Fragment { return nil } +// [#next-free-field: 4] type StringMatch struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -159,6 +160,55 @@ func (*StringMatch_ExactMatch) isStringMatch_Type() {} func (*StringMatch_RegexMatch) isStringMatch_Type() {} +// [#next-free-field: 2] +type BoolMatch struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + ValueMatch bool `protobuf:"varint,1,opt,name=value_match,json=valueMatch,proto3" json:"value_match,omitempty"` +} + +func (x *BoolMatch) Reset() { + *x = BoolMatch{} + if protoimpl.UnsafeEnabled { + mi := &file_aggregation_v1_aggregation_proto_msgTypes[2] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *BoolMatch) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*BoolMatch) ProtoMessage() {} + +func (x *BoolMatch) ProtoReflect() protoreflect.Message { + mi := &file_aggregation_v1_aggregation_proto_msgTypes[2] + 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 BoolMatch.ProtoReflect.Descriptor instead. +func (*BoolMatch) Descriptor() ([]byte, []int) { + return file_aggregation_v1_aggregation_proto_rawDescGZIP(), []int{2} +} + +func (x *BoolMatch) GetValueMatch() bool { + if x != nil { + return x.ValueMatch + } + return false +} + +// [#next-free-field: 4] type LocalityMatch struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -172,7 +222,7 @@ type LocalityMatch struct { func (x *LocalityMatch) Reset() { *x = LocalityMatch{} if protoimpl.UnsafeEnabled { - mi := &file_aggregation_v1_aggregation_proto_msgTypes[2] + mi := &file_aggregation_v1_aggregation_proto_msgTypes[3] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -185,7 +235,7 @@ func (x *LocalityMatch) String() string { func (*LocalityMatch) ProtoMessage() {} func (x *LocalityMatch) ProtoReflect() protoreflect.Message { - mi := &file_aggregation_v1_aggregation_proto_msgTypes[2] + mi := &file_aggregation_v1_aggregation_proto_msgTypes[3] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -198,7 +248,7 @@ func (x *LocalityMatch) ProtoReflect() protoreflect.Message { // Deprecated: Use LocalityMatch.ProtoReflect.Descriptor instead. func (*LocalityMatch) Descriptor() ([]byte, []int) { - return file_aggregation_v1_aggregation_proto_rawDescGZIP(), []int{2} + return file_aggregation_v1_aggregation_proto_rawDescGZIP(), []int{3} } func (x *LocalityMatch) GetRegion() *StringMatch { @@ -222,6 +272,194 @@ func (x *LocalityMatch) GetSubZone() *StringMatch { return nil } +// [#next-free-field: 2] +type PathSegment struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` +} + +func (x *PathSegment) Reset() { + *x = PathSegment{} + if protoimpl.UnsafeEnabled { + mi := &file_aggregation_v1_aggregation_proto_msgTypes[4] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *PathSegment) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*PathSegment) ProtoMessage() {} + +func (x *PathSegment) ProtoReflect() protoreflect.Message { + mi := &file_aggregation_v1_aggregation_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 PathSegment.ProtoReflect.Descriptor instead. +func (*PathSegment) Descriptor() ([]byte, []int) { + return file_aggregation_v1_aggregation_proto_rawDescGZIP(), []int{4} +} + +func (x *PathSegment) GetKey() string { + if x != nil { + return x.Key + } + return "" +} + +// [#next-free-field: 3] +type StructValueMatch struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + // TODO: we have to match every single type described in + // https://developers.google.com/protocol-buffers/docs/reference/google.protobuf#google.protobuf.Value. + // + // Types that are assignable to Match: + // *StructValueMatch_StringMatch + // *StructValueMatch_BoolMatch + Match isStructValueMatch_Match `protobuf_oneof:"match"` +} + +func (x *StructValueMatch) Reset() { + *x = StructValueMatch{} + if protoimpl.UnsafeEnabled { + mi := &file_aggregation_v1_aggregation_proto_msgTypes[5] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *StructValueMatch) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*StructValueMatch) ProtoMessage() {} + +func (x *StructValueMatch) ProtoReflect() protoreflect.Message { + mi := &file_aggregation_v1_aggregation_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 StructValueMatch.ProtoReflect.Descriptor instead. +func (*StructValueMatch) Descriptor() ([]byte, []int) { + return file_aggregation_v1_aggregation_proto_rawDescGZIP(), []int{5} +} + +func (m *StructValueMatch) GetMatch() isStructValueMatch_Match { + if m != nil { + return m.Match + } + return nil +} + +func (x *StructValueMatch) GetStringMatch() *StringMatch { + if x, ok := x.GetMatch().(*StructValueMatch_StringMatch); ok { + return x.StringMatch + } + return nil +} + +func (x *StructValueMatch) GetBoolMatch() *BoolMatch { + if x, ok := x.GetMatch().(*StructValueMatch_BoolMatch); ok { + return x.BoolMatch + } + return nil +} + +type isStructValueMatch_Match interface { + isStructValueMatch_Match() +} + +type StructValueMatch_StringMatch struct { + StringMatch *StringMatch `protobuf:"bytes,1,opt,name=string_match,json=stringMatch,proto3,oneof"` +} + +type StructValueMatch_BoolMatch struct { + BoolMatch *BoolMatch `protobuf:"bytes,2,opt,name=bool_match,json=boolMatch,proto3,oneof"` +} + +func (*StructValueMatch_StringMatch) isStructValueMatch_Match() {} + +func (*StructValueMatch_BoolMatch) isStructValueMatch_Match() {} + +// [#next-free-field: 3] +type NodeMetadataMatch struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Path []*PathSegment `protobuf:"bytes,1,rep,name=path,proto3" json:"path,omitempty"` + Match *StructValueMatch `protobuf:"bytes,2,opt,name=match,proto3" json:"match,omitempty"` +} + +func (x *NodeMetadataMatch) Reset() { + *x = NodeMetadataMatch{} + if protoimpl.UnsafeEnabled { + mi := &file_aggregation_v1_aggregation_proto_msgTypes[6] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *NodeMetadataMatch) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*NodeMetadataMatch) ProtoMessage() {} + +func (x *NodeMetadataMatch) ProtoReflect() protoreflect.Message { + mi := &file_aggregation_v1_aggregation_proto_msgTypes[6] + 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 NodeMetadataMatch.ProtoReflect.Descriptor instead. +func (*NodeMetadataMatch) Descriptor() ([]byte, []int) { + return file_aggregation_v1_aggregation_proto_rawDescGZIP(), []int{6} +} + +func (x *NodeMetadataMatch) GetPath() []*PathSegment { + if x != nil { + return x.Path + } + return nil +} + +func (x *NodeMetadataMatch) GetMatch() *StructValueMatch { + if x != nil { + return x.Match + } + return nil +} + // This is a recursive structure which allows complex nested match // configurations to be built using various logical operators. // [#next-free-field: 7] @@ -243,7 +481,7 @@ type MatchPredicate struct { func (x *MatchPredicate) Reset() { *x = MatchPredicate{} if protoimpl.UnsafeEnabled { - mi := &file_aggregation_v1_aggregation_proto_msgTypes[3] + mi := &file_aggregation_v1_aggregation_proto_msgTypes[7] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -256,7 +494,7 @@ func (x *MatchPredicate) String() string { func (*MatchPredicate) ProtoMessage() {} func (x *MatchPredicate) ProtoReflect() protoreflect.Message { - mi := &file_aggregation_v1_aggregation_proto_msgTypes[3] + mi := &file_aggregation_v1_aggregation_proto_msgTypes[7] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -269,7 +507,7 @@ func (x *MatchPredicate) ProtoReflect() protoreflect.Message { // Deprecated: Use MatchPredicate.ProtoReflect.Descriptor instead. func (*MatchPredicate) Descriptor() ([]byte, []int) { - return file_aggregation_v1_aggregation_proto_rawDescGZIP(), []int{3} + return file_aggregation_v1_aggregation_proto_rawDescGZIP(), []int{7} } func (m *MatchPredicate) GetType() isMatchPredicate_Type { @@ -390,7 +628,7 @@ type ResultPredicate struct { func (x *ResultPredicate) Reset() { *x = ResultPredicate{} if protoimpl.UnsafeEnabled { - mi := &file_aggregation_v1_aggregation_proto_msgTypes[4] + mi := &file_aggregation_v1_aggregation_proto_msgTypes[8] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -403,7 +641,7 @@ func (x *ResultPredicate) String() string { func (*ResultPredicate) ProtoMessage() {} func (x *ResultPredicate) ProtoReflect() protoreflect.Message { - mi := &file_aggregation_v1_aggregation_proto_msgTypes[4] + mi := &file_aggregation_v1_aggregation_proto_msgTypes[8] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -416,7 +654,7 @@ func (x *ResultPredicate) ProtoReflect() protoreflect.Message { // Deprecated: Use ResultPredicate.ProtoReflect.Descriptor instead. func (*ResultPredicate) Descriptor() ([]byte, []int) { - return file_aggregation_v1_aggregation_proto_rawDescGZIP(), []int{4} + return file_aggregation_v1_aggregation_proto_rawDescGZIP(), []int{8} } func (m *ResultPredicate) GetType() isResultPredicate_Type { @@ -500,7 +738,7 @@ type KeyerConfiguration_Fragment struct { func (x *KeyerConfiguration_Fragment) Reset() { *x = KeyerConfiguration_Fragment{} if protoimpl.UnsafeEnabled { - mi := &file_aggregation_v1_aggregation_proto_msgTypes[5] + mi := &file_aggregation_v1_aggregation_proto_msgTypes[9] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -513,7 +751,7 @@ func (x *KeyerConfiguration_Fragment) String() string { func (*KeyerConfiguration_Fragment) ProtoMessage() {} func (x *KeyerConfiguration_Fragment) ProtoReflect() protoreflect.Message { - mi := &file_aggregation_v1_aggregation_proto_msgTypes[5] + mi := &file_aggregation_v1_aggregation_proto_msgTypes[9] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -553,7 +791,7 @@ type KeyerConfiguration_Fragment_Rule struct { func (x *KeyerConfiguration_Fragment_Rule) Reset() { *x = KeyerConfiguration_Fragment_Rule{} if protoimpl.UnsafeEnabled { - mi := &file_aggregation_v1_aggregation_proto_msgTypes[6] + mi := &file_aggregation_v1_aggregation_proto_msgTypes[10] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -566,7 +804,7 @@ func (x *KeyerConfiguration_Fragment_Rule) String() string { func (*KeyerConfiguration_Fragment_Rule) ProtoMessage() {} func (x *KeyerConfiguration_Fragment_Rule) ProtoReflect() protoreflect.Message { - mi := &file_aggregation_v1_aggregation_proto_msgTypes[6] + mi := &file_aggregation_v1_aggregation_proto_msgTypes[10] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -611,7 +849,7 @@ type MatchPredicate_RequestTypeMatch struct { func (x *MatchPredicate_RequestTypeMatch) Reset() { *x = MatchPredicate_RequestTypeMatch{} if protoimpl.UnsafeEnabled { - mi := &file_aggregation_v1_aggregation_proto_msgTypes[7] + mi := &file_aggregation_v1_aggregation_proto_msgTypes[11] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -624,7 +862,7 @@ func (x *MatchPredicate_RequestTypeMatch) String() string { func (*MatchPredicate_RequestTypeMatch) ProtoMessage() {} func (x *MatchPredicate_RequestTypeMatch) ProtoReflect() protoreflect.Message { - mi := &file_aggregation_v1_aggregation_proto_msgTypes[7] + mi := &file_aggregation_v1_aggregation_proto_msgTypes[11] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -637,7 +875,7 @@ func (x *MatchPredicate_RequestTypeMatch) ProtoReflect() protoreflect.Message { // Deprecated: Use MatchPredicate_RequestTypeMatch.ProtoReflect.Descriptor instead. func (*MatchPredicate_RequestTypeMatch) Descriptor() ([]byte, []int) { - return file_aggregation_v1_aggregation_proto_rawDescGZIP(), []int{3, 0} + return file_aggregation_v1_aggregation_proto_rawDescGZIP(), []int{7, 0} } func (x *MatchPredicate_RequestTypeMatch) GetTypes() []string { @@ -648,7 +886,7 @@ func (x *MatchPredicate_RequestTypeMatch) GetTypes() []string { } // Match on a field in Envoy's request node. -// [#next-free-field: 4] +// [#next-free-field: 5] type MatchPredicate_RequestNodeMatch struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -658,13 +896,14 @@ type MatchPredicate_RequestNodeMatch struct { // *MatchPredicate_RequestNodeMatch_IdMatch // *MatchPredicate_RequestNodeMatch_ClusterMatch // *MatchPredicate_RequestNodeMatch_LocalityMatch + // *MatchPredicate_RequestNodeMatch_NodeMetadataMatch Type isMatchPredicate_RequestNodeMatch_Type `protobuf_oneof:"type"` } func (x *MatchPredicate_RequestNodeMatch) Reset() { *x = MatchPredicate_RequestNodeMatch{} if protoimpl.UnsafeEnabled { - mi := &file_aggregation_v1_aggregation_proto_msgTypes[8] + mi := &file_aggregation_v1_aggregation_proto_msgTypes[12] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -677,7 +916,7 @@ func (x *MatchPredicate_RequestNodeMatch) String() string { func (*MatchPredicate_RequestNodeMatch) ProtoMessage() {} func (x *MatchPredicate_RequestNodeMatch) ProtoReflect() protoreflect.Message { - mi := &file_aggregation_v1_aggregation_proto_msgTypes[8] + mi := &file_aggregation_v1_aggregation_proto_msgTypes[12] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -690,7 +929,7 @@ func (x *MatchPredicate_RequestNodeMatch) ProtoReflect() protoreflect.Message { // Deprecated: Use MatchPredicate_RequestNodeMatch.ProtoReflect.Descriptor instead. func (*MatchPredicate_RequestNodeMatch) Descriptor() ([]byte, []int) { - return file_aggregation_v1_aggregation_proto_rawDescGZIP(), []int{3, 1} + return file_aggregation_v1_aggregation_proto_rawDescGZIP(), []int{7, 1} } func (m *MatchPredicate_RequestNodeMatch) GetType() isMatchPredicate_RequestNodeMatch_Type { @@ -721,6 +960,13 @@ func (x *MatchPredicate_RequestNodeMatch) GetLocalityMatch() *LocalityMatch { return nil } +func (x *MatchPredicate_RequestNodeMatch) GetNodeMetadataMatch() *NodeMetadataMatch { + if x, ok := x.GetType().(*MatchPredicate_RequestNodeMatch_NodeMetadataMatch); ok { + return x.NodeMetadataMatch + } + return nil +} + type isMatchPredicate_RequestNodeMatch_Type interface { isMatchPredicate_RequestNodeMatch_Type() } @@ -737,12 +983,18 @@ type MatchPredicate_RequestNodeMatch_LocalityMatch struct { LocalityMatch *LocalityMatch `protobuf:"bytes,3,opt,name=locality_match,json=localityMatch,proto3,oneof"` } +type MatchPredicate_RequestNodeMatch_NodeMetadataMatch struct { + NodeMetadataMatch *NodeMetadataMatch `protobuf:"bytes,4,opt,name=node_metadata_match,json=nodeMetadataMatch,proto3,oneof"` +} + func (*MatchPredicate_RequestNodeMatch_IdMatch) isMatchPredicate_RequestNodeMatch_Type() {} func (*MatchPredicate_RequestNodeMatch_ClusterMatch) isMatchPredicate_RequestNodeMatch_Type() {} func (*MatchPredicate_RequestNodeMatch_LocalityMatch) isMatchPredicate_RequestNodeMatch_Type() {} +func (*MatchPredicate_RequestNodeMatch_NodeMetadataMatch) isMatchPredicate_RequestNodeMatch_Type() {} + // A set of match configurations used for logical operations. // [#next-free-field: 2] type MatchPredicate_MatchSet struct { @@ -757,7 +1009,7 @@ type MatchPredicate_MatchSet struct { func (x *MatchPredicate_MatchSet) Reset() { *x = MatchPredicate_MatchSet{} if protoimpl.UnsafeEnabled { - mi := &file_aggregation_v1_aggregation_proto_msgTypes[9] + mi := &file_aggregation_v1_aggregation_proto_msgTypes[13] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -770,7 +1022,7 @@ func (x *MatchPredicate_MatchSet) String() string { func (*MatchPredicate_MatchSet) ProtoMessage() {} func (x *MatchPredicate_MatchSet) ProtoReflect() protoreflect.Message { - mi := &file_aggregation_v1_aggregation_proto_msgTypes[9] + mi := &file_aggregation_v1_aggregation_proto_msgTypes[13] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -783,7 +1035,7 @@ func (x *MatchPredicate_MatchSet) ProtoReflect() protoreflect.Message { // Deprecated: Use MatchPredicate_MatchSet.ProtoReflect.Descriptor instead. func (*MatchPredicate_MatchSet) Descriptor() ([]byte, []int) { - return file_aggregation_v1_aggregation_proto_rawDescGZIP(), []int{3, 2} + return file_aggregation_v1_aggregation_proto_rawDescGZIP(), []int{7, 2} } func (x *MatchPredicate_MatchSet) GetRules() []*MatchPredicate { @@ -793,6 +1045,7 @@ func (x *MatchPredicate_MatchSet) GetRules() []*MatchPredicate { return nil } +// [#next-free-field: 3] type ResultPredicate_ResultAction struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -807,7 +1060,7 @@ type ResultPredicate_ResultAction struct { func (x *ResultPredicate_ResultAction) Reset() { *x = ResultPredicate_ResultAction{} if protoimpl.UnsafeEnabled { - mi := &file_aggregation_v1_aggregation_proto_msgTypes[10] + mi := &file_aggregation_v1_aggregation_proto_msgTypes[14] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -820,7 +1073,7 @@ func (x *ResultPredicate_ResultAction) String() string { func (*ResultPredicate_ResultAction) ProtoMessage() {} func (x *ResultPredicate_ResultAction) ProtoReflect() protoreflect.Message { - mi := &file_aggregation_v1_aggregation_proto_msgTypes[10] + mi := &file_aggregation_v1_aggregation_proto_msgTypes[14] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -833,7 +1086,7 @@ func (x *ResultPredicate_ResultAction) ProtoReflect() protoreflect.Message { // Deprecated: Use ResultPredicate_ResultAction.ProtoReflect.Descriptor instead. func (*ResultPredicate_ResultAction) Descriptor() ([]byte, []int) { - return file_aggregation_v1_aggregation_proto_rawDescGZIP(), []int{4, 0} + return file_aggregation_v1_aggregation_proto_rawDescGZIP(), []int{8, 0} } func (m *ResultPredicate_ResultAction) GetAction() isResultPredicate_ResultAction_Action { @@ -890,7 +1143,7 @@ type ResultPredicate_LocalityResultAction struct { func (x *ResultPredicate_LocalityResultAction) Reset() { *x = ResultPredicate_LocalityResultAction{} if protoimpl.UnsafeEnabled { - mi := &file_aggregation_v1_aggregation_proto_msgTypes[11] + mi := &file_aggregation_v1_aggregation_proto_msgTypes[15] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -903,7 +1156,7 @@ func (x *ResultPredicate_LocalityResultAction) String() string { func (*ResultPredicate_LocalityResultAction) ProtoMessage() {} func (x *ResultPredicate_LocalityResultAction) ProtoReflect() protoreflect.Message { - mi := &file_aggregation_v1_aggregation_proto_msgTypes[11] + mi := &file_aggregation_v1_aggregation_proto_msgTypes[15] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -916,7 +1169,7 @@ func (x *ResultPredicate_LocalityResultAction) ProtoReflect() protoreflect.Messa // Deprecated: Use ResultPredicate_LocalityResultAction.ProtoReflect.Descriptor instead. func (*ResultPredicate_LocalityResultAction) Descriptor() ([]byte, []int) { - return file_aggregation_v1_aggregation_proto_rawDescGZIP(), []int{4, 1} + return file_aggregation_v1_aggregation_proto_rawDescGZIP(), []int{8, 1} } func (x *ResultPredicate_LocalityResultAction) GetRegionAction() *ResultPredicate_ResultAction { @@ -940,6 +1193,63 @@ func (x *ResultPredicate_LocalityResultAction) GetSubzoneAction() *ResultPredica return nil } +// [#next-free-field: 3] +type ResultPredicate_NodeMetadataAction struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + Path []*PathSegment `protobuf:"bytes,1,rep,name=path,proto3" json:"path,omitempty"` + Action *ResultPredicate_ResultAction `protobuf:"bytes,2,opt,name=action,proto3" json:"action,omitempty"` +} + +func (x *ResultPredicate_NodeMetadataAction) Reset() { + *x = ResultPredicate_NodeMetadataAction{} + if protoimpl.UnsafeEnabled { + mi := &file_aggregation_v1_aggregation_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *ResultPredicate_NodeMetadataAction) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*ResultPredicate_NodeMetadataAction) ProtoMessage() {} + +func (x *ResultPredicate_NodeMetadataAction) ProtoReflect() protoreflect.Message { + mi := &file_aggregation_v1_aggregation_proto_msgTypes[16] + 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 ResultPredicate_NodeMetadataAction.ProtoReflect.Descriptor instead. +func (*ResultPredicate_NodeMetadataAction) Descriptor() ([]byte, []int) { + return file_aggregation_v1_aggregation_proto_rawDescGZIP(), []int{8, 2} +} + +func (x *ResultPredicate_NodeMetadataAction) GetPath() []*PathSegment { + if x != nil { + return x.Path + } + return nil +} + +func (x *ResultPredicate_NodeMetadataAction) GetAction() *ResultPredicate_ResultAction { + if x != nil { + return x.Action + } + return nil +} + +// [#next-free-field: 2] type ResultPredicate_AndResult struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -951,7 +1261,7 @@ type ResultPredicate_AndResult struct { func (x *ResultPredicate_AndResult) Reset() { *x = ResultPredicate_AndResult{} if protoimpl.UnsafeEnabled { - mi := &file_aggregation_v1_aggregation_proto_msgTypes[12] + mi := &file_aggregation_v1_aggregation_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -964,7 +1274,7 @@ func (x *ResultPredicate_AndResult) String() string { func (*ResultPredicate_AndResult) ProtoMessage() {} func (x *ResultPredicate_AndResult) ProtoReflect() protoreflect.Message { - mi := &file_aggregation_v1_aggregation_proto_msgTypes[12] + mi := &file_aggregation_v1_aggregation_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -977,7 +1287,7 @@ func (x *ResultPredicate_AndResult) ProtoReflect() protoreflect.Message { // Deprecated: Use ResultPredicate_AndResult.ProtoReflect.Descriptor instead. func (*ResultPredicate_AndResult) Descriptor() ([]byte, []int) { - return file_aggregation_v1_aggregation_proto_rawDescGZIP(), []int{4, 2} + return file_aggregation_v1_aggregation_proto_rawDescGZIP(), []int{8, 3} } func (x *ResultPredicate_AndResult) GetResultPredicates() []*ResultPredicate { @@ -988,7 +1298,7 @@ func (x *ResultPredicate_AndResult) GetResultPredicates() []*ResultPredicate { } // Rules for generating the resulting fragment from a Envoy request node. -// [#next-free-field: 4] +// [#next-free-field: 5] type ResultPredicate_RequestNodeFragment struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -998,13 +1308,14 @@ type ResultPredicate_RequestNodeFragment struct { // *ResultPredicate_RequestNodeFragment_IdAction // *ResultPredicate_RequestNodeFragment_ClusterAction // *ResultPredicate_RequestNodeFragment_LocalityAction + // *ResultPredicate_RequestNodeFragment_NodeMetadataAction Action isResultPredicate_RequestNodeFragment_Action `protobuf_oneof:"action"` } func (x *ResultPredicate_RequestNodeFragment) Reset() { *x = ResultPredicate_RequestNodeFragment{} if protoimpl.UnsafeEnabled { - mi := &file_aggregation_v1_aggregation_proto_msgTypes[13] + mi := &file_aggregation_v1_aggregation_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1017,7 +1328,7 @@ func (x *ResultPredicate_RequestNodeFragment) String() string { func (*ResultPredicate_RequestNodeFragment) ProtoMessage() {} func (x *ResultPredicate_RequestNodeFragment) ProtoReflect() protoreflect.Message { - mi := &file_aggregation_v1_aggregation_proto_msgTypes[13] + mi := &file_aggregation_v1_aggregation_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1030,7 +1341,7 @@ func (x *ResultPredicate_RequestNodeFragment) ProtoReflect() protoreflect.Messag // Deprecated: Use ResultPredicate_RequestNodeFragment.ProtoReflect.Descriptor instead. func (*ResultPredicate_RequestNodeFragment) Descriptor() ([]byte, []int) { - return file_aggregation_v1_aggregation_proto_rawDescGZIP(), []int{4, 3} + return file_aggregation_v1_aggregation_proto_rawDescGZIP(), []int{8, 4} } func (m *ResultPredicate_RequestNodeFragment) GetAction() isResultPredicate_RequestNodeFragment_Action { @@ -1061,6 +1372,13 @@ func (x *ResultPredicate_RequestNodeFragment) GetLocalityAction() *ResultPredica return nil } +func (x *ResultPredicate_RequestNodeFragment) GetNodeMetadataAction() *ResultPredicate_NodeMetadataAction { + if x, ok := x.GetAction().(*ResultPredicate_RequestNodeFragment_NodeMetadataAction); ok { + return x.NodeMetadataAction + } + return nil +} + type isResultPredicate_RequestNodeFragment_Action interface { isResultPredicate_RequestNodeFragment_Action() } @@ -1077,6 +1395,10 @@ type ResultPredicate_RequestNodeFragment_LocalityAction struct { LocalityAction *ResultPredicate_LocalityResultAction `protobuf:"bytes,3,opt,name=locality_action,json=localityAction,proto3,oneof"` } +type ResultPredicate_RequestNodeFragment_NodeMetadataAction struct { + NodeMetadataAction *ResultPredicate_NodeMetadataAction `protobuf:"bytes,4,opt,name=node_metadata_action,json=nodeMetadataAction,proto3,oneof"` +} + func (*ResultPredicate_RequestNodeFragment_IdAction) isResultPredicate_RequestNodeFragment_Action() {} func (*ResultPredicate_RequestNodeFragment_ClusterAction) isResultPredicate_RequestNodeFragment_Action() { @@ -1085,6 +1407,9 @@ func (*ResultPredicate_RequestNodeFragment_ClusterAction) isResultPredicate_Requ func (*ResultPredicate_RequestNodeFragment_LocalityAction) isResultPredicate_RequestNodeFragment_Action() { } +func (*ResultPredicate_RequestNodeFragment_NodeMetadataAction) isResultPredicate_RequestNodeFragment_Action() { +} + // Rules for generating the resulting fragment from Envoy request names. // [#next-free-field: 3] type ResultPredicate_ResourceNamesFragment struct { @@ -1101,7 +1426,7 @@ type ResultPredicate_ResourceNamesFragment struct { func (x *ResultPredicate_ResourceNamesFragment) Reset() { *x = ResultPredicate_ResourceNamesFragment{} if protoimpl.UnsafeEnabled { - mi := &file_aggregation_v1_aggregation_proto_msgTypes[14] + mi := &file_aggregation_v1_aggregation_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1114,7 +1439,7 @@ func (x *ResultPredicate_ResourceNamesFragment) String() string { func (*ResultPredicate_ResourceNamesFragment) ProtoMessage() {} func (x *ResultPredicate_ResourceNamesFragment) ProtoReflect() protoreflect.Message { - mi := &file_aggregation_v1_aggregation_proto_msgTypes[14] + mi := &file_aggregation_v1_aggregation_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1127,7 +1452,7 @@ func (x *ResultPredicate_ResourceNamesFragment) ProtoReflect() protoreflect.Mess // Deprecated: Use ResultPredicate_ResourceNamesFragment.ProtoReflect.Descriptor instead. func (*ResultPredicate_ResourceNamesFragment) Descriptor() ([]byte, []int) { - return file_aggregation_v1_aggregation_proto_rawDescGZIP(), []int{4, 4} + return file_aggregation_v1_aggregation_proto_rawDescGZIP(), []int{8, 5} } func (x *ResultPredicate_ResourceNamesFragment) GetElement() int32 { @@ -1159,7 +1484,7 @@ type ResultPredicate_ResultAction_RegexAction struct { func (x *ResultPredicate_ResultAction_RegexAction) Reset() { *x = ResultPredicate_ResultAction_RegexAction{} if protoimpl.UnsafeEnabled { - mi := &file_aggregation_v1_aggregation_proto_msgTypes[15] + mi := &file_aggregation_v1_aggregation_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1172,7 +1497,7 @@ func (x *ResultPredicate_ResultAction_RegexAction) String() string { func (*ResultPredicate_ResultAction_RegexAction) ProtoMessage() {} func (x *ResultPredicate_ResultAction_RegexAction) ProtoReflect() protoreflect.Message { - mi := &file_aggregation_v1_aggregation_proto_msgTypes[15] + mi := &file_aggregation_v1_aggregation_proto_msgTypes[20] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1185,7 +1510,7 @@ func (x *ResultPredicate_ResultAction_RegexAction) ProtoReflect() protoreflect.M // Deprecated: Use ResultPredicate_ResultAction_RegexAction.ProtoReflect.Descriptor instead. func (*ResultPredicate_ResultAction_RegexAction) Descriptor() ([]byte, []int) { - return file_aggregation_v1_aggregation_proto_rawDescGZIP(), []int{4, 0, 0} + return file_aggregation_v1_aggregation_proto_rawDescGZIP(), []int{8, 0, 0} } func (x *ResultPredicate_ResultAction_RegexAction) GetPattern() string { @@ -1236,17 +1561,41 @@ var file_aggregation_v1_aggregation_proto_rawDesc = []byte{ 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x21, 0x0a, 0x0b, 0x72, 0x65, 0x67, 0x65, 0x78, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0a, 0x72, 0x65, 0x67, 0x65, 0x78, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x42, 0x0b, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, - 0x12, 0x03, 0xf8, 0x42, 0x01, 0x22, 0xa4, 0x01, 0x0a, 0x0d, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x69, - 0x74, 0x79, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x30, 0x0a, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, - 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4d, 0x61, 0x74, 0x63, - 0x68, 0x52, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x12, 0x2c, 0x0a, 0x04, 0x7a, 0x6f, 0x6e, - 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, + 0x12, 0x03, 0xf8, 0x42, 0x01, 0x22, 0x2c, 0x0a, 0x09, 0x42, 0x6f, 0x6f, 0x6c, 0x4d, 0x61, 0x74, + 0x63, 0x68, 0x12, 0x1f, 0x0a, 0x0b, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x5f, 0x6d, 0x61, 0x74, 0x63, + 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0a, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x4d, 0x61, + 0x74, 0x63, 0x68, 0x22, 0xa4, 0x01, 0x0a, 0x0d, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x69, 0x74, 0x79, + 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x30, 0x0a, 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, + 0x06, 0x72, 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x12, 0x2c, 0x0a, 0x04, 0x7a, 0x6f, 0x6e, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, + 0x69, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, + 0x04, 0x7a, 0x6f, 0x6e, 0x65, 0x12, 0x33, 0x0a, 0x08, 0x73, 0x75, 0x62, 0x5f, 0x7a, 0x6f, 0x6e, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4d, 0x61, 0x74, 0x63, - 0x68, 0x52, 0x04, 0x7a, 0x6f, 0x6e, 0x65, 0x12, 0x33, 0x0a, 0x08, 0x73, 0x75, 0x62, 0x5f, 0x7a, - 0x6f, 0x6e, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x61, 0x67, 0x67, 0x72, - 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x4d, 0x61, - 0x74, 0x63, 0x68, 0x52, 0x07, 0x73, 0x75, 0x62, 0x5a, 0x6f, 0x6e, 0x65, 0x22, 0xa1, 0x06, 0x0a, + 0x68, 0x52, 0x07, 0x73, 0x75, 0x62, 0x5a, 0x6f, 0x6e, 0x65, 0x22, 0x28, 0x0a, 0x0b, 0x50, 0x61, + 0x74, 0x68, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x19, 0x0a, 0x03, 0x6b, 0x65, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, + 0x03, 0x6b, 0x65, 0x79, 0x22, 0x98, 0x01, 0x0a, 0x10, 0x53, 0x74, 0x72, 0x75, 0x63, 0x74, 0x56, + 0x61, 0x6c, 0x75, 0x65, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x3d, 0x0a, 0x0c, 0x73, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x18, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x53, 0x74, + 0x72, 0x69, 0x6e, 0x67, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x48, 0x00, 0x52, 0x0b, 0x73, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x37, 0x0a, 0x0a, 0x62, 0x6f, 0x6f, 0x6c, + 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x61, + 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x4d, + 0x61, 0x74, 0x63, 0x68, 0x48, 0x00, 0x52, 0x09, 0x62, 0x6f, 0x6f, 0x6c, 0x4d, 0x61, 0x74, 0x63, + 0x68, 0x42, 0x0c, 0x0a, 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x03, 0xf8, 0x42, 0x01, 0x22, + 0x8a, 0x01, 0x0a, 0x11, 0x4e, 0x6f, 0x64, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, + 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x36, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x2e, 0x50, 0x61, 0x74, 0x68, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x08, 0xfa, + 0x42, 0x05, 0x92, 0x01, 0x02, 0x08, 0x01, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x3d, 0x0a, + 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x61, + 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x53, 0x74, 0x72, 0x75, 0x63, + 0x74, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x42, 0x08, 0xfa, 0x42, 0x05, + 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x05, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x22, 0xf3, 0x06, 0x0a, 0x0e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x50, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x43, 0x0a, 0x09, 0x61, 0x6e, 0x64, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, @@ -1277,7 +1626,7 @@ var file_aggregation_v1_aggregation_proto_rawDesc = []byte{ 0x64, 0x65, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x1a, 0x32, 0x0a, 0x10, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x54, 0x79, 0x70, 0x65, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x1e, 0x0a, 0x05, 0x74, 0x79, 0x70, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x92, - 0x01, 0x02, 0x08, 0x01, 0x52, 0x05, 0x74, 0x79, 0x70, 0x65, 0x73, 0x1a, 0xdc, 0x01, 0x0a, 0x10, + 0x01, 0x02, 0x08, 0x01, 0x52, 0x05, 0x74, 0x79, 0x70, 0x65, 0x73, 0x1a, 0xae, 0x02, 0x0a, 0x10, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x35, 0x0a, 0x08, 0x69, 0x64, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, @@ -1290,103 +1639,124 @@ var file_aggregation_v1_aggregation_proto_rawDesc = []byte{ 0x6c, 0x69, 0x74, 0x79, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x48, 0x00, 0x52, 0x0d, - 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x42, 0x0b, 0x0a, - 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x03, 0xf8, 0x42, 0x01, 0x1a, 0x47, 0x0a, 0x08, 0x4d, 0x61, - 0x74, 0x63, 0x68, 0x53, 0x65, 0x74, 0x12, 0x3b, 0x0a, 0x05, 0x72, 0x75, 0x6c, 0x65, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, - 0x69, 0x6f, 0x6e, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x50, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, - 0x74, 0x65, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x92, 0x01, 0x02, 0x08, 0x02, 0x52, 0x05, 0x72, 0x75, - 0x6c, 0x65, 0x73, 0x42, 0x0b, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x03, 0xf8, 0x42, 0x01, - 0x22, 0xf0, 0x0a, 0x0a, 0x0f, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x50, 0x72, 0x65, 0x64, 0x69, - 0x63, 0x61, 0x74, 0x65, 0x12, 0x47, 0x0a, 0x0a, 0x61, 0x6e, 0x64, 0x5f, 0x72, 0x65, 0x73, 0x75, - 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, + 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x12, 0x50, 0x0a, + 0x13, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x6d, + 0x61, 0x74, 0x63, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x61, 0x67, 0x67, + 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x4d, 0x65, 0x74, + 0x61, 0x64, 0x61, 0x74, 0x61, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x48, 0x00, 0x52, 0x11, 0x6e, 0x6f, + 0x64, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x42, + 0x0b, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x03, 0xf8, 0x42, 0x01, 0x1a, 0x47, 0x0a, 0x08, + 0x4d, 0x61, 0x74, 0x63, 0x68, 0x53, 0x65, 0x74, 0x12, 0x3b, 0x0a, 0x05, 0x72, 0x75, 0x6c, 0x65, + 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x50, 0x72, 0x65, 0x64, 0x69, + 0x63, 0x61, 0x74, 0x65, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x92, 0x01, 0x02, 0x08, 0x02, 0x52, 0x05, + 0x72, 0x75, 0x6c, 0x65, 0x73, 0x42, 0x0b, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x03, 0xf8, + 0x42, 0x01, 0x22, 0xf1, 0x0c, 0x0a, 0x0f, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x50, 0x72, 0x65, + 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x12, 0x47, 0x0a, 0x0a, 0x61, 0x6e, 0x64, 0x5f, 0x72, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x26, 0x2e, 0x61, 0x67, 0x67, + 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x50, + 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x2e, 0x41, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x48, 0x00, 0x52, 0x09, 0x61, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, + 0x66, 0x0a, 0x15, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x5f, + 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, + 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x50, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x2e, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x46, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, + 0x48, 0x00, 0x52, 0x13, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x46, + 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x6c, 0x0a, 0x17, 0x72, 0x65, 0x73, 0x6f, 0x75, + 0x72, 0x63, 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, + 0x6e, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x50, 0x72, 0x65, - 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x2e, 0x41, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, - 0x48, 0x00, 0x52, 0x09, 0x61, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x66, 0x0a, - 0x15, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x6e, 0x6f, 0x64, 0x65, 0x5f, 0x66, 0x72, - 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x30, 0x2e, 0x61, - 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, - 0x74, 0x50, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x2e, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x46, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x48, 0x00, - 0x52, 0x13, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x46, 0x72, 0x61, - 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x6c, 0x0a, 0x17, 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, - 0x65, 0x5f, 0x6e, 0x61, 0x6d, 0x65, 0x73, 0x5f, 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x32, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x50, 0x72, 0x65, 0x64, 0x69, - 0x63, 0x61, 0x74, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4e, 0x61, 0x6d, - 0x65, 0x73, 0x46, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x15, 0x72, 0x65, - 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x46, 0x72, 0x61, 0x67, 0x6d, - 0x65, 0x6e, 0x74, 0x12, 0x29, 0x0a, 0x0f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5f, 0x66, 0x72, - 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0e, - 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x46, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x1a, 0xef, - 0x01, 0x0a, 0x0c, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, - 0x1f, 0x0a, 0x05, 0x65, 0x78, 0x61, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, 0x42, 0x07, - 0xfa, 0x42, 0x04, 0x6a, 0x02, 0x08, 0x01, 0x48, 0x00, 0x52, 0x05, 0x65, 0x78, 0x61, 0x63, 0x74, - 0x12, 0x5a, 0x0a, 0x0c, 0x72, 0x65, 0x67, 0x65, 0x78, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, - 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x50, 0x72, 0x65, 0x64, 0x69, - 0x63, 0x61, 0x74, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x2e, 0x52, 0x65, 0x67, 0x65, 0x78, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, - 0x0b, 0x72, 0x65, 0x67, 0x65, 0x78, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x53, 0x0a, 0x0b, - 0x52, 0x65, 0x67, 0x65, 0x78, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x0a, 0x07, 0x70, - 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, 0xfa, 0x42, - 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x07, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x12, 0x21, - 0x0a, 0x07, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x42, - 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x00, 0x52, 0x07, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, - 0x65, 0x42, 0x0d, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x03, 0xf8, 0x42, 0x01, - 0x1a, 0x84, 0x02, 0x0a, 0x14, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x65, 0x73, - 0x75, 0x6c, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x4e, 0x0a, 0x0d, 0x72, 0x65, 0x67, - 0x69, 0x6f, 0x6e, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4e, + 0x61, 0x6d, 0x65, 0x73, 0x46, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x48, 0x00, 0x52, 0x15, + 0x72, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x46, 0x72, 0x61, + 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x29, 0x0a, 0x0f, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5f, + 0x66, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, + 0x52, 0x0e, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x46, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, + 0x1a, 0xef, 0x01, 0x0a, 0x0c, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x12, 0x1f, 0x0a, 0x05, 0x65, 0x78, 0x61, 0x63, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x08, + 0x42, 0x07, 0xfa, 0x42, 0x04, 0x6a, 0x02, 0x08, 0x01, 0x48, 0x00, 0x52, 0x05, 0x65, 0x78, 0x61, + 0x63, 0x74, 0x12, 0x5a, 0x0a, 0x0c, 0x72, 0x65, 0x67, 0x65, 0x78, 0x5f, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, + 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x50, 0x72, 0x65, + 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x41, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x67, 0x65, 0x78, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x48, + 0x00, 0x52, 0x0b, 0x72, 0x65, 0x67, 0x65, 0x78, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x53, + 0x0a, 0x0b, 0x52, 0x65, 0x67, 0x65, 0x78, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x21, 0x0a, + 0x07, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x42, 0x07, + 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x01, 0x52, 0x07, 0x70, 0x61, 0x74, 0x74, 0x65, 0x72, 0x6e, + 0x12, 0x21, 0x0a, 0x07, 0x72, 0x65, 0x70, 0x6c, 0x61, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x72, 0x02, 0x10, 0x00, 0x52, 0x07, 0x72, 0x65, 0x70, 0x6c, + 0x61, 0x63, 0x65, 0x42, 0x0d, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x03, 0xf8, + 0x42, 0x01, 0x1a, 0x84, 0x02, 0x0a, 0x14, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x52, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x4e, 0x0a, 0x0d, 0x72, + 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x50, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, + 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x72, + 0x65, 0x67, 0x69, 0x6f, 0x6e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x4a, 0x0a, 0x0b, 0x7a, + 0x6f, 0x6e, 0x65, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x50, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x2e, 0x52, - 0x65, 0x73, 0x75, 0x6c, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x72, 0x65, 0x67, - 0x69, 0x6f, 0x6e, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x4a, 0x0a, 0x0b, 0x7a, 0x6f, 0x6e, - 0x65, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, - 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x73, - 0x75, 0x6c, 0x74, 0x50, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x2e, 0x52, 0x65, 0x73, - 0x75, 0x6c, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x7a, 0x6f, 0x6e, 0x65, 0x41, - 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x50, 0x0a, 0x0e, 0x73, 0x75, 0x62, 0x7a, 0x6f, 0x6e, 0x65, - 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, - 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x73, 0x75, - 0x6c, 0x74, 0x50, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, - 0x6c, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0d, 0x73, 0x75, 0x62, 0x7a, 0x6f, 0x6e, - 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x60, 0x0a, 0x09, 0x41, 0x6e, 0x64, 0x52, 0x65, - 0x73, 0x75, 0x6c, 0x74, 0x12, 0x53, 0x0a, 0x11, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x5f, 0x70, - 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x1c, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, - 0x73, 0x75, 0x6c, 0x74, 0x50, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x42, 0x08, 0xfa, - 0x42, 0x05, 0x92, 0x01, 0x02, 0x08, 0x02, 0x52, 0x10, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x50, - 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x1a, 0xa0, 0x02, 0x0a, 0x13, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x46, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, - 0x74, 0x12, 0x48, 0x0a, 0x09, 0x69, 0x64, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x50, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, - 0x74, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x48, - 0x00, 0x52, 0x08, 0x69, 0x64, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x52, 0x0a, 0x0e, 0x63, - 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x50, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, - 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, - 0x52, 0x0d, 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, - 0x5c, 0x0a, 0x0f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x5f, 0x61, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0a, 0x7a, 0x6f, 0x6e, + 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x50, 0x0a, 0x0e, 0x73, 0x75, 0x62, 0x7a, 0x6f, + 0x6e, 0x65, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x29, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x50, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x2e, 0x52, 0x65, + 0x73, 0x75, 0x6c, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0d, 0x73, 0x75, 0x62, 0x7a, + 0x6f, 0x6e, 0x65, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x99, 0x01, 0x0a, 0x12, 0x4e, 0x6f, + 0x64, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x12, 0x36, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x18, + 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x50, 0x61, 0x74, + 0x68, 0x53, 0x65, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x92, 0x01, 0x02, + 0x08, 0x01, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x4b, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x50, 0x72, 0x65, - 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x52, - 0x65, 0x73, 0x75, 0x6c, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x0e, 0x6c, - 0x6f, 0x63, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x0d, 0x0a, - 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x03, 0xf8, 0x42, 0x01, 0x1a, 0x87, 0x01, 0x0a, - 0x15, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x73, 0x46, 0x72, - 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x21, 0x0a, 0x07, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, - 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x1a, 0x02, 0x28, 0x00, - 0x52, 0x07, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x4b, 0x0a, 0x06, 0x61, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x61, 0x67, 0x67, 0x72, + 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x41, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x06, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x1a, 0x60, 0x0a, 0x09, 0x41, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x12, 0x53, 0x0a, 0x11, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x5f, 0x70, 0x72, 0x65, + 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, + 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x50, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x42, 0x08, 0xfa, 0x42, 0x05, + 0x92, 0x01, 0x02, 0x08, 0x02, 0x52, 0x10, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x50, 0x72, 0x65, + 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x1a, 0x85, 0x03, 0x0a, 0x13, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x4e, 0x6f, 0x64, 0x65, 0x46, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x12, + 0x48, 0x0a, 0x09, 0x69, 0x64, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, + 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x50, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, + 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, + 0x08, 0x69, 0x64, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x52, 0x0a, 0x0e, 0x63, 0x6c, 0x75, + 0x73, 0x74, 0x65, 0x72, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x29, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, + 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x50, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x2e, + 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x0d, + 0x63, 0x6c, 0x75, 0x73, 0x74, 0x65, 0x72, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x5c, 0x0a, + 0x0f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x5f, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x31, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x50, 0x72, 0x65, 0x64, 0x69, + 0x63, 0x61, 0x74, 0x65, 0x2e, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x69, 0x74, 0x79, 0x52, 0x65, 0x73, + 0x75, 0x6c, 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x0e, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x69, 0x74, 0x79, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x63, 0x0a, 0x14, 0x6e, + 0x6f, 0x64, 0x65, 0x5f, 0x6d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x5f, 0x61, 0x63, 0x74, + 0x69, 0x6f, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x2f, 0x2e, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x50, 0x72, - 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x41, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, 0x01, 0x52, 0x06, - 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x0b, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x03, - 0xf8, 0x42, 0x01, 0x42, 0x1e, 0x5a, 0x1c, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x3b, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, - 0x6e, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x2e, 0x4e, 0x6f, 0x64, 0x65, 0x4d, 0x65, 0x74, 0x61, + 0x64, 0x61, 0x74, 0x61, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x48, 0x00, 0x52, 0x12, 0x6e, 0x6f, + 0x64, 0x65, 0x4d, 0x65, 0x74, 0x61, 0x64, 0x61, 0x74, 0x61, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x42, 0x0d, 0x0a, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x03, 0xf8, 0x42, 0x01, 0x1a, + 0x87, 0x01, 0x0a, 0x15, 0x52, 0x65, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x4e, 0x61, 0x6d, 0x65, + 0x73, 0x46, 0x72, 0x61, 0x67, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x21, 0x0a, 0x07, 0x65, 0x6c, 0x65, + 0x6d, 0x65, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x1a, + 0x02, 0x28, 0x00, 0x52, 0x07, 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x12, 0x4b, 0x0a, 0x06, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x61, + 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, + 0x74, 0x50, 0x72, 0x65, 0x64, 0x69, 0x63, 0x61, 0x74, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, + 0x74, 0x41, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x08, 0xfa, 0x42, 0x05, 0x8a, 0x01, 0x02, 0x10, + 0x01, 0x52, 0x06, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x0b, 0x0a, 0x04, 0x74, 0x79, 0x70, + 0x65, 0x12, 0x03, 0xf8, 0x42, 0x01, 0x42, 0x1e, 0x5a, 0x1c, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, + 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x31, 0x3b, 0x61, 0x67, 0x67, 0x72, 0x65, 0x67, 0x61, + 0x74, 0x69, 0x6f, 0x6e, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1401,59 +1771,72 @@ func file_aggregation_v1_aggregation_proto_rawDescGZIP() []byte { return file_aggregation_v1_aggregation_proto_rawDescData } -var file_aggregation_v1_aggregation_proto_msgTypes = make([]protoimpl.MessageInfo, 16) +var file_aggregation_v1_aggregation_proto_msgTypes = make([]protoimpl.MessageInfo, 21) var file_aggregation_v1_aggregation_proto_goTypes = []interface{}{ (*KeyerConfiguration)(nil), // 0: aggregation.KeyerConfiguration (*StringMatch)(nil), // 1: aggregation.StringMatch - (*LocalityMatch)(nil), // 2: aggregation.LocalityMatch - (*MatchPredicate)(nil), // 3: aggregation.MatchPredicate - (*ResultPredicate)(nil), // 4: aggregation.ResultPredicate - (*KeyerConfiguration_Fragment)(nil), // 5: aggregation.KeyerConfiguration.Fragment - (*KeyerConfiguration_Fragment_Rule)(nil), // 6: aggregation.KeyerConfiguration.Fragment.Rule - (*MatchPredicate_RequestTypeMatch)(nil), // 7: aggregation.MatchPredicate.RequestTypeMatch - (*MatchPredicate_RequestNodeMatch)(nil), // 8: aggregation.MatchPredicate.RequestNodeMatch - (*MatchPredicate_MatchSet)(nil), // 9: aggregation.MatchPredicate.MatchSet - (*ResultPredicate_ResultAction)(nil), // 10: aggregation.ResultPredicate.ResultAction - (*ResultPredicate_LocalityResultAction)(nil), // 11: aggregation.ResultPredicate.LocalityResultAction - (*ResultPredicate_AndResult)(nil), // 12: aggregation.ResultPredicate.AndResult - (*ResultPredicate_RequestNodeFragment)(nil), // 13: aggregation.ResultPredicate.RequestNodeFragment - (*ResultPredicate_ResourceNamesFragment)(nil), // 14: aggregation.ResultPredicate.ResourceNamesFragment - (*ResultPredicate_ResultAction_RegexAction)(nil), // 15: aggregation.ResultPredicate.ResultAction.RegexAction + (*BoolMatch)(nil), // 2: aggregation.BoolMatch + (*LocalityMatch)(nil), // 3: aggregation.LocalityMatch + (*PathSegment)(nil), // 4: aggregation.PathSegment + (*StructValueMatch)(nil), // 5: aggregation.StructValueMatch + (*NodeMetadataMatch)(nil), // 6: aggregation.NodeMetadataMatch + (*MatchPredicate)(nil), // 7: aggregation.MatchPredicate + (*ResultPredicate)(nil), // 8: aggregation.ResultPredicate + (*KeyerConfiguration_Fragment)(nil), // 9: aggregation.KeyerConfiguration.Fragment + (*KeyerConfiguration_Fragment_Rule)(nil), // 10: aggregation.KeyerConfiguration.Fragment.Rule + (*MatchPredicate_RequestTypeMatch)(nil), // 11: aggregation.MatchPredicate.RequestTypeMatch + (*MatchPredicate_RequestNodeMatch)(nil), // 12: aggregation.MatchPredicate.RequestNodeMatch + (*MatchPredicate_MatchSet)(nil), // 13: aggregation.MatchPredicate.MatchSet + (*ResultPredicate_ResultAction)(nil), // 14: aggregation.ResultPredicate.ResultAction + (*ResultPredicate_LocalityResultAction)(nil), // 15: aggregation.ResultPredicate.LocalityResultAction + (*ResultPredicate_NodeMetadataAction)(nil), // 16: aggregation.ResultPredicate.NodeMetadataAction + (*ResultPredicate_AndResult)(nil), // 17: aggregation.ResultPredicate.AndResult + (*ResultPredicate_RequestNodeFragment)(nil), // 18: aggregation.ResultPredicate.RequestNodeFragment + (*ResultPredicate_ResourceNamesFragment)(nil), // 19: aggregation.ResultPredicate.ResourceNamesFragment + (*ResultPredicate_ResultAction_RegexAction)(nil), // 20: aggregation.ResultPredicate.ResultAction.RegexAction } var file_aggregation_v1_aggregation_proto_depIdxs = []int32{ - 5, // 0: aggregation.KeyerConfiguration.fragments:type_name -> aggregation.KeyerConfiguration.Fragment + 9, // 0: aggregation.KeyerConfiguration.fragments:type_name -> aggregation.KeyerConfiguration.Fragment 1, // 1: aggregation.LocalityMatch.region:type_name -> aggregation.StringMatch 1, // 2: aggregation.LocalityMatch.zone:type_name -> aggregation.StringMatch 1, // 3: aggregation.LocalityMatch.sub_zone:type_name -> aggregation.StringMatch - 9, // 4: aggregation.MatchPredicate.and_match:type_name -> aggregation.MatchPredicate.MatchSet - 9, // 5: aggregation.MatchPredicate.or_match:type_name -> aggregation.MatchPredicate.MatchSet - 3, // 6: aggregation.MatchPredicate.not_match:type_name -> aggregation.MatchPredicate - 7, // 7: aggregation.MatchPredicate.request_type_match:type_name -> aggregation.MatchPredicate.RequestTypeMatch - 8, // 8: aggregation.MatchPredicate.request_node_match:type_name -> aggregation.MatchPredicate.RequestNodeMatch - 12, // 9: aggregation.ResultPredicate.and_result:type_name -> aggregation.ResultPredicate.AndResult - 13, // 10: aggregation.ResultPredicate.request_node_fragment:type_name -> aggregation.ResultPredicate.RequestNodeFragment - 14, // 11: aggregation.ResultPredicate.resource_names_fragment:type_name -> aggregation.ResultPredicate.ResourceNamesFragment - 6, // 12: aggregation.KeyerConfiguration.Fragment.rules:type_name -> aggregation.KeyerConfiguration.Fragment.Rule - 3, // 13: aggregation.KeyerConfiguration.Fragment.Rule.match:type_name -> aggregation.MatchPredicate - 4, // 14: aggregation.KeyerConfiguration.Fragment.Rule.result:type_name -> aggregation.ResultPredicate - 1, // 15: aggregation.MatchPredicate.RequestNodeMatch.id_match:type_name -> aggregation.StringMatch - 1, // 16: aggregation.MatchPredicate.RequestNodeMatch.cluster_match:type_name -> aggregation.StringMatch - 2, // 17: aggregation.MatchPredicate.RequestNodeMatch.locality_match:type_name -> aggregation.LocalityMatch - 3, // 18: aggregation.MatchPredicate.MatchSet.rules:type_name -> aggregation.MatchPredicate - 15, // 19: aggregation.ResultPredicate.ResultAction.regex_action:type_name -> aggregation.ResultPredicate.ResultAction.RegexAction - 10, // 20: aggregation.ResultPredicate.LocalityResultAction.region_action:type_name -> aggregation.ResultPredicate.ResultAction - 10, // 21: aggregation.ResultPredicate.LocalityResultAction.zone_action:type_name -> aggregation.ResultPredicate.ResultAction - 10, // 22: aggregation.ResultPredicate.LocalityResultAction.subzone_action:type_name -> aggregation.ResultPredicate.ResultAction - 4, // 23: aggregation.ResultPredicate.AndResult.result_predicates:type_name -> aggregation.ResultPredicate - 10, // 24: aggregation.ResultPredicate.RequestNodeFragment.id_action:type_name -> aggregation.ResultPredicate.ResultAction - 10, // 25: aggregation.ResultPredicate.RequestNodeFragment.cluster_action:type_name -> aggregation.ResultPredicate.ResultAction - 11, // 26: aggregation.ResultPredicate.RequestNodeFragment.locality_action:type_name -> aggregation.ResultPredicate.LocalityResultAction - 10, // 27: aggregation.ResultPredicate.ResourceNamesFragment.action:type_name -> aggregation.ResultPredicate.ResultAction - 28, // [28:28] is the sub-list for method output_type - 28, // [28:28] is the sub-list for method input_type - 28, // [28:28] is the sub-list for extension type_name - 28, // [28:28] is the sub-list for extension extendee - 0, // [0:28] is the sub-list for field type_name + 1, // 4: aggregation.StructValueMatch.string_match:type_name -> aggregation.StringMatch + 2, // 5: aggregation.StructValueMatch.bool_match:type_name -> aggregation.BoolMatch + 4, // 6: aggregation.NodeMetadataMatch.path:type_name -> aggregation.PathSegment + 5, // 7: aggregation.NodeMetadataMatch.match:type_name -> aggregation.StructValueMatch + 13, // 8: aggregation.MatchPredicate.and_match:type_name -> aggregation.MatchPredicate.MatchSet + 13, // 9: aggregation.MatchPredicate.or_match:type_name -> aggregation.MatchPredicate.MatchSet + 7, // 10: aggregation.MatchPredicate.not_match:type_name -> aggregation.MatchPredicate + 11, // 11: aggregation.MatchPredicate.request_type_match:type_name -> aggregation.MatchPredicate.RequestTypeMatch + 12, // 12: aggregation.MatchPredicate.request_node_match:type_name -> aggregation.MatchPredicate.RequestNodeMatch + 17, // 13: aggregation.ResultPredicate.and_result:type_name -> aggregation.ResultPredicate.AndResult + 18, // 14: aggregation.ResultPredicate.request_node_fragment:type_name -> aggregation.ResultPredicate.RequestNodeFragment + 19, // 15: aggregation.ResultPredicate.resource_names_fragment:type_name -> aggregation.ResultPredicate.ResourceNamesFragment + 10, // 16: aggregation.KeyerConfiguration.Fragment.rules:type_name -> aggregation.KeyerConfiguration.Fragment.Rule + 7, // 17: aggregation.KeyerConfiguration.Fragment.Rule.match:type_name -> aggregation.MatchPredicate + 8, // 18: aggregation.KeyerConfiguration.Fragment.Rule.result:type_name -> aggregation.ResultPredicate + 1, // 19: aggregation.MatchPredicate.RequestNodeMatch.id_match:type_name -> aggregation.StringMatch + 1, // 20: aggregation.MatchPredicate.RequestNodeMatch.cluster_match:type_name -> aggregation.StringMatch + 3, // 21: aggregation.MatchPredicate.RequestNodeMatch.locality_match:type_name -> aggregation.LocalityMatch + 6, // 22: aggregation.MatchPredicate.RequestNodeMatch.node_metadata_match:type_name -> aggregation.NodeMetadataMatch + 7, // 23: aggregation.MatchPredicate.MatchSet.rules:type_name -> aggregation.MatchPredicate + 20, // 24: aggregation.ResultPredicate.ResultAction.regex_action:type_name -> aggregation.ResultPredicate.ResultAction.RegexAction + 14, // 25: aggregation.ResultPredicate.LocalityResultAction.region_action:type_name -> aggregation.ResultPredicate.ResultAction + 14, // 26: aggregation.ResultPredicate.LocalityResultAction.zone_action:type_name -> aggregation.ResultPredicate.ResultAction + 14, // 27: aggregation.ResultPredicate.LocalityResultAction.subzone_action:type_name -> aggregation.ResultPredicate.ResultAction + 4, // 28: aggregation.ResultPredicate.NodeMetadataAction.path:type_name -> aggregation.PathSegment + 14, // 29: aggregation.ResultPredicate.NodeMetadataAction.action:type_name -> aggregation.ResultPredicate.ResultAction + 8, // 30: aggregation.ResultPredicate.AndResult.result_predicates:type_name -> aggregation.ResultPredicate + 14, // 31: aggregation.ResultPredicate.RequestNodeFragment.id_action:type_name -> aggregation.ResultPredicate.ResultAction + 14, // 32: aggregation.ResultPredicate.RequestNodeFragment.cluster_action:type_name -> aggregation.ResultPredicate.ResultAction + 15, // 33: aggregation.ResultPredicate.RequestNodeFragment.locality_action:type_name -> aggregation.ResultPredicate.LocalityResultAction + 16, // 34: aggregation.ResultPredicate.RequestNodeFragment.node_metadata_action:type_name -> aggregation.ResultPredicate.NodeMetadataAction + 14, // 35: aggregation.ResultPredicate.ResourceNamesFragment.action:type_name -> aggregation.ResultPredicate.ResultAction + 36, // [36:36] is the sub-list for method output_type + 36, // [36:36] is the sub-list for method input_type + 36, // [36:36] is the sub-list for extension type_name + 36, // [36:36] is the sub-list for extension extendee + 0, // [0:36] is the sub-list for field type_name } func init() { file_aggregation_v1_aggregation_proto_init() } @@ -1487,7 +1870,7 @@ func file_aggregation_v1_aggregation_proto_init() { } } file_aggregation_v1_aggregation_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*LocalityMatch); i { + switch v := v.(*BoolMatch); i { case 0: return &v.state case 1: @@ -1499,7 +1882,7 @@ func file_aggregation_v1_aggregation_proto_init() { } } file_aggregation_v1_aggregation_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MatchPredicate); i { + switch v := v.(*LocalityMatch); i { case 0: return &v.state case 1: @@ -1511,7 +1894,7 @@ func file_aggregation_v1_aggregation_proto_init() { } } file_aggregation_v1_aggregation_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ResultPredicate); i { + switch v := v.(*PathSegment); i { case 0: return &v.state case 1: @@ -1523,7 +1906,7 @@ func file_aggregation_v1_aggregation_proto_init() { } } file_aggregation_v1_aggregation_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*KeyerConfiguration_Fragment); i { + switch v := v.(*StructValueMatch); i { case 0: return &v.state case 1: @@ -1535,7 +1918,7 @@ func file_aggregation_v1_aggregation_proto_init() { } } file_aggregation_v1_aggregation_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*KeyerConfiguration_Fragment_Rule); i { + switch v := v.(*NodeMetadataMatch); i { case 0: return &v.state case 1: @@ -1547,7 +1930,7 @@ func file_aggregation_v1_aggregation_proto_init() { } } file_aggregation_v1_aggregation_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MatchPredicate_RequestTypeMatch); i { + switch v := v.(*MatchPredicate); i { case 0: return &v.state case 1: @@ -1559,7 +1942,7 @@ func file_aggregation_v1_aggregation_proto_init() { } } file_aggregation_v1_aggregation_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MatchPredicate_RequestNodeMatch); i { + switch v := v.(*ResultPredicate); i { case 0: return &v.state case 1: @@ -1571,7 +1954,7 @@ func file_aggregation_v1_aggregation_proto_init() { } } file_aggregation_v1_aggregation_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*MatchPredicate_MatchSet); i { + switch v := v.(*KeyerConfiguration_Fragment); i { case 0: return &v.state case 1: @@ -1583,7 +1966,7 @@ func file_aggregation_v1_aggregation_proto_init() { } } file_aggregation_v1_aggregation_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ResultPredicate_ResultAction); i { + switch v := v.(*KeyerConfiguration_Fragment_Rule); i { case 0: return &v.state case 1: @@ -1595,7 +1978,7 @@ func file_aggregation_v1_aggregation_proto_init() { } } file_aggregation_v1_aggregation_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ResultPredicate_LocalityResultAction); i { + switch v := v.(*MatchPredicate_RequestTypeMatch); i { case 0: return &v.state case 1: @@ -1607,7 +1990,7 @@ func file_aggregation_v1_aggregation_proto_init() { } } file_aggregation_v1_aggregation_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ResultPredicate_AndResult); i { + switch v := v.(*MatchPredicate_RequestNodeMatch); i { case 0: return &v.state case 1: @@ -1619,7 +2002,7 @@ func file_aggregation_v1_aggregation_proto_init() { } } file_aggregation_v1_aggregation_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ResultPredicate_RequestNodeFragment); i { + switch v := v.(*MatchPredicate_MatchSet); i { case 0: return &v.state case 1: @@ -1631,7 +2014,7 @@ func file_aggregation_v1_aggregation_proto_init() { } } file_aggregation_v1_aggregation_proto_msgTypes[14].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ResultPredicate_ResourceNamesFragment); i { + switch v := v.(*ResultPredicate_ResultAction); i { case 0: return &v.state case 1: @@ -1643,6 +2026,66 @@ func file_aggregation_v1_aggregation_proto_init() { } } file_aggregation_v1_aggregation_proto_msgTypes[15].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ResultPredicate_LocalityResultAction); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_aggregation_v1_aggregation_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ResultPredicate_NodeMetadataAction); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_aggregation_v1_aggregation_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ResultPredicate_AndResult); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_aggregation_v1_aggregation_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ResultPredicate_RequestNodeFragment); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_aggregation_v1_aggregation_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*ResultPredicate_ResourceNamesFragment); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_aggregation_v1_aggregation_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*ResultPredicate_ResultAction_RegexAction); i { case 0: return &v.state @@ -1659,7 +2102,11 @@ func file_aggregation_v1_aggregation_proto_init() { (*StringMatch_ExactMatch)(nil), (*StringMatch_RegexMatch)(nil), } - file_aggregation_v1_aggregation_proto_msgTypes[3].OneofWrappers = []interface{}{ + file_aggregation_v1_aggregation_proto_msgTypes[5].OneofWrappers = []interface{}{ + (*StructValueMatch_StringMatch)(nil), + (*StructValueMatch_BoolMatch)(nil), + } + file_aggregation_v1_aggregation_proto_msgTypes[7].OneofWrappers = []interface{}{ (*MatchPredicate_AndMatch)(nil), (*MatchPredicate_OrMatch)(nil), (*MatchPredicate_NotMatch)(nil), @@ -1667,25 +2114,27 @@ func file_aggregation_v1_aggregation_proto_init() { (*MatchPredicate_RequestTypeMatch_)(nil), (*MatchPredicate_RequestNodeMatch_)(nil), } - file_aggregation_v1_aggregation_proto_msgTypes[4].OneofWrappers = []interface{}{ + file_aggregation_v1_aggregation_proto_msgTypes[8].OneofWrappers = []interface{}{ (*ResultPredicate_AndResult_)(nil), (*ResultPredicate_RequestNodeFragment_)(nil), (*ResultPredicate_ResourceNamesFragment_)(nil), (*ResultPredicate_StringFragment)(nil), } - file_aggregation_v1_aggregation_proto_msgTypes[8].OneofWrappers = []interface{}{ + file_aggregation_v1_aggregation_proto_msgTypes[12].OneofWrappers = []interface{}{ (*MatchPredicate_RequestNodeMatch_IdMatch)(nil), (*MatchPredicate_RequestNodeMatch_ClusterMatch)(nil), (*MatchPredicate_RequestNodeMatch_LocalityMatch)(nil), + (*MatchPredicate_RequestNodeMatch_NodeMetadataMatch)(nil), } - file_aggregation_v1_aggregation_proto_msgTypes[10].OneofWrappers = []interface{}{ + file_aggregation_v1_aggregation_proto_msgTypes[14].OneofWrappers = []interface{}{ (*ResultPredicate_ResultAction_Exact)(nil), (*ResultPredicate_ResultAction_RegexAction_)(nil), } - file_aggregation_v1_aggregation_proto_msgTypes[13].OneofWrappers = []interface{}{ + file_aggregation_v1_aggregation_proto_msgTypes[18].OneofWrappers = []interface{}{ (*ResultPredicate_RequestNodeFragment_IdAction)(nil), (*ResultPredicate_RequestNodeFragment_ClusterAction)(nil), (*ResultPredicate_RequestNodeFragment_LocalityAction)(nil), + (*ResultPredicate_RequestNodeFragment_NodeMetadataAction)(nil), } type x struct{} out := protoimpl.TypeBuilder{ @@ -1693,7 +2142,7 @@ func file_aggregation_v1_aggregation_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_aggregation_v1_aggregation_proto_rawDesc, NumEnums: 0, - NumMessages: 16, + NumMessages: 21, NumExtensions: 0, NumServices: 0, }, diff --git a/pkg/api/aggregation/v1/aggregation.pb.validate.go b/pkg/api/aggregation/v1/aggregation.pb.validate.go index 61538a3c..6e98a6cc 100644 --- a/pkg/api/aggregation/v1/aggregation.pb.validate.go +++ b/pkg/api/aggregation/v1/aggregation.pb.validate.go @@ -206,6 +206,72 @@ var _ interface { ErrorName() string } = StringMatchValidationError{} +// Validate checks the field values on BoolMatch with the rules defined in the +// proto definition for this message. If any rules are violated, an error is returned. +func (m *BoolMatch) Validate() error { + if m == nil { + return nil + } + + // no validation rules for ValueMatch + + return nil +} + +// BoolMatchValidationError is the validation error returned by +// BoolMatch.Validate if the designated constraints aren't met. +type BoolMatchValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e BoolMatchValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e BoolMatchValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e BoolMatchValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e BoolMatchValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e BoolMatchValidationError) ErrorName() string { return "BoolMatchValidationError" } + +// Error satisfies the builtin error interface +func (e BoolMatchValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sBoolMatch.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = BoolMatchValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = BoolMatchValidationError{} + // Validate checks the field values on LocalityMatch with the rules defined in // the proto definition for this message. If any rules are violated, an error // is returned. @@ -301,6 +367,283 @@ var _ interface { ErrorName() string } = LocalityMatchValidationError{} +// Validate checks the field values on PathSegment with the rules defined in +// the proto definition for this message. If any rules are violated, an error +// is returned. +func (m *PathSegment) Validate() error { + if m == nil { + return nil + } + + if utf8.RuneCountInString(m.GetKey()) < 1 { + return PathSegmentValidationError{ + field: "Key", + reason: "value length must be at least 1 runes", + } + } + + return nil +} + +// PathSegmentValidationError is the validation error returned by +// PathSegment.Validate if the designated constraints aren't met. +type PathSegmentValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e PathSegmentValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e PathSegmentValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e PathSegmentValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e PathSegmentValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e PathSegmentValidationError) ErrorName() string { return "PathSegmentValidationError" } + +// Error satisfies the builtin error interface +func (e PathSegmentValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sPathSegment.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = PathSegmentValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = PathSegmentValidationError{} + +// Validate checks the field values on StructValueMatch with the rules defined +// in the proto definition for this message. If any rules are violated, an +// error is returned. +func (m *StructValueMatch) Validate() error { + if m == nil { + return nil + } + + switch m.Match.(type) { + + case *StructValueMatch_StringMatch: + + if v, ok := interface{}(m.GetStringMatch()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return StructValueMatchValidationError{ + field: "StringMatch", + reason: "embedded message failed validation", + cause: err, + } + } + } + + case *StructValueMatch_BoolMatch: + + if v, ok := interface{}(m.GetBoolMatch()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return StructValueMatchValidationError{ + field: "BoolMatch", + reason: "embedded message failed validation", + cause: err, + } + } + } + + default: + return StructValueMatchValidationError{ + field: "Match", + reason: "value is required", + } + + } + + return nil +} + +// StructValueMatchValidationError is the validation error returned by +// StructValueMatch.Validate if the designated constraints aren't met. +type StructValueMatchValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e StructValueMatchValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e StructValueMatchValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e StructValueMatchValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e StructValueMatchValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e StructValueMatchValidationError) ErrorName() string { return "StructValueMatchValidationError" } + +// Error satisfies the builtin error interface +func (e StructValueMatchValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sStructValueMatch.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = StructValueMatchValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = StructValueMatchValidationError{} + +// Validate checks the field values on NodeMetadataMatch with the rules defined +// in the proto definition for this message. If any rules are violated, an +// error is returned. +func (m *NodeMetadataMatch) Validate() error { + if m == nil { + return nil + } + + if len(m.GetPath()) < 1 { + return NodeMetadataMatchValidationError{ + field: "Path", + reason: "value must contain at least 1 item(s)", + } + } + + for idx, item := range m.GetPath() { + _, _ = idx, item + + if v, ok := interface{}(item).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return NodeMetadataMatchValidationError{ + field: fmt.Sprintf("Path[%v]", idx), + reason: "embedded message failed validation", + cause: err, + } + } + } + + } + + if m.GetMatch() == nil { + return NodeMetadataMatchValidationError{ + field: "Match", + reason: "value is required", + } + } + + if v, ok := interface{}(m.GetMatch()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return NodeMetadataMatchValidationError{ + field: "Match", + reason: "embedded message failed validation", + cause: err, + } + } + } + + return nil +} + +// NodeMetadataMatchValidationError is the validation error returned by +// NodeMetadataMatch.Validate if the designated constraints aren't met. +type NodeMetadataMatchValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e NodeMetadataMatchValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e NodeMetadataMatchValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e NodeMetadataMatchValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e NodeMetadataMatchValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e NodeMetadataMatchValidationError) ErrorName() string { + return "NodeMetadataMatchValidationError" +} + +// Error satisfies the builtin error interface +func (e NodeMetadataMatchValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sNodeMetadataMatch.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = NodeMetadataMatchValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = NodeMetadataMatchValidationError{} + // Validate checks the field values on MatchPredicate with the rules defined in // the proto definition for this message. If any rules are violated, an error // is returned. @@ -872,6 +1215,18 @@ func (m *MatchPredicate_RequestNodeMatch) Validate() error { } } + case *MatchPredicate_RequestNodeMatch_NodeMetadataMatch: + + if v, ok := interface{}(m.GetNodeMetadataMatch()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return MatchPredicate_RequestNodeMatchValidationError{ + field: "NodeMetadataMatch", + reason: "embedded message failed validation", + cause: err, + } + } + } + default: return MatchPredicate_RequestNodeMatchValidationError{ field: "Type", @@ -1226,6 +1581,113 @@ var _ interface { ErrorName() string } = ResultPredicate_LocalityResultActionValidationError{} +// Validate checks the field values on ResultPredicate_NodeMetadataAction with +// the rules defined in the proto definition for this message. If any rules +// are violated, an error is returned. +func (m *ResultPredicate_NodeMetadataAction) Validate() error { + if m == nil { + return nil + } + + if len(m.GetPath()) < 1 { + return ResultPredicate_NodeMetadataActionValidationError{ + field: "Path", + reason: "value must contain at least 1 item(s)", + } + } + + for idx, item := range m.GetPath() { + _, _ = idx, item + + if v, ok := interface{}(item).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return ResultPredicate_NodeMetadataActionValidationError{ + field: fmt.Sprintf("Path[%v]", idx), + reason: "embedded message failed validation", + cause: err, + } + } + } + + } + + if m.GetAction() == nil { + return ResultPredicate_NodeMetadataActionValidationError{ + field: "Action", + reason: "value is required", + } + } + + if v, ok := interface{}(m.GetAction()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return ResultPredicate_NodeMetadataActionValidationError{ + field: "Action", + reason: "embedded message failed validation", + cause: err, + } + } + } + + return nil +} + +// ResultPredicate_NodeMetadataActionValidationError is the validation error +// returned by ResultPredicate_NodeMetadataAction.Validate if the designated +// constraints aren't met. +type ResultPredicate_NodeMetadataActionValidationError struct { + field string + reason string + cause error + key bool +} + +// Field function returns field value. +func (e ResultPredicate_NodeMetadataActionValidationError) Field() string { return e.field } + +// Reason function returns reason value. +func (e ResultPredicate_NodeMetadataActionValidationError) Reason() string { return e.reason } + +// Cause function returns cause value. +func (e ResultPredicate_NodeMetadataActionValidationError) Cause() error { return e.cause } + +// Key function returns key value. +func (e ResultPredicate_NodeMetadataActionValidationError) Key() bool { return e.key } + +// ErrorName returns error name. +func (e ResultPredicate_NodeMetadataActionValidationError) ErrorName() string { + return "ResultPredicate_NodeMetadataActionValidationError" +} + +// Error satisfies the builtin error interface +func (e ResultPredicate_NodeMetadataActionValidationError) Error() string { + cause := "" + if e.cause != nil { + cause = fmt.Sprintf(" | caused by: %v", e.cause) + } + + key := "" + if e.key { + key = "key for " + } + + return fmt.Sprintf( + "invalid %sResultPredicate_NodeMetadataAction.%s: %s%s", + key, + e.field, + e.reason, + cause) +} + +var _ error = ResultPredicate_NodeMetadataActionValidationError{} + +var _ interface { + Field() string + Reason() string + Key() bool + Cause() error + ErrorName() string +} = ResultPredicate_NodeMetadataActionValidationError{} + // Validate checks the field values on ResultPredicate_AndResult with the rules // defined in the proto definition for this message. If any rules are // violated, an error is returned. @@ -1361,6 +1823,18 @@ func (m *ResultPredicate_RequestNodeFragment) Validate() error { } } + case *ResultPredicate_RequestNodeFragment_NodeMetadataAction: + + if v, ok := interface{}(m.GetNodeMetadataAction()).(interface{ Validate() error }); ok { + if err := v.Validate(); err != nil { + return ResultPredicate_RequestNodeFragmentValidationError{ + field: "NodeMetadataAction", + reason: "embedded message failed validation", + cause: err, + } + } + } + default: return ResultPredicate_RequestNodeFragmentValidationError{ field: "Action",