aboutsummaryrefslogtreecommitdiff
path: root/potpourri/ca-pickle.py
blob: 5b88f3f941d9425f4be4f9530eb0a20de2723166 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
#!/usr/bin/env python

# $Id$

"""
Package up state of an old (pre-rpkidb, pre-pubdb, pre-Django 1.8)
RPKI CA installation as a Python pickle database, for later re-loading
into a more recent version of the code using a companion script.
"""

import os
import sys
import cPickle
import argparse
import subprocess
import rpki.config
import rpki.version
import rpki.autoconf

from rpki.mysql_import import MySQLdb, _mysql_exceptions

parser = argparse.ArgumentParser(description = __doc__)
parser.add_argument("-c", "--config",
                    help = "specify alternate location for rpki.conf")
parser.add_argument("-p", "--protocol",
                    choices = (0, 1, 2), type = int, default = 2,
                    help = "pickling protocol to use")
parser.add_argument("output",
                    help = "output file")
args = parser.parse_args()

cfg = rpki.config.parser(args.config)

databases = {}

for section in ("rpkid", "irdbd", "pubd"):
    db = MySQLdb.connect(db     = cfg.get(section = section, option = "sql-database"),
                         user   = cfg.get(section = section, option = "sql-username"),
                         passwd = cfg.get(section = section, option = "sql-password"))
    tables = {}

    cur = db.cursor()
    cur.execute("SHOW TABLES")
    table_names = tuple(row[0] for row in cur.fetchall())
    cur.close()

    cur = db.cursor(MySQLdb.cursors.DictCursor)
    for name in table_names:
        cur.execute("SELECT * FROM " + name)
        tables[name] = cur.fetchall()
    cur.close()

    db.close()

    databases[section] = tables

filenames     = [cfg.filename]
raw_config    = dict((section, {}) for section in cfg.cfg.sections())
cooked_config = dict((section, {}) for section in cfg.cfg.sections())

for section in cfg.cfg.sections():
    for option in cfg.cfg.options(section):
        raw_config   [section][option] = cfg.cfg.get(section = section, option = option)
        cooked_config[section][option] =     cfg.get(section = section, option = option)
        if os.path.isfile(   cooked_config[section][option]):
            filenames.append(cooked_config[section][option])

# Sigh, even here we need special hacks for rootd, which handles filenames a bit differently.
rootd_dir = cfg.get(section = "rootd", option = "rpki-root-dir", default = "")
for option in ("rpki-root-crl", "rpki-root-manifest", "rpki-subject-cert"):
    fn = os.path.join(rootd_dir, cfg.get(section = "rootd", option = option, default = ""))
    if os.path.isfile(fn):
        filenames.append(fn)

for i, fn in enumerate(filenames):
    filenames[i] = os.path.abspath(fn)

files = {}

for filename in filenames:
    with open(filename, "rb") as f:
        files[filename] = f.read()

world = dict(
    version       = rpki.version.VERSION,
    rpki_conf     = filenames[0],
    databases     = databases,
    files         = files,
    raw_config    = raw_config,
    cooked_config = cooked_config)

xz = subprocess.Popen(
    ("xz", "-C", "sha256"),
    stdin = subprocess.PIPE,
    stdout = os.open(args.output, os.O_WRONLY | os.O_CREAT, 0600))

cPickle.dump(world, xz.stdin, args.protocol)

xz.stdin.flush()
xz.stdin.close()

if xz.wait() != 0:
    sys.exit("XZ pickling failed with code {}".format(xz.returncode))