diff options
-rw-r--r-- | rpkid/Makefile.in | 1 | ||||
-rw-r--r-- | rpkid/examples/rpki.conf | 10 | ||||
-rw-r--r-- | rpkid/portal-gui/Makefile.in | 14 | ||||
-rwxr-xr-x | rpkid/portal-gui/scripts/dumpdata.py | 43 | ||||
-rw-r--r-- | rpkid/portal-gui/settings.py.in | 30 | ||||
-rw-r--r-- | rpkid/rpki/gui/app/glue.py | 140 |
6 files changed, 160 insertions, 78 deletions
diff --git a/rpkid/Makefile.in b/rpkid/Makefile.in index db47b0da..ff035f17 100644 --- a/rpkid/Makefile.in +++ b/rpkid/Makefile.in @@ -202,7 +202,6 @@ COMPILE_DJANGO = \ COMPILE_SETTINGS = \ rm -f $@; \ - AC_DATABASE_PATH='${DESTDIR}${localstatedir}/rpki/gui.db' \ AC_SECRET_KEY='${SECRET_KEY}' \ AC_LOCALSTATEDIR='${DESTDIR}${localstatedir}' \ AC_WEBUSER='${WEBUSER}' \ diff --git a/rpkid/examples/rpki.conf b/rpkid/examples/rpki.conf index 17e37b7b..53216b97 100644 --- a/rpkid/examples/rpki.conf +++ b/rpkid/examples/rpki.conf @@ -368,6 +368,16 @@ root_cert_manifest = rsync://${myrpki::publication_rsync_server}/${myrpki::publ ################################################################# +# Glue to allow the django application to pull user configuration +# from this file rather than directly editing settings.py + +[web_portal] +sql-database = ${myrpki::irdbd_sql_database} +sql-username = ${myrpki::irdbd_sql_username} +sql-password = ${myrpki::irdbd_sql_password} + +################################################################# + # Constants for OpenSSL voodoo portion of this file, to make them # easier to find. diff --git a/rpkid/portal-gui/Makefile.in b/rpkid/portal-gui/Makefile.in index fa4e1e46..4c3882eb 100644 --- a/rpkid/portal-gui/Makefile.in +++ b/rpkid/portal-gui/Makefile.in @@ -17,16 +17,11 @@ libexecdir=@libexecdir@ sysconfdir=@sysconfdir@ WEBUSER=@WEBUSER@ -DJANGO_ADMIN=@DJANGO_ADMIN@ -PYTHON=@PYTHON@ -DJANGO_DIR=@DJANGO_DIR@ INSTALL = @INSTALL@ CONFDIR=${DESTDIR}$(localstatedir)/rpki/conf -DATABASE_PATH=${DESTDIR}$(localstatedir)/rpki/gui.db INSTDIR=${DESTDIR}$(datarootdir)/rpki/gui -STATIC_DIR=${INSTDIR}/static PYTHONPATH=${DESTDIR}${sysconfdir}/rpki # automatically built sources @@ -42,9 +37,7 @@ distclean: clean rm -f Makefile edit = sed \ - -e 's|@DJANGO_DIR[@]|$(DJANGO_DIR)|g' \ - -e 's|@INSTDIR[@]|$(INSTDIR)|g' \ - -e 's|@STATIC_DIR[@]|$(STATIC_DIR)|g' + -e 's|@INSTDIR[@]|$(INSTDIR)|g' apache/rpki.conf: $(srcdir)/apache/rpki.conf.in Makefile $(edit) $@.in > $@ @@ -52,8 +45,6 @@ apache/rpki.conf: $(srcdir)/apache/rpki.conf.in Makefile .PHONY: install-perms install-data install install-perms: - chown $(WEBUSER) `dirname $(DATABASE_PATH)` - chown $(WEBUSER) $(DATABASE_PATH) mkdir -p $(CONFDIR) chown -R $(WEBUSER) $(CONFDIR) @@ -63,7 +54,6 @@ install-apache: ${INSTALL} -m 644 apache/rpki.wsgi $(INSTDIR)/apache install-data: $(BUILD) install-apache - mkdir -p `dirname $(DATABASE_PATH)` mkdir -p ${PYTHONPATH} # FIXME should eventually try to merge new settings? @if [ ! -f ${PYTHONPATH}/settings.py ]; then \ @@ -72,8 +62,6 @@ install-data: $(BUILD) install-apache echo "${PYTHONPATH}/settings.py already exists, installing settings.py as ${PYTHONPATH}/settings.py.new"; \ ${INSTALL} -m 644 settings.py ${PYTHONPATH}/settings.py.new; \ fi - $(DJANGO_ADMIN) syncdb --pythonpath ${PYTHONPATH} --settings settings - #$(DJANGO_ADMIN) collectstatic --noinput --pythonpath ${PYTHONPATH} --settings settings if [ ! -f $(INSTDIR)/rpki.conf.template ]; then ${INSTALL} -m 644 ../examples/rpki.conf $(INSTDIR)/rpki.conf.template; fi install: install-data install-perms diff --git a/rpkid/portal-gui/scripts/dumpdata.py b/rpkid/portal-gui/scripts/dumpdata.py new file mode 100755 index 00000000..dcf23666 --- /dev/null +++ b/rpkid/portal-gui/scripts/dumpdata.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python +# $Id$ +# +# Copyright (C) 2012 SPARTA, Inc. a Parsons Company +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND SPARTA DISCLAIMS ALL WARRANTIES WITH +# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +# AND FITNESS. IN NO EVENT SHALL SPARTA BE LIABLE FOR ANY SPECIAL, DIRECT, +# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE +# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. +# +# This is a helper script which will dump the rpki.gui.app models from +# the old sqlite3 database, forcing the output order to the primary key in +# order to avoid forward references for the AddressRange table. + +from django.conf import settings +settings.configure(DEBUG=True, + DATABASES={ + 'default': { + 'ENGINE': 'django.db.backends.sqlite3', + 'NAME': '/usr/local/var/rpki/gui.db', + } + }) + +from django.core import serializers +import django.db.models + +from rpki.gui.app import models +from django.contrib.auth import models as auth_models + +data = [] +for v in (auth_models.User, models.Conf, models.Parent, models.Child, models.AddressRange, models.Asn, models.ResourceCert, models.Roa, models.RoaRequest, models.Ghostbuster): + data.extend(list(v.objects.all().order_by('id'))) + +print serializers.serialize('json', data, use_natural_keys=True) + +# vim:sw=4 ts=8 expandtab diff --git a/rpkid/portal-gui/settings.py.in b/rpkid/portal-gui/settings.py.in index 2800bc24..baa9197c 100644 --- a/rpkid/portal-gui/settings.py.in +++ b/rpkid/portal-gui/settings.py.in @@ -6,13 +6,33 @@ # DO NOT EDIT! This file is automatically generated from # settings.py.in +import rpki.config + DEBUG = True TEMPLATE_DEBUG = DEBUG +# needs to be set prior to the call to rpki.config.parser so it knows +# where to find the system rpki.conf +rpki.config.default_dirname = '%(AC_SYSCONFDIR)s' + +# load the sql authentication bits from the system rpki.conf +rpki_config = rpki.config.parser(section='web_portal') + DATABASES = { 'default' : { - 'ENGINE': 'django.db.backends.sqlite3', - 'NAME' : '%(AC_DATABASE_PATH)s' + 'ENGINE' : 'django.db.backends.mysql', + 'NAME' : rpki_config.get('sql-database'), + 'USER' : rpki_config.get('sql-username'), + 'PASSWORD': rpki_config.get('sql-password'), + + # Ensure the default storage engine is InnoDB since we need + # foreign key support. The Django documentation suggests + # removing this after the syncdb is performed as an optimization, + # but there isn't an easy way to do this automatically. + + 'OPTIONS' : { + 'init_command': 'SET storage_engine=INNODB' + } } } @@ -54,7 +74,6 @@ INSTALLED_APPS = ( 'django.contrib.admindocs', 'django.contrib.contenttypes', 'django.contrib.sessions', -# 'django.contrib.staticfiles', 'rpki.gui.app', 'rpki.gui.cacheview' ) @@ -67,8 +86,3 @@ TEMPLATE_CONTEXT_PROCESSORS = ( "django.contrib.messages.context_processors.messages", "django.core.context_processors.request" ) - -#STATIC_URL = '/static/' -#STATIC_ROOT = '%(AC_DATAROOTDIR)s/rpki/gui/static' -#STATICFILES_DIRS = (("admin", "%(AC_DJANGO_DIR)s/contrib/admin/media"),) -#STATICFILES_FINDERS = ("django.contrib.staticfiles.finders.FileSystemFinder",) diff --git a/rpkid/rpki/gui/app/glue.py b/rpkid/rpki/gui/app/glue.py index 687af268..c796c148 100644 --- a/rpkid/rpki/gui/app/glue.py +++ b/rpkid/rpki/gui/app/glue.py @@ -28,17 +28,22 @@ from rpki.gui.app import models, settings def confpath(*handle): """ - Return the absolute pathname to the configuration directory for - the given resource handle. If additional arguments are given, they - are taken to mean files/subdirectories. + Return the absolute pathname to the configuration directory for the + given resource handle. If additional arguments are given, they are + taken to mean files/subdirectories relative to the configuration + directory. + """ argv = [ settings.CONFDIR ] argv.extend(handle) return os.path.join(*argv) def read_file_from_handle(handle, fname): - """read a filename relative to the directory for the given resource handle. returns - a tuple of (content, mtime)""" + """ + read a filename relative to the directory for the given resource + handle. returns a tuple of (content, mtime) + + """ with open(confpath(handle, fname), 'r') as fp: data = fp.read() mtime = os.fstat(fp.fileno())[stat.ST_MTIME] @@ -47,21 +52,21 @@ def read_file_from_handle(handle, fname): read_identity = lambda h: read_file_from_handle(h, 'entitydb/identity.xml')[0] def output_asns(path, handle): - '''Write out csv file containing asns delegated to my children.''' + """Write out csv file containing asns delegated to my children.""" qs = models.Asn.objects.filter(lo=F('hi'), allocated__in=handle.children.all()) w = rpki.myrpki.csv_writer(path) w.writerows([asn.allocated.handle, asn.lo] for asn in qs) w.close() def output_prefixes(path, handle): - '''Write out csv file containing prefixes delegated to my children.''' + """Write out csv file containing prefixes delegated to my children.""" qs = models.AddressRange.objects.filter(allocated__in=handle.children.all()) w = rpki.myrpki.csv_writer(path) w.writerows([p.allocated.handle, p.as_resource_range()] for p in qs) w.close() def output_roas(path, handle): - '''Write out csv file containing my roas.''' + """Write out csv file containing my roas.""" qs = models.RoaRequest.objects.filter(roa__in=handle.roas.all()) w = rpki.myrpki.csv_writer(path) w.writerows([req.as_roa_prefix(), req.roa.asn, @@ -77,6 +82,7 @@ def build_rpkid_caller(cfg, verbose=False): Returns a function suitable for calling rpkid using the configuration information specified in the rpki.config.parser object. + """ bpki_servers_dir = cfg.get("bpki_servers_directory") if not bpki_servers_dir.startswith('/'): @@ -111,9 +117,7 @@ def build_pubd_caller(cfg): url = pubd_base + "control")) def ghostbuster_to_vcard(gbr): - """ - Convert a Ghostbuster object into a vCard object. - """ + """Convert a Ghostbuster object into a vCard object.""" import vobject vcard = vobject.vCard() @@ -139,11 +143,13 @@ def ghostbuster_to_vcard(gbr): return vcard.serialize() def qualify_path(pfx, fname): - """ - Ensure 'path' is an absolute filename. - """ + """Ensure 'path' is an absolute filename.""" return fname if fname.startswith('/') else os.path.join(pfx, fname) +def get_system_config(): + """Returns an rpki.config.parser object for the system rpki.conf.""" + return rpki.config.parser(section='myrpki') + def configure_resources(log, handle): """ This function should be called when resources for this resource @@ -153,10 +159,16 @@ def configure_resources(log, handle): For backwards compatability (and backups), it also writes the csv files for use with the myrpki.py command line script. - """ + """ path = confpath(handle.handle) - cfg = rpki.config.parser(os.path.join(path, 'rpki.conf'), 'myrpki') + + # Read rpki.conf to determine the paths for the csv files. + if handle.host: + cfg = rpki.config.parser(os.path.join(path, 'rpki.conf'), section='myrpki') + else: + # Use the system rpki.conf for the self-hosted handle. + cfg = get_system_config() output_asns(qualify_path(path, cfg.get('asn_csv')), handle) output_prefixes(qualify_path(path, cfg.get('prefix_csv')), handle) @@ -187,7 +199,7 @@ def configure_resources(log, handle): else: v6.append(rng) - # convert from datetime.datetime to rpki.sundial.datetime + # Convert from datetime.datetime to rpki.sundial.datetime valid_until = rpki.sundial.datetime.fromdatetime(child.valid_until) children.append((child.handle, asns, v4, v6, valid_until)) @@ -201,24 +213,23 @@ def configure_resources(log, handle): else: ghostbusters.append((None, vcard)) - # for hosted handles, get the config for the irdbd/rpkid host + # For hosted handles, get the config for the irdbd/rpkid host, which + # contains the information needed to talk to the daemons. if handle.host: - cfg = rpki.config.parser(confpath(handle.host.handle, 'rpki.conf'), 'myrpki') + cfg = get_system_config() irdb = rpki.myrpki.IRDB(cfg) irdb.update(handle, roa_requests, children, ghostbusters) irdb.close() - # contact rpkid to request immediate update + # Contact rpkid to request immediate update. call_rpkid = build_rpkid_caller(cfg) call_rpkid(rpki.left_right.self_elt.make_pdu(action='set', self_handle=handle.handle, run_now=True)) def list_received_resources(log, conf): - "Query rpkid for this resource handle's children and received resources." - - # if this handle is hosted, get the cfg for the host - rpki_conf = conf.host if conf.host else conf - cfg = rpki.config.parser(confpath(rpki_conf.handle, 'rpki.conf'), 'myrpki') + """Query rpkid for this resource handle's children and received resources.""" + # always use the system rpki.conf for talking to the daemons + cfg = get_system_config() call_rpkid = build_rpkid_caller(cfg) pdus = call_rpkid(rpki.left_right.list_received_resources_elt.make_pdu(self_handle=conf.handle), rpki.left_right.child_elt.make_pdu(action="list", self_handle=conf.handle), @@ -307,6 +318,7 @@ def config_from_template(dest, a): Create a new rpki.conf file from a generic template. Go line by line through the template and substitute directives from the dictionary 'a'. + """ with open(dest, 'w') as f: for r in open(settings.RPKI_CONF_TEMPLATE): @@ -322,26 +334,36 @@ def config_from_template(dest, a): class Myrpki(rpki.myrpki.main): """ - wrapper around rpki.myrpki.main to force the config file to what i want, + Wrapper around rpki.myrpki.main to force the config file to what I want, and avoid cli arg parsing. + """ def __init__(self, handle): self.cfg_file = confpath(handle, 'rpki.conf') self.read_config() +def get_myrpki(conf): + """ + Return a rpki.myrpki.main() or subclass thereof depending on + whether the 'conf' argument refers to the rpki host, or to a + hosted conf. When refering to a hosted conf, we use the wrapper + subclass to force use of the stub rpki.conf located in the conf + directory. For the rpkid host, we use the system rpki.conf. + + """ + return Myrpki(conf.handle) if conf.host else rpki.myrpki.main() + def configure_daemons(log, conf, m): if conf.host: m.configure_resources_main() - host = Myrpki(conf.host.handle) + host = get_myrpki(conf.host) host.do_configure_daemons(m.cfg.get('xml_filename')) else: m.do_configure_daemons('') def initialize_handle(log, handle, host, owner=None, commit=True): - """ - Create a new Conf object for this user. - """ + """Create a new Conf object for this user.""" print >>log, "initializing new resource handle %s" % handle qs = models.Conf.objects.filter(handle=handle) @@ -353,28 +375,35 @@ def initialize_handle(log, handle, host, owner=None, commit=True): else: conf = qs[0] - # create the config directory if it doesn't already exist + # Create the config directory if it doesn't already exist top = confpath(conf.handle) if not os.path.exists(top): os.makedirs(top) cfg_file = confpath(conf.handle, 'rpki.conf') - # create rpki.conf file if it doesn't exist + # Create rpki.conf file if it doesn't exist if not os.path.exists(cfg_file): print >>log, "generating rpki.conf for %s" % conf.handle - config_from_template(cfg_file, { 'handle': conf.handle, - 'configuration_directory': top, 'run_rpkid': 'false'}) - - # create stub csv files + config_from_template(cfg_file, + { + 'handle' : conf.handle, + 'configuration_directory': top, + 'run_rpkid' : 'false', + 'run_pubd' : 'false', + 'run_rootd' : 'false', + 'openssl' : get_system_config().get('openssl') + }) + + # Create stub csv files for f in ('asns', 'prefixes', 'roas'): p = confpath(conf.handle, f + '.csv') if not os.path.exists(p): f = open(p, 'w') f.close() - # load configuration for self - m = Myrpki(conf.handle) + # Load configuration for self + m = get_myrpki(conf) m.do_initialize('') if commit: @@ -385,36 +414,35 @@ def initialize_handle(log, handle, host, owner=None, commit=True): return conf, m def import_child(log, conf, child_handle, xml_file): - """ - Import a child's identity.xml. - """ - m = Myrpki(conf.handle) + """Import a child's identity.xml.""" + m = get_myrpki(conf) m.do_configure_child(xml_file) configure_daemons(log, conf, m) def import_parent(log, conf, parent_handle, xml_file): - m = Myrpki(conf.handle) + m = get_myrpki(conf) m.do_configure_parent(xml_file) configure_daemons(log, conf, m) def import_pubclient(log, conf, xml_file): - m = Myrpki(conf.handle) + m = get_myrpki(conf) m.do_configure_publication_client(xml_file) configure_daemons(log, conf, m) def import_repository(log, conf, xml_file): - m = Myrpki(conf.handle) + m = get_myrpki(conf) m.do_configure_repository(xml_file) configure_daemons(log, conf, m) def create_child(log, parent_conf, child_handle): """ - implements the child create wizard to create a new locally hosted child + Implements the child create wizard to create a new locally hosted child + """ child_conf, child = initialize_handle(log, handle=child_handle, host=parent_conf, commit=False) parent_handle = parent_conf.handle - parent = Myrpki(parent_handle) + parent = get_myrpki(parent_conf) child_identity_xml = os.path.join(child.cfg.get("entitydb_dir"), 'identity.xml') parent_response_xml = os.path.join(parent.cfg.get("entitydb_dir"), 'children', child_handle + '.xml') @@ -460,7 +488,7 @@ def destroy_handle(log, handle): shutil.remove(confpath(handle)) def read_child_response(log, conf, child_handle): - m = Myrpki(conf.handle) + m = get_myrpki(conf) bname = child_handle + '.xml' return open(os.path.join(m.cfg.get('entitydb_dir'), 'children', bname)).read() @@ -471,16 +499,16 @@ def read_child_repo_response(log, conf, child_handle): Note: the current model assumes the publication client is a child of this handle. - """ - m = Myrpki(conf.handle) + """ + m = get_myrpki(conf) return open(os.path.join(m.cfg.get('entitydb_dir'), 'pubclients', '%s.%s.xml' % (conf.handle, child_handle))).read() def update_bpki(log, conf): - m = Myrpki(conf.handle) + m = get_myrpki(conf) - # automatically runs configure_daemons when self-hosted - # otherwise runs configure_resources + # Automatically runs configure_daemons when self-hosted otherwise runs + # configure_resources. m.do_update_bpki('') # when hosted, ship off to rpkid host @@ -488,13 +516,13 @@ def update_bpki(log, conf): configure_daemons(log, conf, m) def delete_child(log, conf, child_handle): - m = Myrpki(conf.handle) + m = get_myrpki(conf) m.do_delete_child(child_handle) configure_daemons(log, conf, m) def delete_parent(log, conf, parent_handle): - m = Myrpki(conf.handle) + m = get_myrpki(conf) m.do_delete_parent(parent_handle) configure_daemons(log, conf, m) -# vim:sw=4 ts=8 expandtab +# vim:sw=4 ts=8 expandtab tw=79 |