summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/README15
-rwxr-xr-xtools/batchadd.py168
-rwxr-xr-xtools/bcfg2-import-config10
-rwxr-xr-xtools/bcfg2-profile-templates.py138
-rwxr-xr-xtools/bcfg2_local.py44
-rwxr-xr-xtools/hostbase.py79
-rwxr-xr-xtools/hostbasepush.py14
-rwxr-xr-xtools/hostinfo.py197
-rwxr-xr-xtools/posixusers_baseline.py94
-rwxr-xr-xtools/selinux_baseline.py33
-rwxr-xr-x[-rw-r--r--]tools/upgrade/1.1/posixunified.py13
-rwxr-xr-xtools/upgrade/1.2/nagiosgen-convert.py15
-rwxr-xr-xtools/upgrade/1.2/packages-convert.py15
-rwxr-xr-xtools/upgrade/1.3/migrate_configs.py51
-rwxr-xr-xtools/upgrade/1.3/migrate_dbstats.py20
-rwxr-xr-xtools/upgrade/1.3/migrate_info.py26
-rwxr-xr-xtools/upgrade/1.3/migrate_perms_to_mode.py17
-rwxr-xr-xtools/upgrade/1.3/service_modes.py12
-rw-r--r--tools/upgrade/1.4/README14
-rwxr-xr-xtools/upgrade/1.4/convert_bundles.py32
-rwxr-xr-xtools/upgrade/1.4/migrate_decisions.py82
-rwxr-xr-xtools/upgrade/1.4/migrate_sslca.py44
22 files changed, 325 insertions, 808 deletions
diff --git a/tools/README b/tools/README
index 8fe2c1a28..6fc99bc6d 100644
--- a/tools/README
+++ b/tools/README
@@ -3,9 +3,6 @@ This directory contains repository maintenance tools.
basebuilder.py <image directory>
- builds v2 base.xml from bcfg1 repo
-batchadd.py <filename>
- - Add records to Hostbase
-
bcfg2-completion.bash
- Bash tab completion for bcfg2-admin
@@ -20,9 +17,6 @@ bcfg2_local.py
- Perform a full Bcfg2 run against a local repository instead of
against a remote server
-bcfg2-profile-templates.py [<template>]
- - Benchmark template rendering times
-
bcfg2_svnlog.py
- Send intelligent log messages about changes made to your Bcfg2
repository from SVN postcommit
@@ -64,15 +58,6 @@ generate-manpages.bash
git_commit.py
- Trigger script to commit local changes back to a git repository
-hostbasepush.py
- - Call the Hostbase.rebuildState XML-RPC method
-
-hostbase.py {-l|-c} <hostname>
- - Display or create host information for Hostbase
-
-hostinfo.py {-q <query>|--showfields}
- - Query the hostbase databse
-
pkgmgr_gen.py
- Generate Pkgmgr XML files from a list of directories that
contain RPMS
diff --git a/tools/batchadd.py b/tools/batchadd.py
deleted file mode 100755
index e8008b330..000000000
--- a/tools/batchadd.py
+++ /dev/null
@@ -1,168 +0,0 @@
-#!/usr/bin/python
-
-from datetime import date
-import os
-import sys
-
-os.environ['DJANGO_SETTINGS_MODULE'] = 'Bcfg2.Server.Hostbase.settings'
-from Bcfg2.Server.Hostbase.hostbase.models import *
-from Bcfg2.Server.Hostbase.settings import DEFAULT_MX, PRIORITY
-import Bcfg2.Server.Hostbase.regex
-
-host_attribs = ['administrator',
- 'comments',
- 'csi',
- 'expiration_date',
- 'hostname',
- 'location',
- 'netgroup',
- 'outbound_smtp',
- 'primary_user',
- 'printq',
- 'security_class',
- 'support',
- 'whatami']
-
-
-def handle_error(field):
- if '-f' in sys.argv:
- return
- print("Error: %s is already defined in hostbase" % field)
- if '-s' in sys.argv:
- sys.exit(1)
-
-
-def checkformat(values, indices):
- """Ensures file contains all necessary attributes in order """
- filelist = [pair[0] for pair in values]
-
- # lines = len(filelist)
-
- filelist = filelist[indices[0]:]
-
- for index in indices:
- if filelist[0:13] != host_attribs:
- # figure out what to do here
- return False
- else:
- # process rest of host attributes
- try:
- next = filelist[1:].index('hostname')
- remaining = filelist[13:next + 1]
- filelist = filelist[next + 1:]
- except:
- remaining = filelist[13:]
- needfields = ['mac_addr', 'hdwr_type', 'ip_addr']
- if [item for item in needfields if item not in remaining]:
- return False
- return True
-
-
-if __name__ == '__main__':
-
- # argument handling for batchadd
- try:
- fd = open(sys.argv[1], 'r')
- except (IndexError, IOError):
- print("\nUsage: batchadd.py filename\n")
- sys.exit()
-
- lines = fd.readlines()
- # splits and strips lines into (attribute, value)
- info = [[item.strip() for item in line.split("->")] for line in lines
- if line.lstrip(' ')[0] != '#' and line != '\n']
-
- if info[0][0] == 'mx' and info[1][0] == 'priority':
- mx, created = MX.objects.get_or_create(mx=info[0][1],
- priority=info[1][1])
- info = info[2:]
- else:
- mx, created = MX.objects.get_or_create(mx=DEFAULT_MX,
- priority=PRIORITY)
- if created:
- mx.save()
-
- hostindices = [num for num in range(0, len(info))
- if info[num][0] == 'hostname']
-
- if not checkformat(info, hostindices):
- print("Error: file format")
- sys.exit()
-
-#################
-
- for host in hostindices:
- try:
- host = Host.objects.get(hostname=info[host][1])
- handle_error(info[host][1])
- except:
- # do something here
- pass
-
- macindices = [num for num in range(0, len(info))
- if info[num][0] == 'mac_addr']
- for mac_addr in macindices:
- try:
- host = Interface.objects.get(mac_addr=info[mac_addr][1])
- handle_error(info[mac_addr][1])
- except:
- # do something here
- pass
-
- for host in hostindices:
- blank = Host()
- for attrib in host_attribs:
- pair = info.pop(0)
- if pair[0] == 'outbound_smtp':
- if pair[1] == 'y':
- blank.__dict__[pair[0]] = 1
- else:
- blank.__dict__[pair[0]] = 0
- elif pair[0] == 'expiration_date':
- (year, month, day) = pair[1].split("-")
- blank.expiration_date = date(int(year),
- int(month),
- int(day))
- else:
- blank.__dict__[pair[0]] = pair[1]
- blank.status = 'active'
- blank.save()
- newhostname = blank.hostname.split(".")[0]
- newdomain = blank.hostname.split(".", 1)[1]
- while info and info[0][0] != 'hostname':
- if info[0][0] == 'mac_addr':
- pair = info.pop(0)
- inter = Interface.objects.create(host=blank,
- mac_addr=pair[1],
- hdwr_type='eth')
- if not pair[1]:
- inter.dhcp = False
- inter.save()
- elif info[0][0] == 'hdwr_type':
- pair = info.pop(0)
- inter.hdwr_type = pair[1]
- inter.save()
- elif info[0][0] == 'ip_addr':
- pair = info.pop(0)
- ip = IP.objects.create(interface=inter, ip_addr=pair[1])
- hostnamenode = Name(ip=ip,
- name=blank.hostname,
- dns_view='global',
- only=False)
- hostnamenode.save()
- namenode = Name(ip=ip,
- name=".".join([newhostname + "-" + inter.hdwr_type,
- newdomain]),
- dns_view="global", only=False)
- namenode.save()
- subnetnode = Name(ip=ip, name=newhostname + "-" +
- ip.ip_addr.split(".")[2] + "." +
- newdomain, dns_view="global", only=False)
- subnetnode.save()
- hostnamenode.mxs.add(mx)
- namenode.mxs.add(mx)
- subnetnode.mxs.add(mx)
- elif info[0][0] == 'cname':
- pair = info.pop(0)
- cname = CName.objects.create(name=hostnamenode, cname=pair[1])
- cname.save()
diff --git a/tools/bcfg2-import-config b/tools/bcfg2-import-config
index d6273f0c6..fec007e7e 100755
--- a/tools/bcfg2-import-config
+++ b/tools/bcfg2-import-config
@@ -11,7 +11,6 @@
usage() {
echo "$0: tool to import files in to bcfg2-server repository"
echo " -s Copy SSH Key files"
- echo " -p Create :info files with current file permissions"
echo " -n No suffix. Generate global files"
echo " --debian Run debsums to detect changed configuration files"
echo " ** debsums is only able to detect part of changes!"
@@ -28,7 +27,6 @@ eval set -- "$TEMP"
## Start Defaults
NEEDSSH=0
-NEEDPERM=0
DEBSUMS=0
NOSUFFIX=0
# End Defaults
@@ -37,7 +35,6 @@ NOSUFFIX=0
while true ; do
case "$1" in
-s) NEEDSSH=1; shift ;;
- -p) NEEDPERM=1; shift ;;
--debian) DEBSUMS=1; shift ;;
-n) NOSUFFIX=1; shift ;;
-h|--help)
@@ -102,11 +99,6 @@ get_files() {
FILE=$(basename $i)
mkdir -p $CFGREPO/$i
cp $i $CFGREPO/$i/${FILE}${SUFFIX}
- if [ $NEEDPERM -ne 0 ]; then
- # Get permissions for the file
- echo -n "(permissions) "
- find $i -printf "owner:%u\ngroup:%g\nperms:%#m\n" > "$CFGREPO/$i/:info"
- fi
echo "OK"
else
echo "$i: Not a file"
@@ -126,7 +118,7 @@ get_debsums() {
}
## End Functions
-if [ $(($NEEDPERM + $NEEDSSH + $DEBSUMS)) -eq 0 -a -z "$FILES" ]; then usage ; exit 0; fi
+if [ $(($NEEDSSH + $DEBSUMS)) -eq 0 -a -z "$FILES" ]; then usage ; exit 0; fi
init_temp_repo
get_debsums
diff --git a/tools/bcfg2-profile-templates.py b/tools/bcfg2-profile-templates.py
deleted file mode 100755
index 2b0ca6d63..000000000
--- a/tools/bcfg2-profile-templates.py
+++ /dev/null
@@ -1,138 +0,0 @@
-#!/usr/bin/python -Ott
-# -*- coding: utf-8 -*-
-""" Benchmark template rendering times """
-
-import sys
-import time
-import math
-import signal
-import logging
-import operator
-import Bcfg2.Logger
-import Bcfg2.Options
-import Bcfg2.Server.Core
-
-
-def stdev(nums):
- mean = float(sum(nums)) / len(nums)
- return math.sqrt(sum((n - mean)**2 for n in nums) / float(len(nums)))
-
-
-def get_sigint_handler(core):
- """ Get a function that handles SIGINT/Ctrl-C by shutting down the
- core and exiting properly."""
-
- def hdlr(sig, frame): # pylint: disable=W0613
- """ Handle SIGINT/Ctrl-C by shutting down the core and exiting
- properly. """
- core.shutdown()
- os._exit(1) # pylint: disable=W0212
-
- return hdlr
-
-
-def main():
- optinfo = dict(
- client=Bcfg2.Options.Option("Benchmark templates for one client",
- cmd="--client",
- odesc="<client>",
- long_arg=True,
- default=None),
- runs=Bcfg2.Options.Option("Number of rendering passes per template",
- cmd="--runs",
- odesc="<runs>",
- long_arg=True,
- default=5,
- cook=int))
- optinfo.update(Bcfg2.Options.CLI_COMMON_OPTIONS)
- optinfo.update(Bcfg2.Options.SERVER_COMMON_OPTIONS)
- setup = Bcfg2.Options.OptionParser(optinfo)
- setup.parse(sys.argv[1:])
-
- if setup['debug']:
- level = logging.DEBUG
- elif setup['verbose']:
- level = logging.INFO
- else:
- level = logging.WARNING
- Bcfg2.Logger.setup_logging("bcfg2-test",
- to_console=setup['verbose'] or setup['debug'],
- to_syslog=False,
- to_file=setup['logging'],
- level=level)
- logger = logging.getLogger(sys.argv[0])
-
- core = Bcfg2.Server.Core.BaseCore(setup)
- signal.signal(signal.SIGINT, get_sigint_handler(core))
- logger.info("Bcfg2 server core loaded")
- core.load_plugins()
- logger.debug("Plugins loaded")
- core.block_for_fam_events(handle_events=True)
- logger.debug("Repository events processed")
-
- if setup['args']:
- templates = setup['args']
- else:
- templates = []
-
- if setup['client'] is None:
- clients = [core.build_metadata(c) for c in core.metadata.clients]
- else:
- clients = [core.build_metadata(setup['client'])]
-
- times = dict()
- client_count = 0
- for metadata in clients:
- client_count += 1
- logger.info("Rendering templates for client %s (%s/%s)" %
- (metadata.hostname, client_count, len(clients)))
- structs = core.GetStructures(metadata)
- struct_count = 0
- for struct in structs:
- struct_count += 1
- logger.info("Rendering templates from structure %s:%s (%s/%s)" %
- (struct.tag, struct.get("name"), struct_count,
- len(structs)))
- entries = struct.xpath("//Path")
- entry_count = 0
- for entry in entries:
- entry_count += 1
- if templates and entry.get("name") not in templates:
- continue
- logger.info("Rendering Path:%s (%s/%s)..." %
- (entry.get("name"), entry_count, len(entries)))
- ptimes = times.setdefault(entry.get("name"), [])
- for i in range(setup['runs']):
- start = time.time()
- try:
- core.Bind(entry, metadata)
- ptimes.append(time.time() - start)
- except:
- break
- if ptimes:
- avg = sum(ptimes) / len(ptimes)
- if avg:
- logger.debug(" %s: %.02f sec" %
- (metadata.hostname, avg))
-
- # print out per-file results
- tmpltimes = []
- for tmpl, ptimes in times.items():
- try:
- mean = float(sum(ptimes)) / len(ptimes)
- except ZeroDivisionError:
- continue
- ptimes.sort()
- median = ptimes[len(ptimes) / 2]
- std = stdev(ptimes)
- if mean > 0.01 or median > 0.01 or std > 1 or templates:
- tmpltimes.append((tmpl, mean, median, std))
- print("%-50s %-9s %-11s %6s" %
- ("Template", "Mean Time", "Median Time", "σ"))
- for info in reversed(sorted(tmpltimes, key=operator.itemgetter(1))):
- print("%-50s %9.02f %11.02f %6.02f" % info)
- core.shutdown()
-
-
-if __name__ == "__main__":
- sys.exit(main())
diff --git a/tools/bcfg2_local.py b/tools/bcfg2_local.py
index 3c90a3ea5..21b5ad8d4 100755
--- a/tools/bcfg2_local.py
+++ b/tools/bcfg2_local.py
@@ -6,19 +6,19 @@ the server core, then uses that to get probes, run them, and so on."""
import sys
import socket
import Bcfg2.Options
-from Bcfg2.Client.Client import Client
-from Bcfg2.Server.Core import BaseCore
+from Bcfg2.Client import Client
+from Bcfg2.Server.Core import Core
-class LocalCore(BaseCore):
+class LocalCore(Core):
""" Local server core similar to the one started by bcfg2-info """
- def __init__(self, setup):
- saved = (setup['syslog'], setup['logging'])
- setup['syslog'] = False
- setup['logging'] = None
- Bcfg2.Server.Core.BaseCore.__init__(self, setup=setup)
- setup['syslog'], setup['logging'] = saved
+ def __init__(self):
+ #saved = (setup['syslog'], setup['logging'])
+ #setup['syslog'] = False
+ #setup['logging'] = None
+ Bcfg2.Server.Core.BaseCore.__init__(self)
+ #setup['syslog'], setup['logging'] = saved
self.load_plugins()
self.block_for_fam_events(handle_events=True)
@@ -57,26 +57,22 @@ class LocalClient(Client):
""" A version of the Client class that uses LocalProxy instead of
an XML-RPC proxy to make its calls """
- def __init__(self, setup, proxy):
- Client.__init__(self, setup)
+ def __init__(self, proxy):
+ Client.__init__(self)
self._proxy = proxy
def main():
- optinfo = Bcfg2.Options.CLIENT_COMMON_OPTIONS
- optinfo.update(Bcfg2.Options.SERVER_COMMON_OPTIONS)
- if 'bundle_quick' in optinfo:
- # CLIENT_BUNDLEQUICK option uses -Q, just like the server repo
- # option. the server repo is more important for this
- # application.
- optinfo['bundle_quick'] = Bcfg2.Options.Option('bundlequick',
- default=False)
- setup = Bcfg2.Options.OptionParser(optinfo)
- setup.parse(sys.argv[1:])
-
- core = LocalCore(setup)
+ parser = Bcfg2.Options.Parser(
+ description="Run a Bcfg2 client against a local repository without a "
+ "server",
+ conflict_handler="resolve",
+ components=[LocalCore, LocalProxy, LocalClient])
+ parser.parse()
+
+ core = LocalCore()
try:
- LocalClient(setup, LocalProxy(core)).run()
+ LocalClient(LocalProxy(core)).run()
finally:
core.shutdown()
diff --git a/tools/hostbase.py b/tools/hostbase.py
deleted file mode 100755
index 7474e68b7..000000000
--- a/tools/hostbase.py
+++ /dev/null
@@ -1,79 +0,0 @@
-#!/usr/bin/python
-import os
-from getopt import getopt, GetoptError
-from re import split
-import sys
-
-os.environ['DJANGO_SETTINGS_MODULE'] = 'Hostbase.settings'
-from Hostbase.hostbase.models import Host
-
-attribs = ['administrator',
- 'comments',
- 'csi',
- 'dhcp',
- 'expiration_date',
- 'hostname',
- 'last',
- 'location',
- 'netgroup',
- 'outbound_smtp',
- 'primary_user',
- 'printq',
- 'security_class',
- 'support',
- 'status',
- 'whatami']
-
-already_exists = None
-#here's my attempt at making the command line idiot proof
-#you must supply and arugument and hostname for hostbase.py to run
-try:
- (opts, args) = getopt(sys.argv[1:], 'l:c:')
- sys.argv[1]
- if len(split("\.", opts[0][1])) == 1:
- hosttouse = opts[0][1] + ".mcs.anl.gov"
- else:
- hosttouse = opts[0][1]
-except (GetoptError, IndexError):
- print("\nUsage: hostbase.py -flag (hostname)\n")
- print("Flags:")
- print("\t-l look (hostname)\n")
-# print("\t-c copy (hostname)\n")
- sys.exit()
-
-try:
- host = Host.objects.get(hostname=hosttouse)
-except:
- print("Error: host %s not in hostbase" % hosttouse)
- sys.exit(1)
-interfaces = []
-for interface in host.interface_set.all():
- interfaces.append([interface, interface.ip_set.all()])
-hostinfo = "\n"
-for attrib in attribs:
- if not (opts[0][0] == '-c' and attrib in ['status', 'last']):
- if attrib == 'dhcp' or attrib == 'outbound_smtp':
- if host.__dict__[attrib]:
- hostinfo += "%-32s-> %s\n" % (attrib, 'y')
- else:
- hostinfo += "%-32s-> %s\n" % (attrib, 'n')
- else:
- hostinfo += "%-32s-> %s\n" % (attrib, host.__dict__[attrib])
-for interface in interfaces:
- hostinfo += "\n%-32s-> %s\n" % ('mac_addr', interface[0].mac_addr)
- hostinfo += "%-32s-> %s\n" % ('hdwr_type', interface[0].hdwr_type)
- for ip in interface[1]:
- hostinfo += "%-32s-> %s\n" % ('ip_addr', ip.ip_addr)
-
-if opts[0][0] == '-l':
- """Displays general host information"""
- print(hostinfo)
-
-if opts[0][0] == '-c':
- """Provides pre-filled template to copy a host record"""
- fd = open('/tmp/hostbase.%s.tmp' % host.id, 'w')
- fd.write(hostinfo)
- fd.close()
- os.system('vi + /tmp/hostbase.%s.tmp' % host.id)
- os.system('batchadd.py /tmp/hostbase.%s.tmp' % host.id)
- os.system('rm /tmp/hostbase.%s.tmp' % host.id)
diff --git a/tools/hostbasepush.py b/tools/hostbasepush.py
deleted file mode 100755
index 02b7a582f..000000000
--- a/tools/hostbasepush.py
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/usr/bin/python
-
-import os
-import Bcfg2.Client.Proxy
-
-if not os.getuid() == 0:
- print("this command must be run as root")
- raise SystemExit
-
-proxy = Bcfg2.Client.Proxy.bcfg2()
-print("building files...")
-proxy.run_method('Hostbase.rebuildState', ())
-print("running bcfg...")
-os.system('bcfg2 -q -d -v')
diff --git a/tools/hostinfo.py b/tools/hostinfo.py
deleted file mode 100755
index 8ae5c4df6..000000000
--- a/tools/hostinfo.py
+++ /dev/null
@@ -1,197 +0,0 @@
-#!/usr/bin/python
-"""Hostinfo queries the hostbase database according to user-defined data"""
-
-from os import system, environ
-environ['DJANGO_SETTINGS_MODULE'] = 'Hostbase.settings'
-from getopt import gnu_getopt, GetoptError
-from django.db import connection
-import sys
-
-logic_ops = ["and", "or"]
-host_attribs = ["hostname", "whatami", "netgroup", "security_class",
- "support", "csi", "memory", "printq", "dhcp", "outbound_smtp",
- "primary_user", "administrator", "location",
- "comments", "last", "expiration_date"]
-dispatch = {'mac_addr': ' i.',
- 'hdwr_type': ' i.',
- 'ip_addr': ' p.',
- 'name': ' n.',
- 'dns_view': ' n.',
- 'cname': ' c.',
- 'mx': ' m.',
- 'priority': ' m.'}
-
-
-def pinger(hosts):
- """Function that uses fping to ping multiple hosts in parallel"""
- hostnames = ""
- for each in hosts:
- hostnames += each[0] + " "
- system("fping -r 1" + hostnames)
- sys.exit()
-
-
-def get_query(arguments):
- """Parses the command line options and returns the necessary
- data for an SQL query"""
- logic = None
- resultset = []
- querystring = ''
- while 1:
- notflag = False
- if arguments[0] == 'not':
- notflag = True
- querypos = 1
- elif arguments[0] in logic_ops:
- logic = arguments[0]
- if arguments[1] == 'not':
- notflag = True
- querypos = 2
- else:
- querypos = 1
- else:
- querypos = 0
- if len(arguments[querypos].split("==")) > 1:
- operator = "="
- if notflag:
- operator = "<>"
- querysplit = arguments[querypos].split("==")
- if querysplit[0] in host_attribs:
- querystring = " h.%s%s\'%s\'" % (querysplit[0],
- operator,
- querysplit[1])
- elif querysplit[0] in dispatch:
- querystring = dispatch[querysplit[0]]
- querystring += "%s%s\'%s\'" % (querysplit[0],
- operator,
- querysplit[1])
- elif len(arguments[querypos].split("=")) > 1:
- notstring = ''
- if notflag:
- notstring = 'NOT '
- querysplit = arguments[querypos].split("=")
- if querysplit[0] in host_attribs:
- querystring = " h.%s %sLIKE \'%%%%%s%%%%\'" % (querysplit[0],
- notstring,
- querysplit[1])
- elif querysplit[0] in dispatch:
- querystring = dispatch[querysplit[0]]
- querystring += "%s %sLIKE \'%%%%%s%%%%\'" % (querysplit[0],
- notstring,
- querysplit[1])
- else:
- print("ERROR: bad query format")
- sys.exit()
- if not querystring:
- print("ERROR: bad query format")
- sys.exit()
- resultset.append((querystring, logic))
- arguments = arguments[querypos + 1:]
- if arguments == [] or arguments[0] not in logic_ops:
- break
- return resultset
-
-try:
- (opts, args) = gnu_getopt(sys.argv[1:],
- 'q:', ['showfields', 'fields', 'ping', 'summary'])
- cursor = connection.cursor()
- if ('--showfields', '') in opts:
- print("\nhost fields:\n")
- for field in host_attribs:
- print(field)
- for field in dispatch:
- print(field)
- print("")
- sys.exit()
- if opts[0][0] == '-q':
- results = get_query(sys.argv[2:])
- queryoptions = ""
- for result in results:
- if result[1] == 'and':
- queryoptions += " AND " + result[0]
- elif result[1] == 'or':
- queryoptions += " OR " + result[0]
- else:
- queryoptions += result[0]
- if ('--summary', '') in opts:
- fields = "h.hostname, h.whatami, h.location, h.primary_user"
- query = """SELECT DISTINCT %s FROM (((((hostbase_host h
- INNER JOIN hostbase_interface i ON h.id = i.host_id)
- INNER JOIN hostbase_ip p ON i.id = p.interface_id)
- INNER JOIN hostbase_name n ON p.id = n.ip_id)
- INNER JOIN hostbase_name_mxs x ON x.name_id = n.id)
- INNER JOIN hostbase_mx m ON m.id = x.mx_id)
- LEFT JOIN hostbase_cname c ON n.id = c.name_id
- WHERE %s ORDER BY h.hostname
- """ % (fields, queryoptions)
- cursor.execute(query)
- results = cursor.fetchall()
- if not results:
- print("No matches were found for your query")
- sys.exit()
- print("\n%-32s %-10s %-10s %-10s" % ('Hostname', 'Type', 'Location', 'User'))
- print("================================ ========== ========== ==========")
- for host in results:
- print("%-32s %-10s %-10s %-10s" % (host))
- print("")
- elif ('--fields', '') in opts:
- tolook = [arg for arg in args if arg in host_attribs or arg in dispatch]
- fields = ""
- fields = ", ".join(tolook)
- if not fields:
- print("No valid fields were entered. exiting...")
- sys.exit()
- query = """SELECT DISTINCT %s FROM (((((hostbase_host h
- INNER JOIN hostbase_interface i ON h.id = i.host_id)
- INNER JOIN hostbase_ip p ON i.id = p.interface_id)
- INNER JOIN hostbase_name n ON p.id = n.ip_id)
- INNER JOIN hostbase_name_mxs x ON x.name_id = n.id)
- INNER JOIN hostbase_mx m ON m.id = x.mx_id)
- LEFT JOIN hostbase_cname c ON n.id = c.name_id
- WHERE %s ORDER BY h.hostname
- """ % (fields, queryoptions)
-
- cursor.execute(query)
- results = cursor.fetchall()
-
- last = results[0]
- for field in results[0]:
- print(repr(field) + "\t")
- for host in results:
- if not host == last:
- for field in host:
- print(repr(field) + "\t")
- last = host
- print("")
- else:
- basequery = """SELECT DISTINCT h.hostname FROM (((((hostbase_host h
- INNER JOIN hostbase_interface i ON h.id = i.host_id)
- INNER JOIN hostbase_ip p ON i.id = p.interface_id)
- INNER JOIN hostbase_name n ON p.id = n.ip_id)
- INNER JOIN hostbase_name_mxs x ON x.name_id = n.id)
- INNER JOIN hostbase_mx m ON m.id = x.mx_id)
- LEFT JOIN hostbase_cname c ON n.id = c.name_id
- WHERE
- """
- cursor.execute(basequery + queryoptions + " ORDER BY h.hostname")
- results = cursor.fetchall()
-
- if not results:
- print("No matches were found for your query")
- sys.exit()
-
- if ("--ping", '') in opts:
- pinger(results)
-
- for host in results:
- print(host[0])
-
-
-except (GetoptError, IndexError):
- print("\nUsage: hostinfo.py -q <field>=[=]<value> [and/or <field>=<value> [--long option]]")
- print(" hostinfo.py --showfields\tshows all data fields")
- print("\n long options:")
- print("\t --fields f1 f2 ...\tspecifies the fields displayed from the queried hosts")
- print("\t --summary\t\tprints out a predetermined set of fields")
- print("\t --ping\t\t\tuses fping to ping all queried hosts\n")
- sys.exit()
diff --git a/tools/posixusers_baseline.py b/tools/posixusers_baseline.py
index c45e54f1a..1f89c7cb6 100755
--- a/tools/posixusers_baseline.py
+++ b/tools/posixusers_baseline.py
@@ -2,72 +2,46 @@
import grp
import sys
-import logging
import lxml.etree
import Bcfg2.Logger
+import Bcfg2.Options
from Bcfg2.Client.Tools.POSIXUsers import POSIXUsers
-from Bcfg2.Options import OptionParser, Option, get_bool, CLIENT_COMMON_OPTIONS
-def get_setup():
- optinfo = CLIENT_COMMON_OPTIONS
- optinfo['nouids'] = Option("Do not include UID numbers for users",
- default=False,
- cmd='--no-uids',
- long_arg=True,
- cook=get_bool)
- optinfo['nogids'] = Option("Do not include GID numbers for groups",
- default=False,
- cmd='--no-gids',
- long_arg=True,
- cook=get_bool)
- setup = OptionParser(optinfo)
- setup.parse(sys.argv[1:])
+class CLI(object):
+ options = [
+ Bcfg2.Options.BooleanOption(
+ "--no-uids", help="Do not include UID numbers for users"),
+ Bcfg2.Options.BooleanOption(
+ "--no-gids", help="Do not include GID numbers for groups")]
- if setup['args']:
- print("posixuser_[baseline.py takes no arguments, only options")
- print(setup.buildHelpMessage())
- raise SystemExit(1)
- level = 30
- if setup['verbose']:
- level = 20
- if setup['debug']:
- level = 0
- Bcfg2.Logger.setup_logging('posixusers_baseline.py',
- to_syslog=False,
- level=level,
- to_file=setup['logging'])
- return setup
-
-
-def main():
- setup = get_setup()
- if setup['file']:
- config = lxml.etree.parse(setup['file']).getroot()
- else:
+ def __init__(self):
+ Bcfg2.Options.get_parser(
+ description="Generate a bundle with a baseline of POSIX users and "
+ "groups",
+ components=[self, POSIXUsers]).parse()
config = lxml.etree.Element("Configuration")
- users = POSIXUsers(logging.getLogger('posixusers_baseline.py'),
- setup, config)
-
- baseline = lxml.etree.Element("Bundle", name="posixusers_baseline")
- for entry in users.FindExtra():
- data = users.existing[entry.tag][entry.get("name")]
- for attr, idx in users.attr_mapping[entry.tag].items():
- if (entry.get(attr) or
- (attr == 'uid' and setup['nouids']) or
- (attr == 'gid' and setup['nogids'])):
- continue
- entry.set(attr, str(data[idx]))
- if entry.tag == 'POSIXUser':
- entry.set("group", grp.getgrgid(data[3])[0])
- for group in users.user_supplementary_groups(entry):
- memberof = lxml.etree.SubElement(entry, "MemberOf",
- group=group[0])
-
- entry.tag = "Bound" + entry.tag
- baseline.append(entry)
-
- print(lxml.etree.tostring(baseline, pretty_print=True))
+ self.users = POSIXUsers(config)
+
+ def run(self):
+ baseline = lxml.etree.Element("Bundle", name="posixusers_baseline")
+ for entry in self.users.FindExtra():
+ data = self.users.existing[entry.tag][entry.get("name")]
+ for attr, idx in self.users.attr_mapping[entry.tag].items():
+ if (entry.get(attr) or
+ (attr == 'uid' and Bcfg2.Options.setup.no_uids) or
+ (attr == 'gid' and Bcfg2.Options.setup.no_gids)):
+ continue
+ entry.set(attr, str(data[idx]))
+ if entry.tag == 'POSIXUser':
+ entry.set("group", grp.getgrgid(data[3])[0])
+ for group in self.users.user_supplementary_groups(entry):
+ lxml.etree.SubElement(entry, "MemberOf", group=group[0])
+
+ entry.tag = "Bound" + entry.tag
+ baseline.append(entry)
+
+ print(lxml.etree.tostring(baseline, pretty_print=True))
if __name__ == "__main__":
- sys.exit(main())
+ sys.exit(CLI().run())
diff --git a/tools/selinux_baseline.py b/tools/selinux_baseline.py
index 507a16f43..ad2a40426 100755
--- a/tools/selinux_baseline.py
+++ b/tools/selinux_baseline.py
@@ -1,41 +1,18 @@
#!/usr/bin/env python
import sys
-import logging
import lxml.etree
-
import Bcfg2.Logger
import Bcfg2.Options
-from Bcfg2.Client.Tools.SELinux import *
-
-LOGGER = None
-
-def get_setup():
- global LOGGER
- optinfo = Bcfg2.Options.CLIENT_COMMON_OPTIONS
- setup = Bcfg2.Options.OptionParser(optinfo)
- setup.parse(sys.argv[1:])
+from Bcfg2.Client.Tools.SELinux import SELinux
- if setup['args']:
- print("selinux_baseline.py takes no arguments, only options")
- print(setup.buildHelpMessage())
- raise SystemExit(1)
- level = 30
- if setup['verbose']:
- level = 20
- if setup['debug']:
- level = 0
- Bcfg2.Logger.setup_logging('selinux_base',
- to_syslog=False,
- level=level,
- to_file=setup['logging'])
- LOGGER = logging.getLogger('bcfg2')
- return setup
def main():
- setup = get_setup()
+ Bcfg2.Options.get_parser(
+ description="Get a baseline bundle of SELinux entries",
+ components=[SELinux]).parse()
config = lxml.etree.Element("Configuration")
- selinux = SELinux(LOGGER, setup, config)
+ selinux = SELinux(config)
baseline = lxml.etree.Element("Bundle", name="selinux_baseline")
for etype, handler in selinux.handlers.items():
diff --git a/tools/upgrade/1.1/posixunified.py b/tools/upgrade/1.1/posixunified.py
index 8eb4ed734..b6ce7bc90 100644..100755
--- a/tools/upgrade/1.1/posixunified.py
+++ b/tools/upgrade/1.1/posixunified.py
@@ -17,12 +17,13 @@ NOTE: This script takes a conservative approach when it comes to
"""
if __name__ == '__main__':
- opts = {
- 'repo': Bcfg2.Options.SERVER_REPOSITORY,
- }
- setup = Bcfg2.Options.OptionParser(opts)
- setup.parse(sys.argv[1:])
- repo = setup['repo']
+ parser = Bcfg2.Options.get_parser(
+ description="Migrate from Bcfg2 1.0-style POSIX entries to 1.1-style "
+ "unified Path entries")
+ parser.add_options([Bcfg2.Options.Common.repository])
+ parser.parse()
+
+ repo = Bcfg2.Options.setup.repository
unifiedposixrules = "%s/Rules/unified-rules.xml" % repo
rulesroot = lxml.etree.Element("Rules")
diff --git a/tools/upgrade/1.2/nagiosgen-convert.py b/tools/upgrade/1.2/nagiosgen-convert.py
index 2c2142735..eb10cd4ea 100755
--- a/tools/upgrade/1.2/nagiosgen-convert.py
+++ b/tools/upgrade/1.2/nagiosgen-convert.py
@@ -7,10 +7,13 @@ import lxml.etree
import Bcfg2.Options
def main():
- opts = {'repo': Bcfg2.Options.SERVER_REPOSITORY}
- setup = Bcfg2.Options.OptionParser(opts)
- setup.parse(sys.argv[1:])
- repo = setup['repo']
+ parser = Bcfg2.Options.get_parser(
+ description="Migrate from Bcfg2 1.1-style Properties-based NagiosGen "
+ "configuration to standalone 1.2-style")
+ parser.add_options([Bcfg2.Options.Common.repository])
+ parser.parse()
+
+ repo = Bcfg2.Options.setup.repository
oldconfigfile = os.path.join(repo, 'Properties', 'NagiosGen.xml')
newconfigpath = os.path.join(repo, 'NagiosGen')
newconfigfile = os.path.join(newconfigpath, 'config.xml')
@@ -32,11 +35,11 @@ def main():
if host.tag == lxml.etree.Comment:
# skip comments
continue
-
+
if host.tag == 'default':
print("default tag will not be converted; use a suitable Group tag instead")
continue
-
+
newhost = lxml.etree.Element("Client", name=host.tag)
for opt in host:
newopt = lxml.etree.Element("Option", name=opt.tag)
diff --git a/tools/upgrade/1.2/packages-convert.py b/tools/upgrade/1.2/packages-convert.py
index d65ce90a2..eb1f2f7de 100755
--- a/tools/upgrade/1.2/packages-convert.py
+++ b/tools/upgrade/1.2/packages-convert.py
@@ -30,10 +30,13 @@ def place_source(xdata, source, groups):
return xdata
def main():
- opts = {'repo': Bcfg2.Options.SERVER_REPOSITORY}
- setup = Bcfg2.Options.OptionParser(opts)
- setup.parse(sys.argv[1:])
- repo = setup['repo']
+ parser = Bcfg2.Options.get_parser(
+ description="Migrate from Bcfg2 1.1-style Packages configuration to "
+ "1.2-style")
+ parser.add_options([Bcfg2.Options.Common.repository])
+ parser.parse()
+
+ repo = Bcfg2.Options.setup.repository
configpath = os.path.join(repo, 'Packages')
oldconfigfile = os.path.join(configpath, 'config.xml')
newconfigfile = os.path.join(configpath, 'packages.conf')
@@ -78,7 +81,7 @@ def main():
if el.tag == lxml.etree.Comment or el.tag == 'Config':
# skip comments and Config
continue
-
+
if el.tag == XI + 'include':
oldsources.append(os.path.join(configpath, el.get('href')))
newsource.append(el)
@@ -98,7 +101,7 @@ def main():
newel.set(tag.lower(), el.find(tag).text)
except AttributeError:
pass
-
+
for child in el.getchildren():
if child.tag in ['Component', 'Blacklist', 'Whitelist', 'Arch']:
newel.append(child)
diff --git a/tools/upgrade/1.3/migrate_configs.py b/tools/upgrade/1.3/migrate_configs.py
index b7adb2528..9fa362acf 100755
--- a/tools/upgrade/1.3/migrate_configs.py
+++ b/tools/upgrade/1.3/migrate_configs.py
@@ -16,13 +16,13 @@ def copy_section(src_file, tgt_cfg, section, newsection=None):
tgt_cfg.add_section(newsection)
except ConfigParser.DuplicateSectionError:
print("[%s] section already exists in %s, adding options" %
- (newsection, setup['cfile']))
+ (newsection, Bcfg2.Options.setup.config))
for opt in cfg.options(section):
val = cfg.get(section, opt)
if tgt_cfg.has_option(newsection, opt):
print("%s in [%s] already populated in %s, skipping" %
- (opt, newsection, setup['cfile']))
- print(" %s: %s" % (setup['cfile'],
+ (opt, newsection, Bcfg2.Options.setup.config))
+ print(" %s: %s" % (Bcfg2.Options.setup.config,
tgt_cfg.get(newsection, opt)))
print(" %s: %s" % (src_file, val))
else:
@@ -30,47 +30,50 @@ def copy_section(src_file, tgt_cfg, section, newsection=None):
tgt_cfg.set(newsection, opt, val)
def main():
- opts = dict(repo=Bcfg2.Options.SERVER_REPOSITORY,
- configfile=Bcfg2.Options.CFILE)
- setup = Bcfg2.Options.OptionParser(opts)
- setup.parse(sys.argv[1:])
+ parser = Bcfg2.Options.get_parser(
+ description="Migrate from Bcfg2 1.2 per-plugin config files to 1.3 "
+ "unified config file")
+ parser.add_options([Bcfg2.Options.Common.repository])
+ parser.parse()
+ repo = Bcfg2.Options.setup.repository
+ cfp = ConfigParser.ConfigParser()
+ cfp.read(Bcfg2.Options.setup.config)
# files that you should remove manually
remove = []
# move rules config out of rules.conf and into bcfg2.conf
- rules_conf = os.path.join(setup['repo'], 'Rules', 'rules.conf')
+ rules_conf = os.path.join(repo, 'Rules', 'rules.conf')
if os.path.exists(rules_conf):
remove.append(rules_conf)
- copy_section(rules_conf, setup.cfp, "rules")
-
+ copy_section(rules_conf, cfp, "rules")
+
# move packages config out of packages.conf and into bcfg2.conf
- pkgs_conf = os.path.join(setup['repo'], 'Packages', 'packages.conf')
+ pkgs_conf = os.path.join(repo, 'Packages', 'packages.conf')
if os.path.exists(pkgs_conf):
remove.append(pkgs_conf)
- copy_section(pkgs_conf, setup.cfp, "global", newsection="packages")
+ copy_section(pkgs_conf, cfp, "global", newsection="packages")
for section in ["apt", "yum", "pulp"]:
- copy_section(pkgs_conf, setup.cfp, section,
+ copy_section(pkgs_conf, cfp, section,
newsection="packages:" + section)
# move reports database config into [database] section
- if setup.cfp.has_section("statistics"):
- if not setup.cfp.has_section("database"):
- setup.cfp.add_section("database")
- for opt in setup.cfp.options("statistics"):
+ if cfp.has_section("statistics"):
+ if not cfp.has_section("database"):
+ cfp.add_section("database")
+ for opt in cfp.options("statistics"):
if opt.startswith("database_"):
newopt = opt[9:]
- if setup.cfp.has_option("database", newopt):
+ if cfp.has_option("database", newopt):
print("%s in [database] already populated, skipping" %
newopt)
else:
- setup.cfp.set("database", newopt,
- setup.cfp.get("statistics", opt))
- setup.cfp.remove_option("statistics", opt)
+ cfp.set("database", newopt, cfp.get("statistics", opt))
+ cfp.remove_option("statistics", opt)
- print("Writing %s" % setup['configfile'])
+ print("Writing %s" % Bcfg2.Options.setup.config)
try:
- setup.cfp.write(open(setup['configfile'], "w"))
+ cfp.write(open(Bcfg2.Options.setup.config, "w"))
if len(remove):
print("Settings were migrated, but you must remove these files "
"manually:")
@@ -78,7 +81,7 @@ def main():
print(" %s" % path)
except IOError:
err = sys.exc_info()[1]
- print("Could not write %s: %s" % (setup['configfile'], err))
+ print("Could not write %s: %s" % (Bcfg2.Options.setup.config, err))
if __name__ == '__main__':
sys.exit(main())
diff --git a/tools/upgrade/1.3/migrate_dbstats.py b/tools/upgrade/1.3/migrate_dbstats.py
index 07def2ac8..f52ccab08 100755
--- a/tools/upgrade/1.3/migrate_dbstats.py
+++ b/tools/upgrade/1.3/migrate_dbstats.py
@@ -9,10 +9,9 @@ import logging
import time
import Bcfg2.Logger
import Bcfg2.Options
-from django.core.cache import cache
from django.db import connection, transaction, backend
-from Bcfg2.Server.Admin.Reports import Reports
+from Bcfg2.Server.Admin import UpdateReports
from Bcfg2.Reporting import models as new_models
from Bcfg2.Reporting.utils import BatchFetch
from Bcfg2.Server.Reports.reports import models as legacy_models
@@ -281,17 +280,10 @@ def _restructure():
if __name__ == '__main__':
- Bcfg2.Logger.setup_logging('bcfg2-report-collector',
- to_console=logging.INFO,
- level=logging.INFO)
-
- optinfo = dict()
- optinfo.update(Bcfg2.Options.CLI_COMMON_OPTIONS)
- optinfo.update(Bcfg2.Options.SERVER_COMMON_OPTIONS)
- setup = Bcfg2.Options.OptionParser(optinfo)
- setup.parse(sys.argv[1:])
-
- #sync!
- Reports(setup).__call__(['update'])
+ parser = Bcfg2.Options.get_parser(
+ description="Migrate from Bcfg2 1.2 DBStats plugin to 1.3 Reporting "
+ "subsystem",
+ components=[UpdateReports])
+ UpdateReports().run(Bcfg2.Options.setup)
_restructure()
diff --git a/tools/upgrade/1.3/migrate_info.py b/tools/upgrade/1.3/migrate_info.py
index 3ccbf0285..7f3bb9a29 100755
--- a/tools/upgrade/1.3/migrate_info.py
+++ b/tools/upgrade/1.3/migrate_info.py
@@ -5,7 +5,16 @@ import re
import sys
import lxml.etree
import Bcfg2.Options
-from Bcfg2.Server.Plugin import INFO_REGEX
+
+INFO_REGEX = re.compile(r'owner:\s*(?P<owner>\S+)|' +
+ r'group:\s*(?P<group>\S+)|' +
+ r'mode:\s*(?P<mode>\w+)|' +
+ r'secontext:\s*(?P<secontext>\S+)|' +
+ r'paranoid:\s*(?P<paranoid>\S+)|' +
+ r'sensitive:\s*(?P<sensitive>\S+)|' +
+ r'encoding:\s*(?P<encoding>\S+)|' +
+ r'important:\s*(?P<important>\S+)|' +
+ r'mtime:\s*(?P<mtime>\w+)')
PERMS_REGEX = re.compile(r'perms:\s*(?P<perms>\w+)')
@@ -32,16 +41,17 @@ def convert(info_file):
def main():
- opts = dict(repo=Bcfg2.Options.SERVER_REPOSITORY,
- configfile=Bcfg2.Options.CFILE,
- plugins=Bcfg2.Options.SERVER_PLUGINS)
- setup = Bcfg2.Options.OptionParser(opts)
- setup.parse(sys.argv[1:])
+ parser = Bcfg2.Options.get_parser(
+ description="Migrate from Bcfg2 1.2 info/:info files to 1.3 info.xml")
+ parser.add_options([Bcfg2.Options.Common.repository,
+ Bcfg2.Options.Common.plugins])
+ parser.parse()
- for plugin in setup['plugins']:
+ for plugin in Bcfg2.Options.setup.plugins:
if plugin not in ['SSLCA', 'Cfg', 'TGenshi', 'TCheetah', 'SSHbase']:
continue
- for root, dirs, files in os.walk(os.path.join(setup['repo'], plugin)):
+ datastore = os.path.join(Bcfg2.Options.setup.repository, plugin)
+ for root, dirs, files in os.walk(datastore):
for fname in files:
if fname in [":info", "info"]:
convert(os.path.join(root, fname))
diff --git a/tools/upgrade/1.3/migrate_perms_to_mode.py b/tools/upgrade/1.3/migrate_perms_to_mode.py
index 18abffec2..786df0de6 100755
--- a/tools/upgrade/1.3/migrate_perms_to_mode.py
+++ b/tools/upgrade/1.3/migrate_perms_to_mode.py
@@ -54,16 +54,17 @@ def convertstructure(structfile):
def main():
- opts = dict(repo=Bcfg2.Options.SERVER_REPOSITORY,
- configfile=Bcfg2.Options.CFILE,
- plugins=Bcfg2.Options.SERVER_PLUGINS)
- setup = Bcfg2.Options.OptionParser(opts)
- setup.parse(sys.argv[1:])
- repo = setup['repo']
+ parser = Bcfg2.Options.get_parser(
+ description="Migrate from Bcfg2 1.2 'perms' attribute to 1.3 'mode' "
+ "attribute")
+ parser.add_options([Bcfg2.Options.Common.repository,
+ Bcfg2.Options.Common.plugins])
+ parser.parse()
+ repo = Bcfg2.Options.setup.repository
- for plugin in setup['plugins']:
+ for plugin in Bcfg2.Options.setup.plugins:
if plugin in ['Base', 'Bundler', 'Rules']:
- for root, dirs, files in os.walk(os.path.join(repo, plugin)):
+ for root, _, files in os.walk(os.path.join(repo, plugin)):
for fname in files:
convertstructure(os.path.join(root, fname))
if plugin not in ['Cfg', 'TGenshi', 'TCheetah', 'SSHbase', 'SSLCA']:
diff --git a/tools/upgrade/1.3/service_modes.py b/tools/upgrade/1.3/service_modes.py
index 0c458c3a9..d8e3c9e6f 100755
--- a/tools/upgrade/1.3/service_modes.py
+++ b/tools/upgrade/1.3/service_modes.py
@@ -6,14 +6,18 @@ import glob
import lxml.etree
import Bcfg2.Options
+
def main():
- opts = dict(repo=Bcfg2.Options.SERVER_REPOSITORY)
- setup = Bcfg2.Options.OptionParser(opts)
- setup.parse(sys.argv[1:])
+ parser = Bcfg2.Options.get_parser(
+ description="Migrate from Bcfg2 1.2 Service modes to 1.3-style "
+ "granular Service specification")
+ parser.add_options([Bcfg2.Options.Common.repository])
+ parser.parse()
files = []
for plugin in ['Bundler', 'Rules', 'Default']:
- files.extend(glob.glob(os.path.join(setup['repo'], plugin, "*")))
+ files.extend(glob.glob(os.path.join(Bcfg2.Options.setup.repository,
+ plugin, "*")))
for bfile in files:
bdata = lxml.etree.parse(bfile)
diff --git a/tools/upgrade/1.4/README b/tools/upgrade/1.4/README
new file mode 100644
index 000000000..b03cb9b74
--- /dev/null
+++ b/tools/upgrade/1.4/README
@@ -0,0 +1,14 @@
+This directory contains scripts to help with upgrading from Bcfg2 1.3
+to 1.4.
+
+migrate_decisions.py
+ - Convert old group- and host-specific whitelist and blacklist
+ files into structured XML
+
+convert_bundles.py
+ - Remove deprecated explicit bundle names, rename .genshi bundles
+ to .xml
+
+migrate_sslca.py
+ - Migrate from the standalone SSLCA plugin to the built-in SSL
+ certificate generation abilities of the Cfg plugin \ No newline at end of file
diff --git a/tools/upgrade/1.4/convert_bundles.py b/tools/upgrade/1.4/convert_bundles.py
new file mode 100755
index 000000000..b9cb483f2
--- /dev/null
+++ b/tools/upgrade/1.4/convert_bundles.py
@@ -0,0 +1,32 @@
+#!/usr/bin/env python
+
+import os
+import sys
+import lxml.etree
+import Bcfg2.Options
+
+
+def main():
+ parser = Bcfg2.Options.get_parser("Tool to remove bundle names")
+ parser.add_options([Bcfg2.Options.Common.repository])
+ parser.parse()
+
+ bundler_dir = os.path.join(Bcfg2.Options.setup.repository, "Bundler")
+ if os.path.exists(bundler_dir):
+ for root, _, files in os.walk(bundler_dir):
+ for fname in files:
+ bpath = os.path.join(root, fname)
+ newpath = bpath
+ if newpath.endswith(".genshi"):
+ newpath = newpath[:-6] + "xml"
+ print("Converting %s to %s" % (bpath, newpath))
+ else:
+ print("Converting %s" % bpath)
+ xroot = lxml.etree.parse(bpath)
+ xdata = xroot.getroot()
+ if 'name' in xdata.attrib:
+ del xdata.attrib['name']
+ xroot.write(bpath)
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/tools/upgrade/1.4/migrate_decisions.py b/tools/upgrade/1.4/migrate_decisions.py
new file mode 100755
index 000000000..d0915f202
--- /dev/null
+++ b/tools/upgrade/1.4/migrate_decisions.py
@@ -0,0 +1,82 @@
+#!/usr/bin/env python
+
+import os
+import re
+import sys
+import glob
+import lxml.etree
+import Bcfg2.Options
+
+
+SPECIFIC = re.compile(r'.*\/(white|black)list'
+ r'(\.(H_(?P<host>.*)|G\d+_(?P<group>.*)))?$')
+
+
+def convert(files, xdata):
+ hosts = []
+ groups = []
+ for oldfile in files:
+ spec = SPECIFIC.match(oldfile)
+ if spec and spec.group('host'):
+ hosts.append(spec.group('host'))
+ elif spec and spec.group('group'):
+ groups.append(spec.group('group'))
+
+ for oldfile in files:
+ print("Converting %s" % oldfile)
+ spec = SPECIFIC.match(oldfile)
+ if not spec:
+ print("Skipping unknown file %s" % oldfile)
+ continue
+
+ parent = xdata
+ if spec.group('host'):
+ for host in hosts:
+ if host != spec.group('host'):
+ parent = lxml.etree.SubElement(parent, "Client",
+ name=host, negate="true")
+ parent = lxml.etree.SubElement(parent, "Client",
+ name=spec.group('host'))
+ elif spec.group('group'):
+ for host in hosts:
+ parent = lxml.etree.SubElement(parent, "Client",
+ name=host, negate="true")
+ for group in groups:
+ if group != spec.group('group'):
+ parent = lxml.etree.SubElement(parent, "Group",
+ name=group, negate="true")
+ parent = lxml.etree.SubElement(parent, "Group",
+ name=spec.group('group'))
+ parent.append(lxml.etree.Comment("Converted from %s" % oldfile))
+ olddata = lxml.etree.parse(oldfile, parser=Bcfg2.Server.XMLParser)
+ for decision in olddata.xpath('//Decision'):
+ parent.append(decision)
+ return xdata
+
+
+def main():
+ parser = Bcfg2.Options.get_parser(
+ description="Migrate from Bcfg2 1.3 Decisions list format to 1.4 "
+ "format")
+ parser.add_options([Bcfg2.Options.Common.repository])
+ parser.parse()
+
+ datadir = os.path.join(Bcfg2.Options.setup.repository, 'Decisions')
+ whitelist = lxml.etree.Element("Decisions")
+ blacklist = lxml.etree.Element("Decisions")
+ if os.path.exists(datadir):
+ convert(glob.glob(os.path.join(datadir, 'whitelist*')),
+ whitelist)
+ convert(glob.glob(os.path.join(datadir, 'blacklist*')),
+ blacklist)
+
+ print("Writing %s" % os.path.join(datadir, "whitelist.xml"))
+ open(os.path.join(datadir, "whitelist.xml"),
+ 'w').write(lxml.etree.tostring(whitelist, pretty_print=True))
+ print("Writing %s" % os.path.join(datadir, "blacklist.xml"))
+ open(os.path.join(datadir, "blacklist.xml"),
+ 'w').write(lxml.etree.tostring(blacklist, pretty_print=True))
+
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/tools/upgrade/1.4/migrate_sslca.py b/tools/upgrade/1.4/migrate_sslca.py
new file mode 100755
index 000000000..958228c86
--- /dev/null
+++ b/tools/upgrade/1.4/migrate_sslca.py
@@ -0,0 +1,44 @@
+#!/usr/bin/env python
+
+import os
+import sys
+import shutil
+import Bcfg2.Options
+
+
+def main():
+ parser = Bcfg2.Options.get_parser(
+ description="Migrate from the SSLCA plugin to built-in Cfg SSL cert "
+ "generation")
+ parser.add_options([Bcfg2.Options.Common.repository])
+ parser.parse()
+
+ sslcadir = os.path.join(Bcfg2.Options.setup.repository, 'SSLCA')
+ cfgdir = os.path.join(Bcfg2.Options.setup.repository, 'Cfg')
+ for root, _, files in os.walk(sslcadir):
+ if not files:
+ continue
+ newpath = cfgdir + root[len(sslcadir):]
+ if not os.path.exists(newpath):
+ print("Creating %s and copying contents from %s" % (newpath, root))
+ shutil.copytree(root, newpath)
+ else:
+ print("Copying contents from %s to %s" % (root, newpath))
+ for fname in files:
+ newfpath = os.path.exists(os.path.join(newpath, fname))
+ if newfpath:
+ print("%s already exists, skipping" % newfpath)
+ else:
+ shutil.copy(os.path.join(root, fname), newpath)
+ cert = os.path.join(newpath, "cert.xml")
+ newcert = os.path.join(newpath, "sslcert.xml")
+ key = os.path.join(newpath, "key.xml")
+ newkey = os.path.join(newpath, "sslkey.xml")
+ if os.path.exists(cert):
+ os.rename(cert, newcert)
+ if os.path.exists(key):
+ os.rename(key, newkey)
+
+
+if __name__ == '__main__':
+ sys.exit(main())