diff options
author | Chris St. Pierre <chris.a.st.pierre@gmail.com> | 2013-04-23 14:50:09 -0400 |
---|---|---|
committer | Chris St. Pierre <chris.a.st.pierre@gmail.com> | 2013-04-23 14:50:09 -0400 |
commit | 46a47b4120b3d892b8149a5e181e4d976ad87f99 (patch) | |
tree | f2697f233fc7f5ad5022864222a5ca87715a651b /tools | |
parent | e1f99d1d5045e0511db42debb30aa97da2018796 (diff) | |
parent | 3d06f311274d6b942ee89d8cdb13b2ecc99af1b0 (diff) | |
download | bcfg2-46a47b4120b3d892b8149a5e181e4d976ad87f99.tar.gz bcfg2-46a47b4120b3d892b8149a5e181e4d976ad87f99.tar.bz2 bcfg2-46a47b4120b3d892b8149a5e181e4d976ad87f99.zip |
Merge branch '1.4.x'
Conflicts:
debian/bcfg2-server.install
doc/server/plugins/grouping/metadata.txt
src/lib/Bcfg2/Client/Client.py
src/lib/Bcfg2/Client/Tools/Portage.py
src/lib/Bcfg2/Client/Tools/RcUpdate.py
src/lib/Bcfg2/Client/Tools/YUM24.py
src/lib/Bcfg2/Client/Tools/__init__.py
src/lib/Bcfg2/Client/Tools/launchd.py
src/lib/Bcfg2/Options.py
src/lib/Bcfg2/Server/Core.py
src/lib/Bcfg2/Server/Plugin/helpers.py
src/lib/Bcfg2/Server/Plugins/Metadata.py
src/lib/Bcfg2/Server/models.py
src/lib/Bcfg2/Utils.py
src/sbin/bcfg2-info
src/sbin/bcfg2-test
testsuite/Testsrc/Testlib/TestClient/TestTools/Test_init.py
testsuite/Testsrc/test_code_checks.py
Diffstat (limited to 'tools')
-rw-r--r-- | tools/README | 12 | ||||
-rwxr-xr-x | tools/batchadd.py | 168 | ||||
-rwxr-xr-x | tools/bcfg2-import-config | 10 | ||||
-rwxr-xr-x | tools/hostbase.py | 79 | ||||
-rwxr-xr-x | tools/hostbasepush.py | 14 | ||||
-rwxr-xr-x | tools/hostinfo.py | 197 | ||||
-rw-r--r-- | tools/upgrade/1.4/README | 6 | ||||
-rwxr-xr-x | tools/upgrade/1.4/migrate_decisions.py | 82 |
8 files changed, 89 insertions, 479 deletions
diff --git a/tools/README b/tools/README index 9e7f667e3..ad6d5eac1 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 @@ -61,15 +58,6 @@ export.sh generate-manpages.bash - Generate man pages from the Sphinx source -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/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/upgrade/1.4/README b/tools/upgrade/1.4/README new file mode 100644 index 000000000..b6ff8d8c8 --- /dev/null +++ b/tools/upgrade/1.4/README @@ -0,0 +1,6 @@ +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 diff --git a/tools/upgrade/1.4/migrate_decisions.py b/tools/upgrade/1.4/migrate_decisions.py new file mode 100755 index 000000000..f7072783a --- /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 +from Bcfg2.Server import XMLParser + + +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(): + opts = dict(repo=Bcfg2.Options.SERVER_REPOSITORY, + configfile=Bcfg2.Options.CFILE) + setup = Bcfg2.Options.load_option_parser(opts) + setup.parse(sys.argv[1:]) + + datadir = os.path.join(setup['repo'], '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()) |