From 70181db91e8fc565660aefd7542bd9596b956e98 Mon Sep 17 00:00:00 2001 From: Eduardo Apolinario Date: Thu, 19 Nov 2020 12:13:05 -0800 Subject: [PATCH] Node metadata matcher (#154) This PR adds a matcher for node metadata fields. This is for #125. Similarly to #137, we encode the node metadata information required in the aggregation rules in a pair of protos: (1) NodeMetadataMatch, and (2) NodeMetadataAction, the former related to the matching process, whereas the latter has to do with the formation of the fragment. Envoy's node metadata is an opaque struct of type google.protobuf.Struct, which basically represents a dictionary of strings to Value. This PR adds support for 3 of the 6 values: string, bool, and a nested struct of Value. The support for these other types is going to be added in separate PRs. --- api/protos/aggregation/v1/aggregation.proto | 49 +- internal/app/mapper/mapper.go | 69 ++ internal/app/mapper/mapper_test.go | 315 ++++++- pkg/api/aggregation/v1/aggregation.pb.go | 867 +++++++++++++----- .../aggregation/v1/aggregation.pb.validate.go | 474 ++++++++++ 5 files changed, 1536 insertions(+), 238 deletions(-) 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",