Commit 58f0922d authored by Michael Tremer's avatar Michael Tremer

export: Allow exporting to stdout

This is useful if you want to pipe output straight into another program.
Signed-off-by: default avatarMichael Tremer <michael.tremer@ipfire.org>
parent 69c87578
...@@ -39,7 +39,7 @@ or countries. ...@@ -39,7 +39,7 @@ or countries.
== COMMANDS == COMMANDS
'export --directory=DIR [--format=FORMAT] [--family=ipv6|ipv4] [ASN|CC ...]':: 'export [--directory=DIR] [--format=FORMAT] [--family=ipv6|ipv4] [ASN|CC ...]'::
This command exports the whole database into the given directory. This command exports the whole database into the given directory.
+ +
The output can be filtered by only exporting a certain address family, or by passing The output can be filtered by only exporting a certain address family, or by passing
...@@ -47,6 +47,9 @@ or countries. ...@@ -47,6 +47,9 @@ or countries.
+ +
The output format can be chosen with the '--format' parameter. For possible formats, The output format can be chosen with the '--format' parameter. For possible formats,
please see below. please see below.
+
If the '--directory' option is omitted, the output will be written to stdout which
is useful when you want to load any custom exports straight into nftables or ipset.
'get-as ASN [ASN...]':: 'get-as ASN [ASN...]'::
This command returns the name of the owning organisation of the Autonomous This command returns the name of the owning organisation of the Autonomous
......
...@@ -23,7 +23,9 @@ import logging ...@@ -23,7 +23,9 @@ import logging
import math import math
import os import os
import socket import socket
import sys
from .i18n import _
import _location import _location
# Initialise logging # Initialise logging
...@@ -66,7 +68,12 @@ class OutputWriter(object): ...@@ -66,7 +68,12 @@ class OutputWriter(object):
""" """
Convenience function to open a file Convenience function to open a file
""" """
f = open(filename, cls.mode) if filename:
f = open(filename, cls.mode)
elif "b" in cls.mode:
f = io.BytesIO()
else:
f = io.StringIO()
return cls(f, *args, **kwargs) return cls(f, *args, **kwargs)
...@@ -94,8 +101,22 @@ class OutputWriter(object): ...@@ -94,8 +101,22 @@ class OutputWriter(object):
""" """
self._write_footer() self._write_footer()
# Close the file # Flush all output
self.f.close() self.f.flush()
def print(self):
"""
Prints the entire output line by line
"""
if isinstance(self.f, io.BytesIO):
raise TypeError(_("Won't write binary output to stdout"))
# Go back to the beginning
self.f.seek(0)
# Iterate over everything line by line
for line in self.f:
sys.stdout.write(line)
class IpsetOutputWriter(OutputWriter): class IpsetOutputWriter(OutputWriter):
...@@ -199,6 +220,8 @@ class Exporter(object): ...@@ -199,6 +220,8 @@ class Exporter(object):
self.db, self.writer = db, writer self.db, self.writer = db, writer
def export(self, directory, families, countries, asns): def export(self, directory, families, countries, asns):
filename = None
for family in families: for family in families:
log.debug("Exporting family %s" % family) log.debug("Exporting family %s" % family)
...@@ -206,17 +229,25 @@ class Exporter(object): ...@@ -206,17 +229,25 @@ class Exporter(object):
# Create writers for countries # Create writers for countries
for country_code in countries: for country_code in countries:
filename = self._make_filename( if directory:
directory, prefix=country_code, suffix=self.writer.suffix, family=family, filename = self._make_filename(
) directory,
prefix=country_code,
suffix=self.writer.suffix,
family=family,
)
writers[country_code] = self.writer.open(filename, family, prefix="%s" % country_code) writers[country_code] = self.writer.open(filename, family, prefix=country_code)
# Create writers for ASNs # Create writers for ASNs
for asn in asns: for asn in asns:
filename = self._make_filename( if directory:
directory, "AS%s" % asn, suffix=self.writer.suffix, family=family, filename = self._make_filename(
) directory,
prefix="AS%s" % asn,
suffix=self.writer.suffix,
family=family,
)
writers[asn] = self.writer.open(filename, family, prefix="AS%s" % asn) writers[asn] = self.writer.open(filename, family, prefix="AS%s" % asn)
...@@ -258,6 +289,11 @@ class Exporter(object): ...@@ -258,6 +289,11 @@ class Exporter(object):
for writer in writers.values(): for writer in writers.values():
writer.finish() writer.finish()
# Print to stdout
if not directory:
for writer in writers.values():
writer.print()
def _make_filename(self, directory, prefix, suffix, family): def _make_filename(self, directory, prefix, suffix, family):
filename = "%s.%s%s" % ( filename = "%s.%s%s" % (
prefix, suffix, "6" if family == socket.AF_INET6 else "4" prefix, suffix, "6" if family == socket.AF_INET6 else "4"
......
...@@ -181,7 +181,7 @@ class CLI(object): ...@@ -181,7 +181,7 @@ class CLI(object):
) )
export.add_argument("--format", help=_("Output format"), export.add_argument("--format", help=_("Output format"),
choices=location.export.formats.keys(), default="list") choices=location.export.formats.keys(), default="list")
export.add_argument("--directory", help=_("Output directory"), required=True) export.add_argument("--directory", help=_("Output directory"))
export.add_argument("--family", export.add_argument("--family",
help=_("Specify address family"), choices=("ipv6", "ipv4"), help=_("Specify address family"), choices=("ipv6", "ipv4"),
) )
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment