private Optional<IpAccessList> makeQueryAcl(IpAccessList originalAcl) { SearchFiltersQuestion question = (SearchFiltersQuestion) _question; switch (question.getType()) { case PERMIT: return Optional.of(originalAcl); case DENY: return Optional.of(toDenyAcl(originalAcl)); case MATCH_LINE: // for each ACL, construct a new ACL that accepts if and only if the specified line matches Integer lineNumber = question.getLineNumber(); checkState(lineNumber != null, "Cannot perform a match line query without a line number"); return originalAcl.getLines().size() > lineNumber ? Optional.of(toMatchLineAcl(lineNumber, originalAcl)) : Optional.empty(); default: throw new BatfishException("Unexpected query Type: " + question.getType()); } }
@Override protected Answerer createAnswerer(Question question, IBatfish batfish) { return new SearchFiltersAnswerer(question, batfish); }
@Override public AnswerElement answerDiff() { differentialAnswer((SearchFiltersQuestion) _question); return _tableAnswerElement; }
@VisibleForTesting List<Triple<String, String, IpAccessList>> getQueryAcls(SearchFiltersQuestion question) { Map<String, Configuration> configs = _batfish.loadConfigurations(); return getSpecifiedAcls(question).entries().stream() .map( entry -> { String hostName = entry.getKey(); String aclName = entry.getValue(); Optional<IpAccessList> queryAcl = makeQueryAcl(configs.get(hostName).getIpAccessLists().get(aclName)); return queryAcl.map(acl -> ImmutableTriple.of(hostName, aclName, acl)); }) .filter(Optional::isPresent) .map(Optional::get) .collect(ImmutableList.toImmutableList()); }
@Test public void testReachFilter_matchLine_blocked() { Optional<SearchFiltersResult> permitResult = _batfish.reachFilter(_config, toMatchLineAcl(2, BLOCKED_LINE_ACL), _allLocationsParams); assertThat("Should not find permitted flow", !permitResult.isPresent()); }
@Test public void testGetQueryAcls_deny() { SearchFiltersQuestion question = SearchFiltersQuestion.builder().setFilterSpecifier(ACL.getName()).setAction("deny").build(); SearchFiltersAnswerer answerer = new SearchFiltersAnswerer(question, _batfish); List<Triple<String, String, IpAccessList>> queryAcls = answerer.getQueryAcls(question); assertThat(queryAcls, hasSize(1)); String queryConfig = queryAcls.get(0).getLeft(); String queryAclName = queryAcls.get(0).getMiddle(); IpAccessList queryAcl = queryAcls.get(0).getRight(); assertThat(queryConfig, equalTo(_config.getHostname())); assertThat(queryAclName, equalTo(ACL.getName())); assertThat(queryAcl.getName(), equalTo(NEGATED_RENAMER.apply(ACL.getName()))); assertThat(queryAcl, is(DENY_ACL)); }
private void differentialAnswer(SearchFiltersQuestion question) { _batfish.pushBaseSnapshot(); Map<String, Configuration> baseConfigs = _batfish.loadConfigurations(); Multimap<String, String> baseAcls = getSpecifiedAcls(question); _batfish.popSnapshot(); Multimap<String, String> deltaAcls = getSpecifiedAcls(question); _batfish.popSnapshot(); toSearchFiltersTable( TestFiltersAnswerer.create(new TestFiltersQuestion(null, null, null, null)), question.getGenerateExplanations()); TableAnswerElement deltaTable = toSearchFiltersTable( TestFiltersAnswerer.create(new TestFiltersQuestion(null, null, null, null)), question.getGenerateExplanations()); Optional<IpAccessList> baseAcl = makeQueryAcl(baseConfig.getIpAccessLists().get(aclName)); Optional<IpAccessList> deltaAcl = makeQueryAcl(deltaConfig.getIpAccessLists().get(aclName)); if (!baseAcl.isPresent() && !deltaAcl.isPresent()) { continue; AclLineMatchExpr description = result.getHeaderSpaceDescription().orElse(null); baseTable.addRow( toSearchFiltersRow( description, testFiltersRow(true, node, aclName, flow), question.getGenerateExplanations())); deltaTable.addRow( toSearchFiltersRow(
@Test public void testReachFilter_deny_ACCEPT_ALL() { Optional<SearchFiltersResult> result = _batfish.reachFilter(_config, toDenyAcl(ACCEPT_ALL_ACL), _allLocationsParams); assertThat("Should not find permitted flow", !result.isPresent()); }
private void nonDifferentialAnswer(SearchFiltersQuestion question) { List<Triple<String, String, IpAccessList>> acls = getQueryAcls(question); if (acls.isEmpty()) { throw new BatfishException("No matching filters"); result -> rows.add( toSearchFiltersRow( result.getHeaderSpaceDescription().orElse(null), testFiltersRow(true, hostname, aclname, result.getExampleFlow()), question.getGenerateExplanations()))); toSearchFiltersTable( TestFiltersAnswerer.create(new TestFiltersQuestion(null, null, null, null)), question.getGenerateExplanations());
@Test public void testAnswer() { SearchFiltersQuestion question = new SearchFiltersQuestion(); SearchFiltersAnswerer answerer = new SearchFiltersAnswerer(question, _batfish); TableAnswerElement ae = (TableAnswerElement) answerer.answer(); assertThat( ae, hasRows( containsInAnyOrder( ImmutableList.of( allOf( hasColumn(COL_ACTION, equalTo("PERMIT"), Schema.STRING), hasColumn(COL_FILTER_NAME, equalTo(ACL.getName()), Schema.STRING)), allOf( hasColumn(COL_ACTION, equalTo("PERMIT"), Schema.STRING), hasColumn( COL_FILTER_NAME, equalTo(BLOCKED_LINE_ACL.getName()), Schema.STRING)), allOf( hasColumn(COL_ACTION, equalTo("PERMIT"), Schema.STRING), hasColumn(COL_FILTER_NAME, equalTo(SRC_ACL.getName()), Schema.STRING)))))); }
TableAnswerElement answer = (TableAnswerElement) new SearchFiltersAnswerer( SearchFiltersQuestion.builder().setStartLocation("enter(.*)").build(), batfish) .answerDiff(); assertThat( answer,
@Test public void testReachFilter_matchLine() { Optional<SearchFiltersResult> permitResult = _batfish.reachFilter(_config, toMatchLineAcl(0, ACL), _allLocationsParams); assertThat("Should find permitted flow", permitResult.isPresent()); assertThat(permitResult.get().getExampleFlow(), hasDstIp(IP0)); permitResult = _batfish.reachFilter(_config, toMatchLineAcl(1, ACL), _allLocationsParams); assertThat("Should find permitted flow", permitResult.isPresent()); assertThat(permitResult.get().getExampleFlow(), hasDstIp(IP1)); permitResult = _batfish.reachFilter(_config, toMatchLineAcl(2, ACL), _allLocationsParams); assertThat("Should find permitted flow", permitResult.isPresent()); assertThat(permitResult.get().getExampleFlow(), hasDstIp(IP2)); permitResult = _batfish.reachFilter(_config, toMatchLineAcl(3, ACL), _allLocationsParams); assertThat("Should find permitted flow", permitResult.isPresent()); assertThat(permitResult.get().getExampleFlow(), hasDstIp(IP3)); }
@Test public void testGetQueryAcls_permit() { SearchFiltersQuestion question = SearchFiltersQuestion.builder() .setFilterSpecifier(ACL.getName()) .setAction("permit") .build(); SearchFiltersAnswerer answerer = new SearchFiltersAnswerer(question, _batfish); List<Triple<String, String, IpAccessList>> queryAcls = answerer.getQueryAcls(question); assertThat(queryAcls, hasSize(1)); String queryConfig = queryAcls.get(0).getLeft(); String queryAclName = queryAcls.get(0).getMiddle(); IpAccessList queryAcl = queryAcls.get(0).getRight(); assertThat(queryConfig, equalTo(_config.getHostname())); assertThat(queryAclName, equalTo(ACL.getName())); assertThat(queryAcl, is(ACL)); }
@Test public void testReachFilter_deny_REJECT_ALL() { Optional<SearchFiltersResult> result = _batfish.reachFilter(_config, toDenyAcl(REJECT_ALL_ACL), _allLocationsParams); assertThat("Should find permitted flow", result.isPresent()); }
@Test public void testAnswerWithRenamingAndExplanations() { SearchFiltersQuestion question = SearchFiltersQuestion.builder().setGenerateExplanations(true).setAction("deny").build(); SearchFiltersAnswerer answerer = new SearchFiltersAnswerer(question, _batfish); TableAnswerElement ae = (TableAnswerElement) answerer.answer(); assertThat( ae, hasRows( containsInAnyOrder( ImmutableList.of( allOf( hasColumn(COL_ACTION, equalTo("DENY"), Schema.STRING), hasColumn(COL_FILTER_NAME, equalTo(ACL.getName()), Schema.STRING)), allOf( hasColumn(COL_ACTION, equalTo("DENY"), Schema.STRING), hasColumn( COL_FILTER_NAME, equalTo(BLOCKED_LINE_ACL.getName()), Schema.STRING)), allOf( hasColumn(COL_ACTION, equalTo("DENY"), Schema.STRING), hasColumn(COL_FILTER_NAME, equalTo(SRC_ACL.getName()), Schema.STRING)))))); }
TableAnswerElement answer = (TableAnswerElement) new SearchFiltersAnswerer( SearchFiltersQuestion.builder() .setStartLocation("enter(.*)") .build(), batfish) .answerDiff(); assertThat( answer,
@Test public void testMatchSrcInterface() { Optional<SearchFiltersResult> result = _batfish.reachFilter(_config, toMatchLineAcl(0, SRC_ACL), _allLocationsParams); assertThat( result.get().getExampleFlow(), allOf(hasIngressInterface(nullValue()), hasDstIp(IP0))); result = _batfish.reachFilter(_config, toMatchLineAcl(1, SRC_ACL), _allLocationsParams); assertThat(result.get().getExampleFlow(), allOf(hasIngressInterface(IFACE1), hasDstIp(IP1))); result = _batfish.reachFilter(_config, toMatchLineAcl(2, SRC_ACL), _allLocationsParams); assertThat(result.get().getExampleFlow(), allOf(hasIngressInterface(IFACE2), hasDstIp(IP2))); // cannot have two different source interfaces result = _batfish.reachFilter(_config, toMatchLineAcl(3, SRC_ACL), _allLocationsParams); assertThat(result, equalTo(Optional.empty())); // cannot have originate from device and have a source interface result = _batfish.reachFilter(_config, toMatchLineAcl(4, SRC_ACL), _allLocationsParams); assertThat(result, equalTo(Optional.empty())); }
@Test public void testGetQueryAcls_matchLine2() { SearchFiltersQuestion question = SearchFiltersQuestion.builder() .setFilterSpecifier(ACL.getName()) .setAction("matchLine 2") .build(); SearchFiltersAnswerer answerer = new SearchFiltersAnswerer(question, _batfish); List<Triple<String, String, IpAccessList>> queryAcls = answerer.getQueryAcls(question); assertThat(queryAcls, hasSize(1)); String queryConfig = queryAcls.get(0).getLeft(); String queryAclName = queryAcls.get(0).getMiddle(); IpAccessList queryAcl = queryAcls.get(0).getRight(); assertThat(queryConfig, equalTo(_config.getHostname())); assertThat(queryAclName, equalTo(ACL.getName())); assertThat(queryAcl.getName(), equalTo(MATCH_LINE_RENAMER.apply(2, ACL.getName()))); assertThat(queryAcl, is(MATCH_LINE2_ACL)); }
@Test public void testReachFilter_deny() { Optional<SearchFiltersResult> permitResult = _batfish.reachFilter(_config, toDenyAcl(ACL), _allLocationsParams); assertThat("Should find permitted flow", permitResult.isPresent()); assertThat(permitResult.get().getExampleFlow(), hasDstIp(not(oneOf(IP0, IP3)))); }
@Test public void testSourceInterfaceParameter() { SearchFiltersParameters params = _allLocationsParams .toBuilder() .setStartLocationSpecifier(new NameRegexInterfaceLinkLocationSpecifier(IFACE1)) .build(); // can match line 1 because IFACE1 is specified Optional<SearchFiltersResult> result = _batfish.reachFilter(_config, toMatchLineAcl(1, SRC_ACL), params); assertThat(result.get().getExampleFlow(), allOf(hasIngressInterface(IFACE1), hasDstIp(IP1))); // cannot match line 2 because IFACE2 is not specified result = _batfish.reachFilter(_config, toMatchLineAcl(2, SRC_ACL), params); assertThat("Should not find a result", !result.isPresent()); }