use of org.batfish.vendor.VendorConfiguration in project batfish by batfish.
the class Batfish method serializeNetworkConfigs.
private void serializeNetworkConfigs(Path testRigPath, Path outputPath, ParseVendorConfigurationAnswerElement answerElement, SortedMap<String, VendorConfiguration> overlayHostConfigurations) {
Map<Path, String> configurationData = readConfigurationFiles(testRigPath, BfConsts.RELPATH_CONFIGURATIONS_DIR);
Map<String, VendorConfiguration> vendorConfigurations;
try (ActiveSpan parseNetworkConfigsSpan = GlobalTracer.get().buildSpan("Parse network configs").startActive()) {
// avoid unused warning
assert parseNetworkConfigsSpan != null;
vendorConfigurations = parseVendorConfigurations(configurationData, answerElement, ConfigurationFormat.UNKNOWN);
}
if (vendorConfigurations == null) {
throw new BatfishException("Exiting due to parser errors");
}
_logger.infof("Testrig:%s in container:%s has total number of network configs:%d", getTestrigName(), getContainerName(), vendorConfigurations.size());
_logger.info("\n*** SERIALIZING VENDOR CONFIGURATION STRUCTURES ***\n");
_logger.resetTimer();
CommonUtil.createDirectories(outputPath);
Map<Path, VendorConfiguration> output = new TreeMap<>();
vendorConfigurations.forEach((name, vc) -> {
if (name.contains(File.separator)) {
// iptables will get a hostname like configs/iptables-save if they
// are not set up correctly using host files
_logger.errorf("Cannot serialize configuration with hostname %s\n", name);
answerElement.addRedFlagWarning(name, new Warning("Cannot serialize network config. Bad hostname " + name.replace("\\", "/"), "MISCELLANEOUS"));
} else {
// apply overlay if it exists
VendorConfiguration overlayConfig = overlayHostConfigurations.get(name);
if (overlayConfig != null) {
vc.setOverlayConfiguration(overlayConfig);
overlayHostConfigurations.remove(name);
}
Path currentOutputPath = outputPath.resolve(name);
output.put(currentOutputPath, vc);
}
});
// warn about unused overlays
overlayHostConfigurations.forEach((name, overlay) -> {
answerElement.getParseStatus().put(name, ParseStatus.ORPHANED);
});
serializeObjects(output);
_logger.printElapsedTime();
}
use of org.batfish.vendor.VendorConfiguration in project batfish by batfish.
the class Batfish method readIptableFiles.
/**
* Read Iptable Files for each host in the keyset of {@code hostConfigurations}, and store the
* contents in {@code iptablesDate}. Each task fails if the Iptable file specified by host is not
* under {@code testRigPath} or does not exist.
*
* @throws BatfishException if there is a failed task and either {@link
* Settings#getExitOnFirstError()} or {@link Settings#getHaltOnParseError()} is set.
*/
void readIptableFiles(Path testRigPath, SortedMap<String, VendorConfiguration> hostConfigurations, SortedMap<Path, String> iptablesData, ParseVendorConfigurationAnswerElement answerElement) {
List<BatfishException> failureCauses = new ArrayList<>();
for (VendorConfiguration vc : hostConfigurations.values()) {
HostConfiguration hostConfig = (HostConfiguration) vc;
if (hostConfig.getIptablesFile() != null) {
Path path = Paths.get(testRigPath.toString(), hostConfig.getIptablesFile());
// testrig
try {
if (!path.toFile().getCanonicalPath().contains(testRigPath.toFile().getCanonicalPath()) || !path.toFile().exists()) {
String failureMessage = String.format("Iptables file %s for host %s is not contained within the testrig", hostConfig.getIptablesFile(), hostConfig.getHostname());
BatfishException bfc;
if (answerElement.getErrors().containsKey(hostConfig.getHostname())) {
bfc = new BatfishException(failureMessage, answerElement.getErrors().get(hostConfig.getHostname()).getException());
answerElement.getErrors().put(hostConfig.getHostname(), bfc.getBatfishStackTrace());
} else {
bfc = new BatfishException(failureMessage);
if (_settings.getExitOnFirstError()) {
throw bfc;
} else {
failureCauses.add(bfc);
answerElement.getErrors().put(hostConfig.getHostname(), bfc.getBatfishStackTrace());
answerElement.getParseStatus().put(hostConfig.getHostname(), ParseStatus.FAILED);
}
}
} else {
String fileText = CommonUtil.readFile(path);
iptablesData.put(path, fileText);
}
} catch (IOException e) {
throw new BatfishException("Could not get canonical path", e);
}
}
}
if (_settings.getHaltOnParseError() && !failureCauses.isEmpty()) {
BatfishException e = new BatfishException("Fatal exception due to at least one Iptables file is" + " not contained within the testrig");
failureCauses.forEach(e::addSuppressed);
throw e;
}
}
use of org.batfish.vendor.VendorConfiguration in project batfish by batfish.
the class Batfish method parseVendorConfigurations.
private SortedMap<String, VendorConfiguration> parseVendorConfigurations(Map<Path, String> configurationData, ParseVendorConfigurationAnswerElement answerElement, ConfigurationFormat configurationFormat) {
_logger.info("\n*** PARSING VENDOR CONFIGURATION FILES ***\n");
_logger.resetTimer();
SortedMap<String, VendorConfiguration> vendorConfigurations = new TreeMap<>();
List<ParseVendorConfigurationJob> jobs = new ArrayList<>();
for (Entry<Path, String> vendorFile : configurationData.entrySet()) {
Path currentFile = vendorFile.getKey();
String fileText = vendorFile.getValue();
Warnings warnings = buildWarnings(_settings);
ParseVendorConfigurationJob job = new ParseVendorConfigurationJob(_settings, fileText, currentFile, warnings, configurationFormat);
jobs.add(job);
}
BatfishJobExecutor.runJobsInExecutor(_settings, _logger, jobs, vendorConfigurations, answerElement, _settings.getHaltOnParseError(), "Parse configurations");
_logger.printElapsedTime();
return vendorConfigurations;
}
use of org.batfish.vendor.VendorConfiguration in project batfish by batfish.
the class Batfish method serializeHostConfigs.
private SortedMap<String, VendorConfiguration> serializeHostConfigs(Path testRigPath, Path outputPath, ParseVendorConfigurationAnswerElement answerElement) {
SortedMap<Path, String> configurationData = readConfigurationFiles(testRigPath, BfConsts.RELPATH_HOST_CONFIGS_DIR);
// read the host files
SortedMap<String, VendorConfiguration> allHostConfigurations;
try (ActiveSpan parseHostConfigsSpan = GlobalTracer.get().buildSpan("Parse host configs").startActive()) {
// avoid unused warning
assert parseHostConfigsSpan != null;
allHostConfigurations = parseVendorConfigurations(configurationData, answerElement, ConfigurationFormat.HOST);
}
if (allHostConfigurations == null) {
throw new BatfishException("Exiting due to parser errors");
}
_logger.infof("Testrig:%s in container:%s has total number of host configs:%d", getTestrigName(), getContainerName(), allHostConfigurations.size());
// split into hostConfigurations and overlayConfigurations
SortedMap<String, VendorConfiguration> overlayConfigurations = allHostConfigurations.entrySet().stream().filter(e -> ((HostConfiguration) e.getValue()).getOverlay()).collect(toMap(Entry::getKey, Entry::getValue, (v1, v2) -> v1, TreeMap::new));
SortedMap<String, VendorConfiguration> nonOverlayHostConfigurations = allHostConfigurations.entrySet().stream().filter(e -> !((HostConfiguration) e.getValue()).getOverlay()).collect(toMap(Entry::getKey, Entry::getValue, (v1, v2) -> v1, TreeMap::new));
// read and associate iptables files for specified hosts
SortedMap<Path, String> iptablesData = new TreeMap<>();
readIptableFiles(testRigPath, allHostConfigurations, iptablesData, answerElement);
SortedMap<String, VendorConfiguration> iptablesConfigurations = parseVendorConfigurations(iptablesData, answerElement, ConfigurationFormat.IPTABLES);
for (VendorConfiguration vc : allHostConfigurations.values()) {
HostConfiguration hostConfig = (HostConfiguration) vc;
if (hostConfig.getIptablesFile() != null) {
Path path = Paths.get(testRigPath.toString(), hostConfig.getIptablesFile());
String relativePathStr = _testrigSettings.getBasePath().relativize(path).toString();
if (iptablesConfigurations.containsKey(relativePathStr)) {
hostConfig.setIptablesVendorConfig((IptablesVendorConfiguration) iptablesConfigurations.get(relativePathStr));
}
}
}
// now, serialize
_logger.info("\n*** SERIALIZING VENDOR CONFIGURATION STRUCTURES ***\n");
_logger.resetTimer();
CommonUtil.createDirectories(outputPath);
Map<Path, VendorConfiguration> output = new TreeMap<>();
nonOverlayHostConfigurations.forEach((name, vc) -> {
Path currentOutputPath = outputPath.resolve(name);
output.put(currentOutputPath, vc);
});
serializeObjects(output);
// serialize warnings
serializeObject(answerElement, _testrigSettings.getParseAnswerPath());
_logger.printElapsedTime();
return overlayConfigurations;
}
use of org.batfish.vendor.VendorConfiguration in project batfish by batfish.
the class ParseVendorConfigurationJob method call.
@SuppressWarnings("fallthrough")
@Override
public ParseVendorConfigurationResult call() throws Exception {
long startTime = System.currentTimeMillis();
long elapsedTime;
String currentPath = _file.toAbsolutePath().toString();
VendorConfiguration vc = null;
BatfishCombinedParser<?, ?> combinedParser = null;
ParserRuleContext tree = null;
ControlPlaneExtractor extractor = null;
ConfigurationFormat format = _format;
_logger.infof("Processing: '%s'\n", currentPath);
for (String s : _settings.ignoreFilesWithStrings()) {
if (_fileText.contains(s)) {
format = ConfigurationFormat.IGNORED;
break;
}
}
String relativePathStr = _settings.getActiveTestrigSettings().getBasePath().relativize(_file).toString();
if (format == ConfigurationFormat.UNKNOWN) {
format = VendorConfigurationFormatDetector.identifyConfigurationFormat(_fileText);
}
switch(format) {
case EMPTY:
_warnings.redFlag("Empty file: '" + currentPath + "'\n");
elapsedTime = System.currentTimeMillis() - startTime;
return new ParseVendorConfigurationResult(elapsedTime, _logger.getHistory(), _file, _warnings, ParseStatus.EMPTY);
case IGNORED:
_warnings.pedantic("Ignored file: '" + currentPath + "'\n");
elapsedTime = System.currentTimeMillis() - startTime;
return new ParseVendorConfigurationResult(elapsedTime, _logger.getHistory(), _file, _warnings, ParseStatus.IGNORED);
case ARISTA:
case CADANT:
case CISCO_ASA:
case CISCO_IOS:
case CISCO_IOS_XR:
case CISCO_NX:
case FORCE10:
case FOUNDRY:
String newFileText = _fileText;
String fileText;
_logger.info("\tPreprocessing...");
do {
fileText = newFileText;
try {
newFileText = preprocessBanner(fileText, format);
} catch (BatfishException e) {
elapsedTime = System.currentTimeMillis() - startTime;
return new ParseVendorConfigurationResult(elapsedTime, _logger.getHistory(), _file, new BatfishException("Error preprocessing banner", e));
}
} while (!newFileText.equals(fileText));
_logger.info("OK\n");
CiscoCombinedParser ciscoParser = new CiscoCombinedParser(newFileText, _settings, format);
combinedParser = ciscoParser;
extractor = new CiscoControlPlaneExtractor(newFileText, ciscoParser, format, _warnings, _settings.getUnrecognizedAsRedFlag());
break;
case HOST:
vc = HostConfiguration.fromJson(_fileText, _warnings);
elapsedTime = System.currentTimeMillis() - startTime;
return new ParseVendorConfigurationResult(elapsedTime, _logger.getHistory(), _file, vc, _warnings, _ptSentences);
case VYOS:
if (_settings.flattenOnTheFly()) {
String msg = "Flattening: '" + currentPath + "' on-the-fly; line-numbers reported for this file will be spurious\n";
_warnings.pedantic(msg);
// _logger
// .warn("Flattening: \""
// + currentPath
// +
// "\" on-the-fly; line-numbers reported for this file will be
// spurious\n");
_fileText = Batfish.flatten(_fileText, _logger, _settings, ConfigurationFormat.VYOS, VendorConfigurationFormatDetector.BATFISH_FLATTENED_VYOS_HEADER);
} else {
elapsedTime = System.currentTimeMillis() - startTime;
return new ParseVendorConfigurationResult(elapsedTime, _logger.getHistory(), _file, new BatfishException("Vyos configurations must be flattened prior to this stage: '" + relativePathStr + "'"));
}
// fall through
case FLAT_VYOS:
FlatVyosCombinedParser flatVyosParser = new FlatVyosCombinedParser(_fileText, _settings);
combinedParser = flatVyosParser;
extractor = new FlatVyosControlPlaneExtractor(_fileText, flatVyosParser, _warnings);
break;
case JUNIPER:
if (_settings.flattenOnTheFly()) {
String msg = "Flattening: '" + currentPath + "' on-the-fly; line-numbers reported for this file will be spurious\n";
_warnings.pedantic(msg);
// spurious\n");
try {
_fileText = Batfish.flatten(_fileText, _logger, _settings, ConfigurationFormat.JUNIPER, VendorConfigurationFormatDetector.BATFISH_FLATTENED_JUNIPER_HEADER);
} catch (BatfishException e) {
String error = "Error flattening configuration file: '" + currentPath + "'";
elapsedTime = System.currentTimeMillis() - startTime;
return new ParseVendorConfigurationResult(elapsedTime, _logger.getHistory(), _file, new BatfishException(error, e));
}
} else {
elapsedTime = System.currentTimeMillis() - startTime;
return new ParseVendorConfigurationResult(elapsedTime, _logger.getHistory(), _file, new BatfishException("Juniper configurations must be flattened prior to this stage: '" + relativePathStr + "'"));
}
// fall through
case FLAT_JUNIPER:
FlatJuniperCombinedParser flatJuniperParser = new FlatJuniperCombinedParser(_fileText, _settings);
combinedParser = flatJuniperParser;
extractor = new FlatJuniperControlPlaneExtractor(_fileText, flatJuniperParser, _warnings, _settings.getUnrecognizedAsRedFlag());
break;
case IPTABLES:
IptablesCombinedParser iptablesParser = new IptablesCombinedParser(_fileText, _settings);
combinedParser = iptablesParser;
extractor = new IptablesControlPlaneExtractor(_fileText, iptablesParser, _warnings, relativePathStr);
break;
case MRV:
MrvCombinedParser mrvParser = new MrvCombinedParser(_fileText, _settings);
combinedParser = mrvParser;
extractor = new MrvControlPlaneExtractor(_fileText, mrvParser, _warnings);
break;
case ALCATEL_AOS:
case AWS:
case BLADENETWORK:
case F5:
case JUNIPER_SWITCH:
case METAMAKO:
case MRV_COMMANDS:
case MSS:
case VXWORKS:
String unsupportedError = "Unsupported configuration format: '" + format + "' for file: '" + currentPath + "'\n";
if (!_settings.ignoreUnsupported()) {
elapsedTime = System.currentTimeMillis() - startTime;
return new ParseVendorConfigurationResult(elapsedTime, _logger.getHistory(), _file, new BatfishException(unsupportedError));
} else {
_warnings.unimplemented(unsupportedError);
elapsedTime = System.currentTimeMillis() - startTime;
return new ParseVendorConfigurationResult(elapsedTime, _logger.getHistory(), _file, _warnings, ParseStatus.UNSUPPORTED);
}
case UNKNOWN:
default:
String unknownError = "Unknown configuration format for file: '" + currentPath + "'\n";
if (!_settings.ignoreUnknown()) {
elapsedTime = System.currentTimeMillis() - startTime;
return new ParseVendorConfigurationResult(elapsedTime, _logger.getHistory(), _file, new BatfishException(unknownError));
} else {
_warnings.unimplemented(unknownError);
elapsedTime = System.currentTimeMillis() - startTime;
return new ParseVendorConfigurationResult(elapsedTime, _logger.getHistory(), _file, _warnings, ParseStatus.UNKNOWN);
}
}
try {
_logger.info("\tParsing...");
tree = Batfish.parse(combinedParser, _logger, _settings);
if (_settings.getPrintParseTree()) {
_ptSentences = ParseTreePrettyPrinter.getParseTreeSentences(tree, combinedParser);
}
_logger.info("\tPost-processing...");
extractor.processParseTree(tree);
if (!combinedParser.getErrors().isEmpty()) {
elapsedTime = System.currentTimeMillis() - startTime;
return new ParseVendorConfigurationResult(elapsedTime, _logger.getHistory(), _file, new BatfishException(String.format("Configuration file: '%s' contains unrecognized lines:\n%s", _file.getFileName().toString(), String.join("\n", combinedParser.getErrors()))));
}
_logger.info("OK\n");
} catch (ParserBatfishException e) {
String error = "Error parsing configuration file: '" + currentPath + "'";
elapsedTime = System.currentTimeMillis() - startTime;
return new ParseVendorConfigurationResult(elapsedTime, _logger.getHistory(), _file, new BatfishException(error, e));
} catch (Exception e) {
String error = "Error post-processing parse tree of configuration file: '" + currentPath + "'";
elapsedTime = System.currentTimeMillis() - startTime;
return new ParseVendorConfigurationResult(elapsedTime, _logger.getHistory(), _file, new BatfishException(error, e));
} finally {
Batfish.logWarnings(_logger, _warnings);
}
vc = extractor.getVendorConfiguration();
vc.setVendor(format);
vc.setFilename(_file.getFileName().toString());
// at this point we should have a VendorConfiguration vc
String hostname = vc.getHostname();
if (hostname == null) {
String error = "No hostname set in file: '" + relativePathStr.replace("\\", "/") + "'\n";
try {
_warnings.redFlag(error);
} catch (BatfishException e) {
elapsedTime = System.currentTimeMillis() - startTime;
return new ParseVendorConfigurationResult(elapsedTime, _logger.getHistory(), _file, e);
}
String filename = _file.getFileName().toString();
String guessedHostname = filename.replaceAll("\\.(cfg|conf)$", "");
_logger.redflag("\tNo hostname set! Guessing hostname from filename: '" + filename + "' ==> '" + guessedHostname + "'\n");
vc.setHostname(guessedHostname);
}
elapsedTime = System.currentTimeMillis() - startTime;
return new ParseVendorConfigurationResult(elapsedTime, _logger.getHistory(), _file, vc, _warnings, _ptSentences);
}
Aggregations