Skip to content

Commit 8dbd47c

Browse files
authored
Sort the policies in a rule by policy name when parsing from proto. (grpc#10334)
* Sort the policies in a rule by policy name when parsing from proto. This fixes the server sending a GOAWAY when an LDS update with no changes other than ordering is received. * Remove use of deprecated method setSourceIp * Fix style issues * Update RbacFilterTest.java
1 parent 68e2992 commit 8dbd47c

File tree

2 files changed

+78
-6
lines changed

2 files changed

+78
-6
lines changed

xds/src/main/java/io/grpc/xds/RbacFilter.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,10 @@
5959
import java.util.ArrayList;
6060
import java.util.List;
6161
import java.util.Map;
62+
import java.util.Map.Entry;
6263
import java.util.logging.Level;
6364
import java.util.logging.Logger;
65+
import java.util.stream.Collectors;
6466
import javax.annotation.Nullable;
6567

6668
/** RBAC Http filter implementation. */
@@ -117,9 +119,12 @@ static ConfigOrError<RbacConfig> parseRbacConfig(RBAC rbac) {
117119
default:
118120
return ConfigOrError.fromError("Unknown rbacConfig action type: " + rbacConfig.getAction());
119121
}
120-
Map<String, Policy> policyMap = rbacConfig.getPoliciesMap();
121122
List<GrpcAuthorizationEngine.PolicyMatcher> policyMatchers = new ArrayList<>();
122-
for (Map.Entry<String, Policy> entry: policyMap.entrySet()) {
123+
List<Entry<String, Policy>> sortedPolicyEntries = rbacConfig.getPoliciesMap().entrySet()
124+
.stream()
125+
.sorted((a,b) -> a.getKey().compareTo(b.getKey()))
126+
.collect(Collectors.toList());
127+
for (Map.Entry<String, Policy> entry: sortedPolicyEntries) {
123128
try {
124129
Policy policy = entry.getValue();
125130
if (policy.hasCondition() || policy.hasCheckedCondition()) {

xds/src/test/java/io/grpc/xds/RbacFilterTest.java

Lines changed: 71 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import static org.mockito.Mockito.when;
2727

2828
import com.google.api.expr.v1alpha1.Expr;
29+
import com.google.common.collect.ImmutableList;
2930
import com.google.protobuf.Any;
3031
import com.google.protobuf.Message;
3132
import com.google.protobuf.UInt32Value;
@@ -339,6 +340,22 @@ public void ignoredConfig() {
339340
assertThat(result.config).isEqualTo(RbacConfig.create(null));
340341
}
341342

343+
@Test
344+
public void testOrderIndependenceOfPolicies() {
345+
Message rawProto = buildComplexRbac(ImmutableList.of(1, 2, 3, 4, 5, 6), true);
346+
ConfigOrError<RbacConfig> ascFirst = new RbacFilter().parseFilterConfig(Any.pack(rawProto));
347+
348+
rawProto = buildComplexRbac(ImmutableList.of(1, 2, 3, 4, 5, 6), false);
349+
ConfigOrError<RbacConfig> ascLast = new RbacFilter().parseFilterConfig(Any.pack(rawProto));
350+
351+
assertThat(ascFirst.config).isEqualTo(ascLast.config);
352+
353+
rawProto = buildComplexRbac(ImmutableList.of(6, 5, 4, 3, 2, 1), true);
354+
ConfigOrError<RbacConfig> decFirst = new RbacFilter().parseFilterConfig(Any.pack(rawProto));
355+
356+
assertThat(ascFirst.config).isEqualTo(decFirst.config);
357+
}
358+
342359
private static Metadata metadata(String key, String value) {
343360
Metadata metadata = new Metadata();
344361
metadata.put(Metadata.Key.of(key, Metadata.ASCII_STRING_MARSHALLER), value);
@@ -369,11 +386,61 @@ private ConfigOrError<RbacConfig> parseRaw(List<Permission> permissionList,
369386
private io.envoyproxy.envoy.extensions.filters.http.rbac.v3.RBAC buildRbac(
370387
List<Permission> permissionList, List<Principal> principalList) {
371388
return io.envoyproxy.envoy.extensions.filters.http.rbac.v3.RBAC.newBuilder()
372-
.setRules(RBAC.newBuilder().setAction(Action.DENY)
373-
.putPolicies("policy-name", Policy.newBuilder()
374-
.addAllPermissions(permissionList)
375-
.addAllPrincipals(principalList).build()).build()).build();
389+
.setRules(buildRbacRule("policy-name", Action.DENY,
390+
permissionList, principalList)).build();
391+
}
392+
393+
private static RBAC buildRbacRule(String policyName, Action action,
394+
List<Permission> permissionList, List<Principal> principalList) {
395+
return RBAC.newBuilder().setAction(action)
396+
.putPolicies(policyName, Policy.newBuilder()
397+
.addAllPermissions(permissionList)
398+
.addAllPrincipals(principalList).build())
399+
.build();
400+
}
401+
402+
private io.envoyproxy.envoy.extensions.filters.http.rbac.v3.RBAC buildComplexRbac(
403+
List<Integer> ids, boolean listsFirst) {
404+
Policy policy1 = createSimplePolicyUsingLists(0);
405+
406+
RBAC.Builder ruleBuilder = RBAC.newBuilder().setAction(Action.DENY);
407+
408+
if (listsFirst) {
409+
ruleBuilder.putPolicies("list-policy", policy1);
410+
}
411+
412+
String base = "filterConfig\\u003dRbacConfig{authConfig\\u003dAuthConfig{policies\\u003d[Poli"
413+
+ "cyMatcher{name\\u003dpsm-interop-authz-policy-20230514-0917-er2uh_td_rbac_rule_";
414+
415+
for (Integer id : ids) {
416+
ruleBuilder.putPolicies(base + id, createSimplePolicyUsingLists(id));
417+
}
418+
419+
if (!listsFirst) {
420+
ruleBuilder.putPolicies("list-policy", policy1);
421+
}
422+
423+
return io.envoyproxy.envoy.extensions.filters.http.rbac.v3.RBAC.newBuilder()
424+
.setRules(ruleBuilder.build()).build();
425+
}
426+
427+
private static Policy createSimplePolicyUsingLists(int id) {
428+
CidrRange cidrRange = CidrRange.newBuilder().setAddressPrefix("10.10." + id + ".0")
429+
.setPrefixLen(UInt32Value.of(24)).build();
430+
List<Permission> permissionList = Arrays.asList(
431+
Permission.newBuilder().setAndRules(Permission.Set.newBuilder()
432+
.addRules(Permission.newBuilder().setDestinationIp(cidrRange).build())
433+
.addRules(Permission.newBuilder().setDestinationPort(9090).build()).build()
434+
).build());
435+
List<Principal> principalList = Arrays.asList(
436+
Principal.newBuilder().setAndIds(Principal.Set.newBuilder()
437+
.addIds(Principal.newBuilder().setDirectRemoteIp(cidrRange).build())
438+
.addIds(Principal.newBuilder().setRemoteIp(cidrRange).build())
439+
.build()).build());
376440

441+
return Policy.newBuilder()
442+
.addAllPermissions(permissionList)
443+
.addAllPrincipals(principalList).build();
377444
}
378445

379446
private ConfigOrError<RbacConfig> parseOverride(List<Permission> permissionList,

0 commit comments

Comments
 (0)