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.
== 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.
+
The output can be filtered by only exporting a certain address family, or by passing
......@@ -47,6 +47,9 @@ or countries.
+
The output format can be chosen with the '--format' parameter. For possible formats,
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...]'::
This command returns the name of the owning organisation of the Autonomous
......
......@@ -23,7 +23,9 @@ import logging
import math
import os
import socket
import sys
from .i18n import _
import _location
# Initialise logging
......@@ -66,7 +68,12 @@ class OutputWriter(object):
"""
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)
......@@ -94,8 +101,22 @@ class OutputWriter(object):
"""
self._write_footer()
# Close the file
self.f.close()
# Flush all output
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):
......@@ -199,6 +220,8 @@ class Exporter(object):
self.db, self.writer = db, writer
def export(self, directory, families, countries, asns):
filename = None
for family in families:
log.debug("Exporting family %s" % family)
......@@ -206,17 +229,25 @@ class Exporter(object):
# Create writers for countries
for country_code in countries:
filename = self._make_filename(
directory, prefix=country_code, suffix=self.writer.suffix, family=family,
)
if directory:
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
for asn in asns:
filename = self._make_filename(
directory, "AS%s" % asn, suffix=self.writer.suffix, family=family,
)
if directory:
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)
......@@ -258,6 +289,11 @@ class Exporter(object):
for writer in writers.values():
writer.finish()
# Print to stdout
if not directory:
for writer in writers.values():
writer.print()
def _make_filename(self, directory, prefix, suffix, family):
filename = "%s.%s%s" % (
prefix, suffix, "6" if family == socket.AF_INET6 else "4"
......
......@@ -181,7 +181,7 @@ class CLI(object):
)
export.add_argument("--format", help=_("Output format"),
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",
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