use of org.batfish.common.BatfishException in project batfish by batfish.
the class Batfish method report.
private AnswerElement report() {
ReportAnswerElement answerElement = new ReportAnswerElement();
checkQuestionsDirExists();
Path questionsDir = _settings.getActiveTestrigSettings().getBasePath().resolve(BfConsts.RELPATH_QUESTIONS_DIR);
ConcurrentMap<Path, String> answers = new ConcurrentHashMap<>();
try (DirectoryStream<Path> questions = Files.newDirectoryStream(questionsDir)) {
questions.forEach(questionDirPath -> answers.put(questionDirPath.resolve(BfConsts.RELPATH_ANSWER_JSON), !questionDirPath.getFileName().startsWith(".") && Files.exists(questionDirPath.resolve(BfConsts.RELPATH_ANSWER_JSON)) ? CommonUtil.readFile(questionDirPath.resolve(BfConsts.RELPATH_ANSWER_JSON)) : ""));
} catch (IOException e1) {
throw new BatfishException("Could not create directory stream for '" + questionsDir + "'", e1);
}
ObjectMapper mapper = BatfishObjectMapper.mapper();
for (Entry<Path, String> entry : answers.entrySet()) {
Path answerPath = entry.getKey();
String answerText = entry.getValue();
if (!answerText.equals("")) {
try {
answerElement.getJsonAnswers().add(mapper.readTree(answerText));
} catch (IOException e) {
throw new BatfishException("Error mapping JSON content of '" + answerPath + "' to object", e);
}
}
}
return answerElement;
}
use of org.batfish.common.BatfishException in project batfish by batfish.
the class Batfish method answerAclReachability.
@Override
public AnswerElement answerAclReachability(String aclNameRegexStr, NamedStructureEquivalenceSets<?> aclEqSets) {
AclLinesAnswerElement answerElement = new AclLinesAnswerElement();
Pattern aclNameRegex;
try {
aclNameRegex = Pattern.compile(aclNameRegexStr);
} catch (PatternSyntaxException e) {
throw new BatfishException("Supplied regex for nodes is not a valid java regex: \"" + aclNameRegexStr + "\"", e);
}
Map<String, Configuration> configurations = loadConfigurations();
List<NodSatJob<AclLine>> jobs = new ArrayList<>();
for (Entry<String, ?> e : aclEqSets.getSameNamedStructures().entrySet()) {
String aclName = e.getKey();
if (!aclNameRegex.matcher(aclName).matches()) {
continue;
}
// operator error
if (aclName.contains("~ZONE_INTERFACE_FILTER~") || aclName.contains("~INBOUND_ZONE_FILTER~")) {
continue;
}
Set<?> s = (Set<?>) e.getValue();
for (Object o : s) {
NamedStructureEquivalenceSet<?> aclEqSet = (NamedStructureEquivalenceSet<?>) o;
String hostname = aclEqSet.getRepresentativeElement();
SortedSet<String> eqClassNodes = aclEqSet.getNodes();
answerElement.addEquivalenceClass(aclName, hostname, eqClassNodes);
Configuration c = configurations.get(hostname);
IpAccessList acl = c.getIpAccessLists().get(aclName);
int numLines = acl.getLines().size();
if (numLines == 0) {
_logger.redflag("RED_FLAG: Acl \"" + hostname + ":" + aclName + "\" contains no lines\n");
continue;
}
AclReachabilityQuerySynthesizer query = new AclReachabilityQuerySynthesizer(hostname, aclName, numLines);
Synthesizer aclSynthesizer = synthesizeAcls(Collections.singletonMap(hostname, c));
NodSatJob<AclLine> job = new NodSatJob<>(_settings, aclSynthesizer, query);
jobs.add(job);
}
}
Map<AclLine, Boolean> output = new TreeMap<>();
computeNodSatOutput(jobs, output);
// rearrange output for next step
Map<String, Map<String, List<AclLine>>> arrangedAclLines = new TreeMap<>();
for (Entry<AclLine, Boolean> e : output.entrySet()) {
AclLine line = e.getKey();
String hostname = line.getHostname();
Map<String, List<AclLine>> byAclName = arrangedAclLines.computeIfAbsent(hostname, k -> new TreeMap<>());
String aclName = line.getAclName();
List<AclLine> aclLines = byAclName.computeIfAbsent(aclName, k -> new ArrayList<>());
aclLines.add(line);
}
// now get earliest more general lines
List<NodFirstUnsatJob<AclLine, Integer>> step2Jobs = new ArrayList<>();
for (Entry<String, Map<String, List<AclLine>>> e : arrangedAclLines.entrySet()) {
String hostname = e.getKey();
Configuration c = configurations.get(hostname);
Synthesizer aclSynthesizer = synthesizeAcls(Collections.singletonMap(hostname, c));
Map<String, List<AclLine>> byAclName = e.getValue();
for (Entry<String, List<AclLine>> e2 : byAclName.entrySet()) {
String aclName = e2.getKey();
IpAccessList ipAccessList = c.getIpAccessLists().get(aclName);
List<AclLine> lines = e2.getValue();
for (int i = 0; i < lines.size(); i++) {
AclLine line = lines.get(i);
boolean reachable = output.get(line);
if (!reachable) {
List<AclLine> toCheck = new ArrayList<>();
for (int j = 0; j < i; j++) {
AclLine earlierLine = lines.get(j);
boolean earlierIsReachable = output.get(earlierLine);
if (earlierIsReachable) {
toCheck.add(earlierLine);
}
}
EarliestMoreGeneralReachableLineQuerySynthesizer query = new EarliestMoreGeneralReachableLineQuerySynthesizer(line, toCheck, ipAccessList);
NodFirstUnsatJob<AclLine, Integer> job = new NodFirstUnsatJob<>(_settings, aclSynthesizer, query);
step2Jobs.add(job);
}
}
}
}
Map<AclLine, Integer> step2Output = new TreeMap<>();
computeNodFirstUnsatOutput(step2Jobs, step2Output);
for (AclLine line : output.keySet()) {
Integer earliestMoreGeneralReachableLine = step2Output.get(line);
line.setEarliestMoreGeneralReachableLine(earliestMoreGeneralReachableLine);
}
Set<Pair<String, String>> aclsWithUnreachableLines = new TreeSet<>();
Set<Pair<String, String>> allAcls = new TreeSet<>();
int numUnreachableLines = 0;
int numLines = output.entrySet().size();
for (Entry<AclLine, Boolean> e : output.entrySet()) {
AclLine aclLine = e.getKey();
boolean sat = e.getValue();
String hostname = aclLine.getHostname();
String aclName = aclLine.getAclName();
Pair<String, String> qualifiedAclName = new Pair<>(hostname, aclName);
allAcls.add(qualifiedAclName);
if (!sat) {
numUnreachableLines++;
aclsWithUnreachableLines.add(qualifiedAclName);
}
}
for (Entry<AclLine, Boolean> e : output.entrySet()) {
AclLine aclLine = e.getKey();
int index = aclLine.getLine();
boolean sat = e.getValue();
String hostname = aclLine.getHostname();
String aclName = aclLine.getAclName();
Pair<String, String> qualifiedAclName = new Pair<>(hostname, aclName);
IpAccessList ipAccessList = configurations.get(hostname).getIpAccessLists().get(aclName);
IpAccessListLine ipAccessListLine = ipAccessList.getLines().get(index);
AclReachabilityEntry line = new AclReachabilityEntry(index, ipAccessListLine.getName());
if (aclsWithUnreachableLines.contains(qualifiedAclName)) {
if (sat) {
_logger.debugf("%s:%s:%d:'%s' is REACHABLE\n", hostname, aclName, line.getIndex(), line.getName());
answerElement.addReachableLine(hostname, ipAccessList, line);
} else {
_logger.debugf("%s:%s:%d:'%s' is UNREACHABLE\n\t%s\n", hostname, aclName, line.getIndex(), line.getName(), ipAccessListLine.toString());
Integer earliestMoreGeneralLineIndex = aclLine.getEarliestMoreGeneralReachableLine();
if (earliestMoreGeneralLineIndex != null) {
IpAccessListLine earliestMoreGeneralLine = ipAccessList.getLines().get(earliestMoreGeneralLineIndex);
line.setEarliestMoreGeneralLineIndex(earliestMoreGeneralLineIndex);
line.setEarliestMoreGeneralLineName(earliestMoreGeneralLine.getName());
if (!earliestMoreGeneralLine.getAction().equals(ipAccessListLine.getAction())) {
line.setDifferentAction(true);
}
}
answerElement.addUnreachableLine(hostname, ipAccessList, line);
aclsWithUnreachableLines.add(qualifiedAclName);
}
} else {
answerElement.addReachableLine(hostname, ipAccessList, line);
}
}
for (Pair<String, String> qualfiedAcl : aclsWithUnreachableLines) {
String hostname = qualfiedAcl.getFirst();
String aclName = qualfiedAcl.getSecond();
_logger.debugf("%s:%s has at least 1 unreachable line\n", hostname, aclName);
}
int numAclsWithUnreachableLines = aclsWithUnreachableLines.size();
int numAcls = allAcls.size();
double percentUnreachableAcls = 100d * numAclsWithUnreachableLines / numAcls;
double percentUnreachableLines = 100d * numUnreachableLines / numLines;
_logger.debugf("SUMMARY:\n");
_logger.debugf("\t%d/%d (%.1f%%) acls have unreachable lines\n", numAclsWithUnreachableLines, numAcls, percentUnreachableAcls);
_logger.debugf("\t%d/%d (%.1f%%) acl lines are unreachable\n", numUnreachableLines, numLines, percentUnreachableLines);
return answerElement;
}
use of org.batfish.common.BatfishException in project batfish by batfish.
the class Batfish method deserializeEnvironmentRoutingTables.
private SortedMap<String, RoutesByVrf> deserializeEnvironmentRoutingTables(Path serializeEnvironmentRoutingTablesPath) {
_logger.info("\n*** DESERIALIZING ENVIRONMENT ROUTING TABLES ***\n");
_logger.resetTimer();
Map<Path, String> namesByPath = new TreeMap<>();
try (DirectoryStream<Path> serializedRoutingTables = Files.newDirectoryStream(serializeEnvironmentRoutingTablesPath)) {
for (Path serializedRoutingTable : serializedRoutingTables) {
String name = serializedRoutingTable.getFileName().toString();
namesByPath.put(serializedRoutingTable, name);
}
} catch (IOException e) {
throw new BatfishException("Error reading serialized routing tables directory", e);
}
SortedMap<String, RoutesByVrf> routingTables = deserializeObjects(namesByPath, RoutesByVrf.class);
_logger.printElapsedTime();
return routingTables;
}
use of org.batfish.common.BatfishException in project batfish by batfish.
the class Batfish method serializeEnvironmentRoutingTables.
private void serializeEnvironmentRoutingTables(SortedMap<String, RoutesByVrf> routingTables, Path outputPath) {
if (routingTables == null) {
throw new BatfishException("Exiting due to parsing error(s)");
}
_logger.info("\n*** SERIALIZING ENVIRONMENT ROUTING TABLES ***\n");
_logger.resetTimer();
outputPath.toFile().mkdirs();
SortedMap<Path, RoutesByVrf> output = new TreeMap<>();
routingTables.forEach((name, rt) -> {
Path currentOutputPath = outputPath.resolve(name);
output.put(currentOutputPath, rt);
});
serializeObjects(output);
_logger.printElapsedTime();
}
use of org.batfish.common.BatfishException in project batfish by batfish.
the class Batfish method checkTopology.
static void checkTopology(Map<String, Configuration> configurations, Topology topology) {
for (Edge edge : topology.getEdges()) {
if (!configurations.containsKey(edge.getNode1())) {
throw new BatfishException(String.format("Topology contains a non-existent node '%s'", edge.getNode1()));
}
if (!configurations.containsKey(edge.getNode2())) {
throw new BatfishException(String.format("Topology contains a non-existent node '%s'", edge.getNode2()));
}
// nodes are valid, now checking corresponding interfaces
Configuration config1 = configurations.get(edge.getNode1());
Configuration config2 = configurations.get(edge.getNode2());
if (!config1.getInterfaces().containsKey(edge.getInt1())) {
throw new BatfishException(String.format("Topology contains a non-existent interface '%s' on node '%s'", edge.getInt1(), edge.getNode1()));
}
if (!config2.getInterfaces().containsKey(edge.getInt2())) {
throw new BatfishException(String.format("Topology contains a non-existent interface '%s' on node '%s'", edge.getInt2(), edge.getNode2()));
}
}
}
Aggregations