aboutsummaryrefslogtreecommitdiffstats
path: root/bootstrap
diff options
context:
space:
mode:
Diffstat (limited to 'bootstrap')
-rw-r--r--bootstrap/README.md150
-rwxr-xr-xbootstrap/apply-baseupdate.sh14
-rwxr-xr-xbootstrap/create-hostsfile.sh17
-rwxr-xr-xbootstrap/create-shellconf.pl30
-rwxr-xr-xbootstrap/init-sshkeys.sh14
-rwxr-xr-xbootstrap/install-dependencies.sh55
-rwxr-xr-xbootstrap/make-base-requires.sh75
-rwxr-xr-xbootstrap/make-dhcp6-init.sh210
-rwxr-xr-xbootstrap/make-dhcpd.pl101
-rwxr-xr-xbootstrap/make-first-zones.pl108
-rwxr-xr-xbootstrap/make-named.pl129
-rwxr-xr-xbootstrap/make-pxeboot.sh32
-rwxr-xr-xbootstrap/make-reverse4-files.pl153
-rwxr-xr-xbootstrap/update-baseservice.sh29
-rwxr-xr-xbootstrap/update-tools.sh25
15 files changed, 1142 insertions, 0 deletions
diff --git a/bootstrap/README.md b/bootstrap/README.md
new file mode 100644
index 0000000..8301d51
--- /dev/null
+++ b/bootstrap/README.md
@@ -0,0 +1,150 @@
+Outline:
+------------------------------------------------------------------
+
+ 1. Install OS on three boxes
+ 2. Bootstrap:
+ * Install tgmanage on one, the bootstrap (tools, include, netlist.txt)
+ * Install dependencies on bootstrap
+ * Push SSH key key to the other boxes (init-sshkeys.sh)
+ * Update configuration
+ * Update netlist.txt
+ * Bootstrap the primary and secondary (make-base-requires.sh)
+ 3. Create new networks/scopes/zones Update during the party using
+ update-baseservice.sh from bootstrap
+ 4. Apply changes usling tools/apply-baseupdate.sh (reloads bind, restarts dhcpd)
+ 5. Changes to generated scopes, pools, zones are done on the primary, in the files
+ 6. If tools need patching, patch on boot and push with update-tools.sh
+ 7. Before wednesday evening, the infra.tgXX.gathering.org zone should be updated!
+
+**Only use make-base-requires.sh during bootstrap !!!!!!! :P**
+
+Detailed instructions and description:
+==================================================================
+
+1: Install Debian
+------------------------------------------------------------------
+
+The following three hosts/servers are normally used:
+ * A 'bootstrap' box. This server will be used to configure
+ the first TG-servers, and may end up hosting the switch-config and NMS.
+ * The server to use as Primary DNS and DHCP server
+ * The server to use as Secondary DNS and SMTP.
+
+2: Perform bootstrapping
+------------------------------------------------------------------
+
+Start by placing the 'tgmanage' directory as '/root/tgmanage' on the bootstrap
+box. Change into the 'tgmanage' directory. Next, run
+'bootstrap/install-dependencies.sh boot'
+
+
+Edit 'include/config.local.pm' and update for this year's TG. Use
+'bootstrap/create-shellconf.pl' to extract configuration from the perl module to
+create/update the 'include/tgmanage.cfg.sh' configuration script.
+
+Run 'bootstrap/create-hostsfile.sh' to make sure the bootstrap-box can use
+hostnames to reach the pri/sec DNS even before DNS is set up.
+
+The tools make extensive use of key-based SSH logins, to make this work
+seamlessly, run 'bootstrap/init-sshkeys.sh' to create an RSA priv/pub keypair, and
+push the pubkey to the Primary and Secondary boxes.
+
+
+The Network-list is _not_ automagically updated. A copy of last year's
+netlist.txt should be included in the goodiebag. With that as a base, update
+for this year's address plan. Remember that client nets in the hall are
+supposed to be pulled from switches.txt ...
+The rest of the information needed should be pulled from techwiki.g.o The
+format of the file is: one net per line, lines starting with # are skipped,
+format of each net-line is:
+
+ # <network adress> <prefixlen> <network-name>
+ 176.110.124.0 24 noc
+
+
+Run 'bootstrap/make-base-requires.sh'. This script will log in on the Primary and
+Secondary boxes, install dependencies and the BIND/DHCP packages, create all
+needed directories, create the initial configuration files.
+
+A short listing of the tasks of scripts called by make-base-requires (NOTE: these
+scripts are run by bootstrap/make-base-requires.sh, you should not need to run these individually):
+ * bootstrap/install-dependencies.sh
+ * Installs needed base software to boot, primary and secondary
+ * bootstrap/make-named.pl
+ * Basic BIND setup (creates named.conf et.al)
+ * bootstrap/make-first-zones.pl
+ * Creates static zone-files (tgname, infra, ipv6zone)
+ * bootstrap/make-reverse4-files.pl
+ * Creates reverse-zones for IPv4
+ * bootstrap/make-dhcpd.pl
+ * Sets up the base setup for DHCP
+
+3++: Update during the party using update-baseservice.sh from bootstrap
+------------------------------------------------------------------
+
+After 'bootstrap/make-base-requires.sh' has been run, further updating should be
+managed by the following three files:
+ * bootstrap/update-baseservice.sh
+ * Used to add/update bind and DHCP configuration
+ * bootstrap/apply-baseupdate.sh
+ * Used to reload bind and restart DHCP
+ * bootstrap/update-tools.sh
+ * Used to push changes to the tgmanage toolchain
+
+This means, after the base setup is completed, updating and managing the
+configuration is done by updating netlist.txt and running bootstrap/update-baseservice.sh
+from the bootstrap box, or from the NMS box if the toolchain gets moved there during
+the party.
+
+To create a new DHCP scope, add DNS forward and reverse zone for a new network:
+
+ * Add the network to netlist.txt
+ * Run bootstrap/update-baseservice.sh to generate new .conf and .zone files
+ * Run bootstrap/apply-baseupdate.sh to load new configuration
+
+To do changes to DHCP config after the scope .conf file has been created
+(read: later in the party), log in to the primary/dhcp server, and make
+the changes in the appropriate .conf file ..
+
+To do DNS changes to the main DNS zone or the infra-zone, make the changes
+in the appropriate zone file on the primary DNS server.
+
+To add DNS records to any other DNS zone (forward or reverse), you have
+to use 'nsupdate'. To simplify the process, use bootstrap/generate-dnsrr.pl
+Usage on this tool is documented in the "header" of the script...
+
+
+The update prosess is handled by a bunch of "sub-tools", these should typically
+not need to be run individually:
+ * bootstrap/make-bind-include.pl
+ * Run via update-baseservice, adds new net's to DNS include
+ * bootstrap/make-dhcpd-include.pl
+ * Run via update-baseservice, adds new net's to DHCP include
+ * bootstrap/make-missing-conf.pl
+ * Run via update-baseservice, adds missing net-conf to BIND/DHCP
+
+
+7: Generation of linknet dns content
+------------------------------------------------------------------
+
+Format for linknet.txt is documented in make-linknet-hosts.pl
+
+Generate IPv4 infra hostnames and IP address assignments
+by using tools/generate-dnsrr.pl
+
+Output from this shuld go in infra.tgXX.gathering.org.zone on primary:
+> cat linknet.txt | tools/make-linknet-hosts.pl | tools/generate-dnsrr.pl --domain infra.tgXX.gathering.org
+
+Output from this should go as input to nsupdate, see doc in generate-dnsrr.pl:
+> cat linknet.txt | tools/make-linknet-hosts.pl | tools/generate-dnsrr.pl --domain infra.tgXX.gathering.org -ns -rev
+
+
+Other stuff....
+------------------------------------------------------------------
+Files that are not used? Need to revisit these files...
+
+ * tools/make-switch-placements.pl
+ * Updates positions for switches in NMS map (png)?
+ * tools/make-switches.pl
+ * tools/fetch-portlist.sh
+
diff --git a/bootstrap/apply-baseupdate.sh b/bootstrap/apply-baseupdate.sh
new file mode 100755
index 0000000..055320c
--- /dev/null
+++ b/bootstrap/apply-baseupdate.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+
+set -e
+
+source include/tgmanage.cfg.sh
+if [ -z ${PRIMARY} ]
+then
+ echo "Not configured!";
+ exit 1;
+fi;
+
+ssh -l root ${PRIMARY} "/etc/init.d/isc-dhcp-server restart"
+ssh -l root ${PRIMARY} "/usr/sbin/rndc reload"
+ssh -l root ${SECONDARY} "/usr/sbin/rndc reload"
diff --git a/bootstrap/create-hostsfile.sh b/bootstrap/create-hostsfile.sh
new file mode 100755
index 0000000..2aaf9cb
--- /dev/null
+++ b/bootstrap/create-hostsfile.sh
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+set -e
+
+source include/tgmanage.cfg.sh
+if [ -z ${PRIMARY} ]
+then
+ echo "Not configured!";
+ exit 1;
+fi;
+
+echo >> /etc/hosts
+echo "# Bootstrap hosts entries for ${TGNAME} ">> /etc/hosts
+echo "${PRI_V6} ${PRIMARY}" >> /etc/hosts
+echo "${PRI_V4} ${PRIMARY}" >> /etc/hosts
+echo "${SEC_V6} ${SECONDARY}" >> /etc/hosts
+echo "${SEC_V4} ${SECONDARY}" >> /etc/hosts
diff --git a/bootstrap/create-shellconf.pl b/bootstrap/create-shellconf.pl
new file mode 100755
index 0000000..9c4b500
--- /dev/null
+++ b/bootstrap/create-shellconf.pl
@@ -0,0 +1,30 @@
+#!/usr/bin/perl -I /root/tgmanage
+use strict;
+
+BEGIN {
+ require "include/config.pm";
+ eval {
+ require "include/config.local.pm";
+ };
+}
+
+my $bind_base = "/etc/bind/";
+my $dhcpd_base = "/etc/dhcp/";
+
+my $shellconf_file = "include/tgmanage.cfg.sh";
+
+open CFG, ">" . $shellconf_file or die ($! . " " . $shellconf_file );
+
+print CFG "# This file is autogenerated by tools/create-shellconf.pl,\n";
+print CFG "# using data from nms::config.\n";
+print CFG "#\n";
+print CFG "# Do you need new common/configuration variables?\n";
+print CFG "# Add/update include/config.local.pm and tools/create-shellconf.pl\n\n";
+print CFG "PRIMARY=\"$nms::config::pri_hostname.$nms::config::tgname.gathering.org\"\n";
+print CFG "SECONDARY=\"$nms::config::sec_hostname.$nms::config::tgname.gathering.org\"\n";
+print CFG "TGNAME=\"$nms::config::tgname\"\n\n";
+print CFG "PRI_V4=\"$nms::config::pri_v4\"\n";
+print CFG "PRI_V6=\"$nms::config::pri_v6\"\n";
+print CFG "SEC_V4=\"$nms::config::sec_v4\"\n\n";
+print CFG "SEC_V6=\"$nms::config::sec_v6\"\n\n";
+close CFG;
diff --git a/bootstrap/init-sshkeys.sh b/bootstrap/init-sshkeys.sh
new file mode 100755
index 0000000..9427bad
--- /dev/null
+++ b/bootstrap/init-sshkeys.sh
@@ -0,0 +1,14 @@
+#!/bin/bash
+
+set -e
+
+source include/tgmanage.cfg.sh
+if [ -z ${PRIMARY} ]
+then
+ echo "Not configured!";
+ exit 1;
+fi;
+
+ssh-keygen -P '' -f ~/.ssh/id_rsa -b 2048
+ssh-copy-id root@${PRIMARY}
+ssh-copy-id root@${SECONDARY}
diff --git a/bootstrap/install-dependencies.sh b/bootstrap/install-dependencies.sh
new file mode 100755
index 0000000..4edb01f
--- /dev/null
+++ b/bootstrap/install-dependencies.sh
@@ -0,0 +1,55 @@
+#!/bin/bash -e
+
+if [ "$1" != "master" -a "$1" != "slave" -a "$1" != "boot" ]; then
+ echo "Run as $0 <boot|master|slave>"
+ exit
+fi
+
+# OK, we know the content of $0 is OK. I prefer sane names.
+ROLE=$1;
+
+# Start by installing common packages. Remember to update
+# this when a new common dependency is discovered, plx.
+apt-get -y install \
+ vim-nox \
+ git \
+ ntp \
+ screen \
+ tmux \
+ dnsutils \
+ build-essential \
+ libnet-ip-perl \
+ libnetaddr-ip-perl \
+ libnet-telnet-cisco-perl \
+ libnet-ping-external-perl \
+ perl-modules \
+ libdbi-perl \
+ libdbd-pg-perl \
+ libnet-telnet-perl
+
+if [ "${ROLE}" == "boot" ]; then
+ # Install-tasks specific for the _bootstrab box_ here
+ echo "Installing for bootstrap"
+ apt-get -y install \
+ bind9utils
+fi
+
+if [ "${ROLE}" == "master" ]; then
+ # Install-tasks specific for the _primary_ here
+ echo "Installing for primary/master"
+ apt-get -y install \
+ isc-dhcp-server \
+ bind9utils \
+ bind9
+fi
+
+if [ "${ROLE}" == "slave" ]; then
+ # Install-tasks specific for the _secondary_ here
+ echo "Installing for secondary/slave"
+ apt-get -y install \
+ isc-dhcp-server \
+ bind9utils \
+ bind9
+fi
+
+echo "Dependency installation for ${ROLE} complete."
diff --git a/bootstrap/make-base-requires.sh b/bootstrap/make-base-requires.sh
new file mode 100755
index 0000000..ad40e73
--- /dev/null
+++ b/bootstrap/make-base-requires.sh
@@ -0,0 +1,75 @@
+#!/bin/bash
+
+set -e
+
+BASE="/etc";
+if [ "$1" != "" ]
+then
+ BASE=$1
+ echo "Using base path ${BASE}"
+fi
+
+source include/tgmanage.cfg.sh
+if [ -z ${PRIMARY} ]
+then
+ echo "Not configured!";
+ exit 1;
+fi;
+
+cd ~/tgmanage
+bootstrap/update-tools.sh
+ssh -l root ${PRIMARY} "~/tgmanage/bootstrap/install-dependencies.sh master"
+ssh -l root ${SECONDARY} "~/tgmanage/bootstrap/install-dependencies.sh slave"
+
+if [ "${BASE}" == "/etc" ]; then
+ ssh -l root ${PRIMARY} "cp -pR /etc/bind /etc/bind.dist"
+ ssh -l root ${PRIMARY} "cp -pR /etc/dhcp /etc/dhcp.dist"
+
+ ssh -l root ${SECONDARY} "cp -pR /etc/bind /etc/bind.dist"
+ ssh -l root ${SECONDARY} "cp -pR /etc/dhcp /etc/dhcp.dist"
+
+ set +e
+ ssh -l root ${PRIMARY} "rm /etc/bind/named.conf"
+ ssh -l root ${PRIMARY} "rm /etc/dhcp/dhcpd.conf"
+
+ ssh -l root ${SECONDARY} "rm /etc/dhcp/dhcpd.conf"
+ ssh -l root ${SECONDARY} "rm /etc/bind/named.conf"
+ set -e
+fi
+
+ssh -l root ${PRIMARY} "mkdir -p ${BASE}/bind/conf-master/"
+ssh -l root ${PRIMARY} "mkdir -p ${BASE}/bind/reverse/"
+ssh -l root ${PRIMARY} "mkdir -p ${BASE}/bind/dynamic/"
+ssh -l root ${PRIMARY} "mkdir -p ${BASE}/dhcp/conf.d/"
+
+ssh -l root ${PRIMARY} "~/tgmanage/bootstrap/make-dhcp6-init.sh"
+ssh -l root ${PRIMARY} "~/tgmanage/bootstrap/make-named.pl master ${BASE}"
+ssh -l root ${PRIMARY} "~/tgmanage/bootstrap/make-dhcpd.pl ${BASE}"
+ssh -l root ${PRIMARY} "~/tgmanage/bootstrap/make-first-zones.pl ${BASE}"
+ssh -l root ${PRIMARY} "~/tgmanage/bootstrap/make-reverse4-files.pl master ${BASE}"
+
+ssh -l root ${SECONDARY} "mkdir -p ${BASE}/dhcp/conf.d/"
+ssh -l root ${SECONDARY} "mkdir -p ${BASE}/bind/conf-slave/"
+ssh -l root ${SECONDARY} "mkdir -p ${BASE}/bind/slave/"
+
+ssh -l root ${SECONDARY} "~/tgmanage/bootstrap/make-dhcp6-init.sh"
+ssh -l root ${SECONDARY} "insserv -r isc-dhcp-server"
+ssh -l root ${SECONDARY} "~/tgmanage/bootstrap/make-dhcpd.pl ${BASE}"
+ssh -l root ${SECONDARY} "~/tgmanage/bootstrap/make-named.pl slave ${BASE}"
+ssh -l root ${SECONDARY} "~/tgmanage/bootstrap/make-reverse4-files.pl slave ${BASE}"
+
+set +e
+ssh -l root ${PRIMARY} "chown -R bind.bind ${BASE}/bind"
+ssh -l root ${SECONDARY} "chown -R bind.bind ${BASE}/bind"
+set -e
+
+ssh -l root ${PRIMARY} "echo THIS COPY OF TGMANAGE IS MANAGED FROM BOOTSTRAP SERVER > ~/tgmanage/NOTICE"
+ssh -l root ${SECONDARY} "echo THIS COPY OF TGMANAGE IS MANAGED FROM BOOTSTRAP SERVER > ~/tgmanage/NOTICE"
+
+# No point in _not_ running update-baseservice at this point....
+tools/update-baseservice.sh ${BASE}
+
+# Set up PXE environment. NOTE that we assume that TFTP-server is the ${SECONDARY} (changed from older behaviour)
+ssh -l root ${SECONDARY} "~/tgmanage/bootstrap/make-pxeboot.sh"
+
+# all done.
diff --git a/bootstrap/make-dhcp6-init.sh b/bootstrap/make-dhcp6-init.sh
new file mode 100755
index 0000000..468c973
--- /dev/null
+++ b/bootstrap/make-dhcp6-init.sh
@@ -0,0 +1,210 @@
+#!/bin/bash
+
+DHCP_DEFAULT="/etc/default/isc-dhcp-server"
+DHCP_INIT="/etc/init.d/isc-dhcp-server"
+
+if [ -e "${DHCP_DEFAULT}" ];
+then
+ echo "${DHCP_DEFAULT} exists!"
+ exit 1
+fi
+
+set -e
+
+cat > ${DHCP_DEFAULT}<<'_EOF'
+
+# Defaults for dhcp initscript
+
+# you can enable v4 and/or v6 protocols
+V4_ENABLED="yes"
+V6_ENABLED="yes"
+
+# On what interfaces should the DHCP server (dhcpd) serve DHCP requests?
+# Separate multiple interfaces with spaces, e.g. "eth0 eth1".
+INTERFACES_V4="eth0"
+INTERFACES_V6="eth0"
+_EOF
+
+set +e
+
+if [ -e "${DHCP_INIT}" ];
+then
+ echo "${DHCP_INIT} exists!"
+ exit 1
+fi
+
+set -e
+
+cat > ${DHCP_INIT}<<'_EOF'
+
+#!/bin/sh
+#
+#
+
+### BEGIN INIT INFO
+# Provides: isc-dhcp-server
+# Required-Start: $remote_fs $network $syslog
+# Required-Stop: $remote_fs $network $syslog
+# Should-Start: $local_fs slapd $named
+# Should-Stop: $local_fs slapd
+# Default-Start: 2 3 4 5
+# Default-Stop: 0 1 6
+# Short-Description: DHCP server
+# Description: Dynamic Host Configuration Protocol Server
+### END INIT INFO
+
+PATH=/sbin:/bin:/usr/sbin:/usr/bin
+
+test -f /usr/sbin/dhcpd || exit 0
+
+# It is not safe to start if we don't have a default configuration...
+if [ ! -f /etc/default/isc-dhcp-server ]; then
+ echo "/etc/default/isc-dhcp-server does not exist! - Aborting..."
+ echo "Run 'dpkg-reconfigure isc-dhcp-server' to fix the problem."
+ exit 0
+fi
+
+. /lib/lsb/init-functions
+
+# Read init script configuration (so far only interfaces the daemon
+# should listen on.)
+[ -f /etc/default/isc-dhcp-server ] && . /etc/default/isc-dhcp-server
+
+NAME=dhcpd
+DESC="DHCPv4"
+DHCPDPID=/var/run/dhcpd.pid
+
+NAME6=dhcpd6
+DESC6="DHCPv6"
+DHCPDPID6=/var/run/dhcpd6.pid
+
+
+# $1 -> version (-4 or -6)
+# $2 -> config file (usually /etc/dhcp/dhcpd.conf or /etc/dhcp/dhcpd6.conf)
+test_config()
+{
+ if ! /usr/sbin/dhcpd -t $1 -cf $2 -q > /dev/null 2>&1; then
+ echo "dhcpd self-test failed. Please fix the config file."
+ echo "The error was: "
+ /usr/sbin/dhcpd -t -6 -cf $2
+ exit 1
+ fi
+}
+
+# $1 -> -v for messages, -q for none
+# $2 -> PID file
+# $3 -> NAME
+check_status()
+{
+ if [ ! -r $2 ]; then
+ test "$1" != -v || echo "$3 is not running."
+ return 3
+ fi
+ if read pid < "$2" && ps -p "$pid" > /dev/null 2>&1; then
+ test "$1" != -v || echo "$3 is running."
+ return 0
+ else
+ test "$1" != -v || echo "$3 is not running but $2 exists."
+ return 1
+ fi
+}
+
+
+start_daemon()
+{
+ VERSION=$1
+ CONF_FILE=$2
+ PROCESS=$3
+ PIDFILE=$4
+ DESCRIPTION=$5
+
+ shift 5
+ INTERFACES=$*
+
+ test_config "$VERSION" "$CONF_FILE";
+ log_daemon_msg "Starting ISC $DESCRIPTION server" "$PROCESS";
+ start-stop-daemon --start --quiet --pidfile $PIDFILE \
+ --exec /usr/sbin/dhcpd -- $VERSION -q -cf $CONF_FILE \
+ $INTERFACES
+ sleep 2
+ if check_status -q $PIDFILE $NAME; then
+ log_end_msg 0
+ else
+ log_failure_msg "check syslog for diagnostics."
+ log_end_msg 1
+ exit 1
+ fi
+}
+
+stop_daemon()
+{
+ # Is DHCPv6 enabled? or daemon is runing ?
+ if test "$V6_ENABLED" = "yes" || check_status -q $DHCPDPID6 $NAME; then
+ log_daemon_msg "Stopping ISC DHCPv6 server" "$NAME6"
+ start-stop-daemon --stop --quiet --pidfile $DHCPDPID6
+ log_end_msg $?
+ rm -f "$DHCPDPID6"
+ fi
+
+ # Is DHCPv4 enabled or daemon is runing?
+ if test "$V4_ENABLED" = "yes" || check_status -q $DHCPDPID $NAME; then
+ log_daemon_msg "Stopping ISC DHCPv4 server" "$NAME"
+ start-stop-daemon --stop --quiet --pidfile $DHCPDPID
+ log_end_msg $?
+ rm -f "$DHCPDPID"
+ fi
+}
+
+
+case "$1" in
+ start)
+ # Is DHCPv6 enabled?
+ case "$V6_ENABLED" in
+ yes)
+ start_daemon "-6" "/etc/dhcp/dhcpd6.conf" \
+ $NAME6 $DHCPDPID6 $DESC6 $INTERFACES_V6
+ ;;
+ esac
+
+ # Is DHCPv4 enabled?
+ case "$V4_ENABLED" in
+ yes)
+ start_daemon "-4" "/etc/dhcp/dhcpd.conf" \
+ $NAME $DHCPDPID $DESC $INTERFACES_V4
+ ;;
+ esac
+
+ ;;
+ stop)
+ stop_daemon
+ ;;
+ restart | force-reload)
+ #test_config
+ $0 stop
+ sleep 2
+ $0 start
+ if [ "$?" != "0" ]; then
+ exit 1
+ fi
+ ;;
+ status)
+ echo -n "Status of $DESC: "
+ check_status -v $DHCPDPID $NAME
+ echo -n "Status of $DESC6: "
+ check_status -v $DHCPDPID6 $NAME6
+
+ exit "$?"
+ ;;
+ *)
+ echo "Usage: $0 {start|stop|restart|force-reload|status}"
+ exit 1
+esac
+
+exit 0
+
+_EOF
+
+set +e
+
+chmod 755 ${DHCP_INIT}
+
diff --git a/bootstrap/make-dhcpd.pl b/bootstrap/make-dhcpd.pl
new file mode 100755
index 0000000..d734c1d
--- /dev/null
+++ b/bootstrap/make-dhcpd.pl
@@ -0,0 +1,101 @@
+#!/usr/bin/perl -I /root/tgmanage
+use strict;
+
+use Net::IP;
+
+BEGIN {
+ require "include/config.pm";
+ eval {
+ require "include/config.local.pm";
+ };
+}
+
+my $base = "/etc";
+$base = $ARGV[0] if $#ARGV > -1;
+$base .= "/" if not $base =~ m/\/$/ and not $base eq "";
+
+my $dhcpd_base = $base . "dhcp/";
+my $dhcpd_conf = $dhcpd_base . "dhcpd.conf";
+my $dhcpd_pxeconf = $dhcpd_base . "pxe-boot.conf";
+my $dhcpd_wlc_conf= $dhcpd_base . "wlc-conf.conf";
+
+# primary
+my $pri_range = Net::IP->new($nms::config::pri_net) or die ("oopxos");
+my $pri_mask = $pri_range->mask();
+my $pri_net = $pri_range->ip();
+
+# secondary
+my $sec_range = Net::IP->new($nms::config::sec_net) or die ("oopxos");
+my $sec_mask = $sec_range->mask();
+my $sec_net = $sec_range->ip();
+
+# Create PXE-boot configuration file for DHCP on master.
+if ( not -f $dhcpd_conf )
+{
+ print STDERR "Creating file " . $dhcpd_conf . "\n";
+ open DHCPDFILE, ">" . $dhcpd_conf or die ( $! . " " . $dhcpd_conf);
+
+ print DHCPDFILE <<"EOF";
+# GENERATED BY make-dhcpd.pl
+#
+# Central concept: as little config in the main .conf,
+# include almost everything from separate files..
+#
+# log-facility local7;
+option domain-name "$nms::config::tgname.gathering.org";
+option domain-name-servers $nms::config::pri_v4, $nms::config::sec_v4;
+default-lease-time 3600;
+max-lease-time 7200;
+authoritative;
+
+ddns-update-style interim;
+key DHCP_UPDATER {
+ algorithm HMAC-MD5.SIG-ALG.REG.INT;
+ secret $nms::config::ddns_key;
+}
+
+subnet $pri_net netmask $pri_mask {}
+subnet $sec_net netmask $sec_mask {}
+
+include "/etc/dhcp/revzones.conf";
+include "/etc/dhcp/generated-include.conf";
+include "$dhcpd_pxeconf";
+include "$dhcpd_wlc_conf";
+
+EOF
+ close DHCPDFILE;
+}
+
+# Create PXE-boot configuration file for DHCP on master.
+if ( not -f $dhcpd_pxeconf )
+{
+ print STDERR "Creating file " . $dhcpd_pxeconf . "\n";
+ open PXEFILE, ">" . $dhcpd_pxeconf or die ( $! . " " . $dhcpd_pxeconf);
+
+ print PXEFILE "next-server " . $nms::config::pxe_server . ";\n";
+ print PXEFILE "filename \"pxelinux.0\";\n";
+
+ close PXEFILE;
+}
+
+
+# Create WLC configuration file
+if ( not -f $dhcpd_wlc_conf )
+{
+ print STDERR "Creating file " . $dhcpd_wlc_conf . "\n";
+ open WLCFILE, ">" . $dhcpd_wlc_conf or die ( $! . " " . $dhcpd_wlc_conf);
+
+ print WLCFILE <<"EOF";
+option space CiscoAP;
+option CiscoAP.server-address code 241 = array of ip-address;
+set vendor-string = option vendor-class-identifier;
+
+class "cisco-aps" {
+ match if substring (option vendor-class-identifier, 0, 8) = "Cisco AP";
+ vendor-option-space CiscoAP;
+ option CiscoAP.server-address $nms::config::wlc1;
+}
+EOF
+ close WLCFILE;
+}
+
diff --git a/bootstrap/make-first-zones.pl b/bootstrap/make-first-zones.pl
new file mode 100755
index 0000000..7d6d9f4
--- /dev/null
+++ b/bootstrap/make-first-zones.pl
@@ -0,0 +1,108 @@
+#!/usr/bin/perl -I /root/tgmanage
+use strict;
+
+use Net::IP;
+
+BEGIN {
+ require "include/config.pm";
+ eval {
+ require "include/config.local.pm";
+ };
+}
+
+my $base = "/etc";
+$base = $ARGV[0] if $#ARGV > -1;
+$base .= "/" if not $base =~ m/\/$/ and not $base eq "";
+
+my $serial = strftime("%Y%m%d", localtime(time())) . "01";
+
+my $zonefile;
+$zonefile = $base . "bind/" . $nms::config::tgname . ".gathering.org.zone";
+
+if ( not -f $zonefile )
+{
+ print $zonefile . "\n";
+ open MAINZONE, ">" . $zonefile or die $! . " " . $zonefile;
+
+ print MAINZONE <<"EOF";
+\$TTL 3600
+@ IN SOA $nms::config::pri_hostname.$nms::config::tgname.gathering.org. abuse.gathering.org. (
+ $serial; serial
+ 3600 ; refresh
+ 1800 ; retry
+ 608400 ; expire
+ 3600 ) ; minimum and default TTL
+
+ IN NS $nms::config::pri_hostname.$nms::config::tgname.gathering.org.
+ IN NS $nms::config::sec_hostname.$nms::config::tgname.gathering.org.
+
+$nms::config::pri_hostname IN A $nms::config::pri_v4
+$nms::config::pri_hostname IN AAAA $nms::config::pri_v6
+$nms::config::sec_hostname IN A $nms::config::sec_v4
+$nms::config::sec_hostname IN AAAA $nms::config::sec_v6
+ns1 IN CNAME $nms::config::pri_hostname.$nms::config::tgname.gathering.org.
+ns2 IN CNAME $nms::config::sec_hostname.$nms::config::tgname.gathering.org.
+
+; Generated by make-all-config.sh on the bootstrapping/nms server.
+; Will not be overwritten unless it is missing ;)
+
+EOF
+ close MAINZONE;
+}
+else { print "Skipped TG-zone, file exists.\n"; }
+
+$zonefile = $base . "bind/infra." . $nms::config::tgname . ".gathering.org.zone";
+if ( not -f $zonefile )
+{
+ print $zonefile . "\n";
+ open MAINZONE, ">" . $zonefile or die $! . " " . $zonefile;
+
+ print MAINZONE <<"EOF";
+\$TTL 3600
+@ IN SOA $nms::config::pri_hostname.$nms::config::tgname.gathering.org. abuse.gathering.org. (
+ $serial; serial
+ 3600 ; refresh
+ 1800 ; retry
+ 608400 ; expire
+ 3600 ) ; minimum and default TTL
+
+ IN NS $nms::config::pri_hostname.$nms::config::tgname.gathering.org.
+ IN NS $nms::config::sec_hostname.$nms::config::tgname.gathering.org.
+
+; Generated by make-all-config.sh on the bootstrapping/nms server.
+; Will not be overwritten unless it is missing ;)
+EOF
+ close MAINZONE;
+}
+else { print "Skipped infra-zone, file exists.\n"; }
+
+$zonefile = $base . "bind/" . $nms::config::ipv6zone . ".zone";
+if ( not -f $zonefile )
+{
+ print $zonefile . "\n";
+ open IPV6ZONE, ">" . $zonefile or die $! . " " . $zonefile;
+
+ print IPV6ZONE <<"EOF";
+; autogenerated, and updated from dhcpd -- DO NOT TOUCH!
+\$TTL 3600
+@ IN SOA $nms::config::pri_hostname.$nms::config::tgname.gathering.org. abuse.gathering.org. (
+ $serial; serial
+ 3600 ; refresh
+ 1800 ; retry
+ 608400 ; expire
+ 3600 ) ; minimum and default TTL
+
+ IN NS $nms::config::pri_hostname.$nms::config::tgname.gathering.org.
+ IN NS $nms::config::sec_hostname.$nms::config::tgname.gathering.org.
+
+; WARNING! Do not edit this file directly!
+; on the bootstrapping/nms server!
+
+EOF
+ my $ip_pri = new Net::IP( $nms::config::pri_v6 ) or die ( "Error, new Net::IP for " . $nms::config::pri_v6 );
+ my $ip_sec = new Net::IP( $nms::config::sec_v6 ) or die ( "Error, new Net::IP for " . $nms::config::sec_v6 );
+ print IPV6ZONE $ip_pri->reverse_ip() . " IN PTR $nms::config::pri_hostname.$nms::config::tgname.gathering.org.\n";
+ print IPV6ZONE $ip_sec->reverse_ip() . " IN PTR $nms::config::sec_hostname.$nms::config::tgname.gathering.org.\n";
+ close IPV6ZONE;
+}
+else { print "Skipped v6-reverse-zone, file exists.\n"; }
diff --git a/bootstrap/make-named.pl b/bootstrap/make-named.pl
new file mode 100755
index 0000000..a9ea02d
--- /dev/null
+++ b/bootstrap/make-named.pl
@@ -0,0 +1,129 @@
+#!/usr/bin/perl -I /root/tgmanage
+use strict;
+
+BEGIN {
+ require "include/config.pm";
+ eval {
+ require "include/config.local.pm";
+ };
+}
+
+
+use Net::IP;
+use Net::IP qw(:PROC);
+
+unless ( (($#ARGV == 0 ) || ( $#ARGV == 1))
+ && (( $ARGV[0] eq "master" ) || ( $ARGV[0] eq "slave" )) )
+{
+ print STDERR "Invalid usage!\ncat netnames.txt | $0 <master|slave> [basedir]\n";
+ exit 1;
+}
+
+my $role = $ARGV[0];
+
+my $base = "/etc";
+$base = $ARGV[1] if $#ARGV == 1;
+$base .= "/" if not $base =~ m/\/$/ and not $base eq "";
+
+my $bind_base = $base . "bind/";
+my $named_file = $bind_base . "named.conf";
+
+if ( -f $named_file )
+{
+ print STDERR $named_file . " already exists. Cowardly refusing to continue.\n";
+ exit;
+}
+
+my $run = `date +%Y%m%d-%H%M`;
+
+open NFILE, ">" . $named_file or die ( $! . " " . $named_file );
+
+chomp $run;
+print NFILE <<EOF;
+// This named.conf was generated by make-named.pl at $run
+// The current version of make-named.pl should not overwrite this file.
+acl tg-nett { $nms::config::base_ipv4net; $nms::config::base_ipv6net; $nms::config::extra_net; 127.0.0.0/8; ::1; };
+acl ns-xfr { $nms::config::sec_v4; $nms::config::sec_v6; $nms::config::pri_v4; $nms::config::pri_v6; $nms::config::noc_nett; };
+acl ext-xfr { $nms::config::ext_xfer; };
+
+options {
+ directory "/etc/bind";
+ allow-recursion { tg-nett; };
+ allow-query { any; };
+ allow-transfer { ns-xfr; };
+ recursion yes;
+ auth-nxdomain no;
+ listen-on-v6 { any; };
+};
+
+key DHCP_UPDATER {
+ algorithm HMAC-MD5.SIG-ALG.REG.INT;
+ secret $nms::config::ddns_key;
+};
+EOF
+
+if ( $role eq "master" )
+{
+ print NFILE <<EOF;
+
+zone "$nms::config::tgname.gathering.org" {
+ type master;
+ file "$nms::config::tgname.gathering.org.zone";
+ notify yes;
+ allow-transfer { ns-xfr; };
+};
+
+zone "infra.$nms::config::tgname.gathering.org" {
+ type master;
+ file "infra.$nms::config::tgname.gathering.org.zone";
+ notify yes;
+ allow-transfer { ns-xfr; };
+};
+
+zone "$nms::config::ipv6zone" {
+ type master;
+ allow-update { key DHCP_UPDATER; };
+ notify yes;
+ file "$nms::config::ipv6zone.zone";
+ allow-transfer { ns-xfr; ext-xfr; };
+};
+
+include "/etc/bind/named.conf.default-zones";
+include "named.reverse4.conf";
+include "named.master-include.conf";
+EOF
+}
+
+if ( $role eq "slave" )
+{
+ print NFILE <<EOF;
+
+masters master_ns { $nms::config::pri_v6; $nms::config::pri_v4; };
+
+zone "$nms::config::tgname.gathering.org" {
+ type slave;
+ file "slave/$nms::config::tgname.gathering.org";
+ notify no;
+ masters { master_ns; };
+};
+
+zone "infra.$nms::config::tgname.gathering.org" {
+ type slave;
+ file "slave/infra.$nms::config::tgname.gathering.org";
+ notify no;
+ masters { master_ns; };
+};
+
+zone "$nms::config::ipv6zone" {
+ type slave;
+ notify no;
+ masters { master_ns; };
+ file "slave/$nms::config::ipv6zone:";
+ allow-transfer { ns-xfr; ext-xfr; };
+};
+
+include "named.conf.default-zones";
+include "named.slave-reverse4.conf";
+include "named.slave-include.conf";
+EOF
+}
diff --git a/bootstrap/make-pxeboot.sh b/bootstrap/make-pxeboot.sh
new file mode 100755
index 0000000..4a9e271
--- /dev/null
+++ b/bootstrap/make-pxeboot.sh
@@ -0,0 +1,32 @@
+#!/bin/bash
+#
+# This tool is to be executed by make-base-requires.sh
+# From tg14 we assume that TFTP server/PXE-boot server
+# is the Secondary/SMTP/TFTP box.
+#
+# TODO: Either rewrite this to be run at/from the bootstrapper,
+# and/or add support for ${BASE} redirection..
+
+apt-get -y install tftpd-hpa
+apt-get -y install nfs-kernel-server
+
+cat << END > /etc/default/tftpd-hpa
+TFTP_USERNAME="tftp"
+TFTP_DIRECTORY="/var/lib/tftpboot"
+TFTP_ADDRESS="0.0.0.0:69"
+TFTP_OPTIONS="--secure"
+END
+
+/etc/init.d/tftpd-hpa restart
+
+mkdir -p /var/lib/tftpboot
+
+# NOTE, this step depends on an SCP of basic content from the bootstrap...
+# This should be done by bootstrap/update-tools ...
+cp -R ~/tgmanage/pxe/* /var/lib/tftpboot
+
+~/tgmanage/tools/fetch-debinstall.sh /var/lib/tftpboot/debian
+# tools/fetch-ubuntulive.sh <- this tool does not exist xD
+# NOTE! The pxe/ directory contains an 'ubuntu' menu...
+# The files required to booting Ubuntu installer or live
+# must be fetched manually (for now)
diff --git a/bootstrap/make-reverse4-files.pl b/bootstrap/make-reverse4-files.pl
new file mode 100755
index 0000000..bbb2d7c
--- /dev/null
+++ b/bootstrap/make-reverse4-files.pl
@@ -0,0 +1,153 @@
+#!/usr/bin/perl -I /root/tgmanage
+use strict;
+
+BEGIN {
+ require "include/config.pm";
+ eval {
+ require "include/config.local.pm";
+ };
+}
+
+
+use Net::IP;
+use Net::IP qw(:PROC);
+
+# FIXME: THIS IS NOT APPRORPIATE!
+my $serial = `date +%Y%m%d01`;
+chomp $serial;
+# FIXME
+
+unless ( (($#ARGV == 0 ) || ( $#ARGV == 1))
+ && (( $ARGV[0] eq "master" ) || ( $ARGV[0] eq "slave" )) )
+{
+ print STDERR "Invalid usage!\n$0 <master|slave> [basedir]\n";
+ exit 1;
+}
+
+my $role = $ARGV[0];
+
+my $base = "/etc";
+$base = $ARGV[1] if $#ARGV == 1;
+$base .= "/" if not $base =~ m/\/$/ and not $base eq "";
+
+
+my $bind_base = $base . "bind/";
+my $dhcpd_base = $base . "dhcp/";
+
+my $dhcp_revzones_file = $dhcpd_base . "revzones.conf";
+my $bind_pri_revzones_file = $bind_base . "named.reverse4.conf";
+my $bind_sec_revzones_file = $bind_base . "named.slave-reverse4.conf";
+
+my $tgname = $nms::config::tgname;
+
+my $pri_hostname = $nms::config::pri_hostname;
+my $pri_v4 = $nms::config::pri_v4;
+my $pri_v6 = $nms::config::pri_v6;
+
+my $sec_hostname = $nms::config::sec_hostname;
+my $sec_v4 = $nms::config::sec_v4;
+my $sec_v6 = $nms::config::sec_v6;
+
+my $ext_xfer = $nms::config::ext_xfer;
+
+my $ddns_key = $nms::config::ddns_key;
+
+my $ddns_to = $nms::config::ddns_to;
+
+my $base_ipv4 = new Net::IP( $nms::config::base_ipv4net );
+my ($p_oct, $s_oct, $t_oct) = ($nms::config::base_ipv4net =~ m/^(\d+)\.(\d+)\.(\d+)\..*/);
+
+$pri_v4 =~ m/^(\d+)\.(\d+)\.(\d+)\.(\d+).*/;
+my ( $pp_oct, $ps_oct, $pt_oct, $pf_oct) = ( $1, $2, $3, $4 );
+$sec_v4 =~ m/^(\d+)\.(\d+)\.(\d+)\.(\d+).*/;
+my ( $sp_oct, $ss_oct, $st_oct, $sf_oct) = ( $1, $2, $3, $4 );
+
+if ( $role eq "master" )
+{
+ open DFILE, ">" . $dhcp_revzones_file or die $!;
+ open NFILE, ">" . $bind_pri_revzones_file or die $!;
+}
+elsif ( $role eq "slave" )
+{
+ open SFILE, ">" . $bind_sec_revzones_file or die $!;
+}
+else
+{
+ die ("WTF, role is neither 'master' or 'slave'");
+}
+
+while (1)
+{
+
+ my $block = $p_oct . "." . $s_oct . "." . $t_oct . ".0/24";
+ my $current = new Net::IP( $block ) or die ("new Net::IP failed for " . $block);
+
+ my $rev_zone = $t_oct . "." . $s_oct . "." . $p_oct . ".in-addr.arpa";
+
+ if ( $role eq "master" )
+ {
+ # Generating IPv4-related reverse-stuff for
+ # both bind9 and dhcp on master.
+
+ print DFILE "zone " . $rev_zone . " { primary " . $ddns_to . "; key DHCP_UPDATER; }\n";
+
+ print NFILE "zone \"". $rev_zone ."\" {\n";
+ print NFILE " type master;\n";
+ print NFILE " allow-update { key DHCP_UPDATER; };\n";
+ print NFILE " notify yes;\n";
+ print NFILE " allow-transfer { $sec_v4; $ext_xfer; $nms::config::noc_nett; };\n";
+ print NFILE " file \"reverse/". $rev_zone .".zone\";\n";
+ print NFILE "};\n\n";
+
+ my $zfilename = $bind_base . "reverse/" . $rev_zone . ".zone";
+ open ZFILE, ">", $zfilename;
+
+ print ZFILE "; " . $zfilename . "\n";
+ print ZFILE <<"EOF";
+; Base reverse zones are updated from dhcpd -- DO NOT TOUCH!
+\$TTL 3600
+@ IN SOA $pri_hostname.$tgname.gathering.org. abuse.gathering.org. (
+ $serial ; serial
+ 3600 ; refresh
+ 1800 ; retry
+ 608400 ; expire
+ 3600 ) ; minimum and default TTL
+
+ IN NS $pri_hostname.$tgname.gathering.org.
+ IN NS $sec_hostname.$tgname.gathering.org.
+
+\$ORIGIN $rev_zone.
+EOF
+ if ( ($pt_oct == $t_oct) && ($ps_oct == $s_oct) )
+ {
+ print ZFILE $pf_oct . " IN PTR $pri_hostname.$tgname.gathering.org.\n";
+ }
+ if ( ($st_oct == $t_oct) && ($ss_oct == $s_oct) )
+ {
+ print ZFILE $sf_oct . " IN PTR $sec_hostname.$tgname.gathering.org.\n";
+ }
+ }
+ else
+ {
+ # AKA "if not master", as in "is slave".
+ # A lot less work: update the named.slave-reverse4.conf file..
+ print SFILE "zone \"". $rev_zone ."\" {\n";
+ print SFILE " type slave;\n";
+ print SFILE " notify no;\n";
+ print SFILE " file \"slave/". $rev_zone .".cache\";\n";
+ print SFILE " masters { bootstrap; };\n";
+ print SFILE " allow-transfer { $ext_xfer; $nms::config::noc_nett; };\n";
+ print SFILE "};\n\n";
+ }
+
+ if ( $current->last_int() == $base_ipv4->last_int() )
+ {
+ print STDERR "Reached last IP network. Finished\n";
+ last;
+ }
+ $t_oct++;
+}
+# Close all files, even those that have never been opened ;)
+close DFILE;
+close NFILE;
+close SFILE;
diff --git a/bootstrap/update-baseservice.sh b/bootstrap/update-baseservice.sh
new file mode 100755
index 0000000..94c3875
--- /dev/null
+++ b/bootstrap/update-baseservice.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+
+set -e
+
+BASE="";
+if [ -n $1 ]
+then
+ BASE=$1
+ echo "Using base path ${BASE}"
+fi
+
+source include/tgmanage.cfg.sh
+if [ -z ${PRIMARY} ]
+then
+ echo "Not configured!";
+ exit 1;
+fi;
+
+cat netlist.txt | ssh -l root ${PRIMARY} "~/tgmanage/tools/make-missing-conf.pl master ${BASE}"
+ssh -l root ${PRIMARY} "~/tgmanage/tools/make-dhcpd-include.pl ${BASE}"
+ssh -l root ${PRIMARY} "~/tgmanage/tools/make-bind-include.pl master ${BASE}"
+
+set +e
+ssh -l root ${PRIMARY} "chown bind.bind /etc/bind/dynamic/*.zone";
+set -e
+
+cat netlist.txt | ssh -l root ${SECONDARY} "~/tgmanage/tools/make-missing-conf.pl slave ${BASE}"
+ssh -l root ${SECONDARY} "~/tgmanage/tools/make-bind-include.pl slave ${BASE}"
+ssh -l root ${SECONDARY} "~/tgmanage/tools/make-dhcpd-include.pl ${BASE}"
diff --git a/bootstrap/update-tools.sh b/bootstrap/update-tools.sh
new file mode 100755
index 0000000..9878f8f
--- /dev/null
+++ b/bootstrap/update-tools.sh
@@ -0,0 +1,25 @@
+#!/bin/bash
+
+set -e
+
+source include/tgmanage.cfg.sh
+if [ -z ${PRIMARY} ]
+then
+ echo "Not configured!";
+ exit 1;
+fi;
+
+cd ~/tgmanage
+
+ssh -l root ${PRIMARY} "mkdir -p ~/tgmanage"
+ssh -l root ${SECONDARY} "mkdir -p ~/tgmanage"
+
+scp -r netlist.txt root@${PRIMARY}:tgmanage/
+scp -r tools root@${PRIMARY}:tgmanage/
+scp -r tools root@${SECONDARY}:tgmanage/
+scp -r include root@${PRIMARY}:tgmanage/
+scp -r include root@${SECONDARY}:tgmanage/
+
+export $TGNAME
+last_year=`perl -e '($y)=($ENV{TGNAME} =~ m/^tg(\d\d)$/); $y--; print "tg$y"'`
+scp -r examples/$last_year/pxe root@${SECONDARY}:tgmanage/