summaryrefslogtreecommitdiffstats
path: root/src/lib/Bcfg2/Server
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/Bcfg2/Server')
-rw-r--r--src/lib/Bcfg2/Server/Admin/Compare.py3
-rw-r--r--src/lib/Bcfg2/Server/Admin/Snapshots.py163
-rw-r--r--src/lib/Bcfg2/Server/Admin/Viz.py6
-rw-r--r--src/lib/Bcfg2/Server/Admin/__init__.py1
-rw-r--r--src/lib/Bcfg2/Server/Core.py22
-rw-r--r--src/lib/Bcfg2/Server/FileMonitor/Fam.py105
-rw-r--r--src/lib/Bcfg2/Server/FileMonitor/__init__.py45
-rw-r--r--src/lib/Bcfg2/Server/Hostbase/.gitignore3
-rw-r--r--src/lib/Bcfg2/Server/Hostbase/__init__.py0
-rw-r--r--src/lib/Bcfg2/Server/Hostbase/backends.py63
-rw-r--r--src/lib/Bcfg2/Server/Hostbase/hostbase/__init__.py0
-rw-r--r--src/lib/Bcfg2/Server/Hostbase/hostbase/admin.py15
-rw-r--r--src/lib/Bcfg2/Server/Hostbase/hostbase/models.py210
-rw-r--r--src/lib/Bcfg2/Server/Hostbase/hostbase/sql/zone.sql2
-rw-r--r--src/lib/Bcfg2/Server/Hostbase/hostbase/urls.py68
-rw-r--r--src/lib/Bcfg2/Server/Hostbase/hostbase/views.py970
-rw-r--r--src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/base.html34
-rw-r--r--src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/confirm.html117
-rw-r--r--src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/copy.html122
-rw-r--r--src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/dns.html40
-rw-r--r--src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/dnsedit.html98
-rw-r--r--src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/edit.html191
-rw-r--r--src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/errors.html31
-rw-r--r--src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/host.html80
-rw-r--r--src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/hostbase/host_confirm_delete.html89
-rw-r--r--src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/hostbase/log_detail.html23
-rw-r--r--src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/index.html16
-rw-r--r--src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/login.html37
-rw-r--r--src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/logout.html13
-rw-r--r--src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/logout.tmpl6
-rw-r--r--src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/logviewer.html27
-rw-r--r--src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/navbar.tmpl5
-rw-r--r--src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/new.html102
-rw-r--r--src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/remove.html89
-rw-r--r--src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/results.html45
-rw-r--r--src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/search.html57
-rw-r--r--src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/zoneedit.html81
-rw-r--r--src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/zonenew.html43
-rw-r--r--src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/zones.html37
-rw-r--r--src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/zoneview.html71
-rw-r--r--src/lib/Bcfg2/Server/Hostbase/ldapauth.py179
-rwxr-xr-xsrc/lib/Bcfg2/Server/Hostbase/manage.py11
-rw-r--r--src/lib/Bcfg2/Server/Hostbase/media/base.css5
-rw-r--r--src/lib/Bcfg2/Server/Hostbase/media/boxypastel.css179
-rw-r--r--src/lib/Bcfg2/Server/Hostbase/media/global.css8
-rw-r--r--src/lib/Bcfg2/Server/Hostbase/media/layout.css62
-rw-r--r--src/lib/Bcfg2/Server/Hostbase/nisauth.py40
-rw-r--r--src/lib/Bcfg2/Server/Hostbase/regex.py6
-rw-r--r--src/lib/Bcfg2/Server/Hostbase/settings.py143
-rw-r--r--src/lib/Bcfg2/Server/Hostbase/templates/batchadd.tmpl29
-rw-r--r--src/lib/Bcfg2/Server/Hostbase/templates/dhcpd.conf.head5
-rw-r--r--src/lib/Bcfg2/Server/Hostbase/templates/dhcpd.tmpl17
-rw-r--r--src/lib/Bcfg2/Server/Hostbase/templates/hosts.tmpl26
-rw-r--r--src/lib/Bcfg2/Server/Hostbase/templates/hostsappend.tmpl5
-rw-r--r--src/lib/Bcfg2/Server/Hostbase/templates/named.tmpl69
-rw-r--r--src/lib/Bcfg2/Server/Hostbase/templates/namedviews.tmpl92
-rw-r--r--src/lib/Bcfg2/Server/Hostbase/templates/reverseappend.tmpl4
-rw-r--r--src/lib/Bcfg2/Server/Hostbase/templates/reversesoa.tmpl13
-rw-r--r--src/lib/Bcfg2/Server/Hostbase/templates/zone.tmpl18
-rw-r--r--src/lib/Bcfg2/Server/Hostbase/urls.py27
-rwxr-xr-xsrc/lib/Bcfg2/Server/Lint/Genshi.py7
-rw-r--r--src/lib/Bcfg2/Server/Lint/InfoXML.py11
-rw-r--r--src/lib/Bcfg2/Server/Plugin/helpers.py80
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Account.py102
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Base.py4
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Bundler.py70
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Cfg/CfgCatFilter.py28
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Cfg/CfgDiffFilter.py35
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Cfg/CfgLegacyInfo.py46
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Cfg/__init__.py31
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Decisions.py3
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Editor.py80
-rw-r--r--src/lib/Bcfg2/Server/Plugins/FileProbes.py4
-rw-r--r--src/lib/Bcfg2/Server/Plugins/GroupPatterns.py6
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Hostbase.py599
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Ldap.py6
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Metadata.py8
-rw-r--r--src/lib/Bcfg2/Server/Plugins/NagiosGen.py7
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Packages/Apt.py9
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Packages/Collection.py36
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Packages/Pac.py9
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Packages/PackagesSources.py7
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Packages/Source.py42
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Packages/Yum.py16
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Packages/__init__.py23
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Probes.py7
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Properties.py28
-rw-r--r--src/lib/Bcfg2/Server/Plugins/PuppetENC.py3
-rw-r--r--src/lib/Bcfg2/Server/Plugins/SSHbase.py7
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Snapshots.py129
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Statistics.py160
-rw-r--r--src/lib/Bcfg2/Server/Plugins/TCheetah.py79
-rw-r--r--src/lib/Bcfg2/Server/Plugins/TGenshi.py139
-rw-r--r--src/lib/Bcfg2/Server/Plugins/TemplateHelper.py5
-rw-r--r--src/lib/Bcfg2/Server/Plugins/Trigger.py3
-rw-r--r--src/lib/Bcfg2/Server/Plugins/__init__.py33
-rw-r--r--src/lib/Bcfg2/Server/Snapshots/__init__.py31
-rw-r--r--src/lib/Bcfg2/Server/Snapshots/model.py323
-rw-r--r--src/lib/Bcfg2/Server/__init__.py3
-rw-r--r--src/lib/Bcfg2/Server/models.py14
100 files changed, 211 insertions, 6090 deletions
diff --git a/src/lib/Bcfg2/Server/Admin/Compare.py b/src/lib/Bcfg2/Server/Admin/Compare.py
index 820271a2f..8214f9e71 100644
--- a/src/lib/Bcfg2/Server/Admin/Compare.py
+++ b/src/lib/Bcfg2/Server/Admin/Compare.py
@@ -22,8 +22,7 @@ class Compare(Bcfg2.Server.Admin.Mode):
'Service': ['name', 'type', 'status', 'mode',
'target', 'sequence', 'parameters'],
'Action': ['name', 'timing', 'when', 'status',
- 'command'],
- 'PostInstall': ['name']
+ 'command']
}
def compareStructures(self, new, old):
diff --git a/src/lib/Bcfg2/Server/Admin/Snapshots.py b/src/lib/Bcfg2/Server/Admin/Snapshots.py
deleted file mode 100644
index bf44d1451..000000000
--- a/src/lib/Bcfg2/Server/Admin/Snapshots.py
+++ /dev/null
@@ -1,163 +0,0 @@
-from datetime import date
-import sys
-
-# Prereq issues can be signaled with ImportError, so no try needed
-import sqlalchemy, sqlalchemy.orm
-import Bcfg2.Server.Admin
-import Bcfg2.Server.Snapshots
-import Bcfg2.Server.Snapshots.model
-from Bcfg2.Server.Snapshots.model import Snapshot, Client, Metadata, Base, \
- File, Group, Package, Service
-# Compatibility import
-from Bcfg2.Compat import u_str
-
-class Snapshots(Bcfg2.Server.Admin.Mode):
- """ Interact with the Snapshots system """
- __usage__ = "[init|query qtype]"
-
- q_dispatch = {'client': Client,
- 'group': Group,
- 'metadata': Metadata,
- 'package': Package,
- 'snapshot': Snapshot}
-
- def __init__(self):
- Bcfg2.Server.Admin.Mode.__init__(self)
- self.session = Bcfg2.Server.Snapshots.setup_session(self.configfile)
- self.cfile = self.configfile
-
- def __call__(self, args):
- Bcfg2.Server.Admin.Mode.__call__(self, args)
- if len(args) == 0 or args[0] == '-h':
- print(self.__usage__)
- raise SystemExit(0)
-
- if args[0] == 'query':
- if args[1] in self.q_dispatch:
- q_obj = self.q_dispatch[args[1]]
- if q_obj == Client:
- rows = []
- labels = ('Client', 'Active')
- for host in \
- self.session.query(q_obj).filter(q_obj.active == False):
- rows.append([host.name, 'No'])
- for host in \
- self.session.query(q_obj).filter(q_obj.active == True):
- rows.append([host.name, 'Yes'])
- self.print_table([labels]+rows,
- justify='left',
- hdr=True,
- vdelim=" ",
- padding=1)
- elif q_obj == Group:
- print("Groups:")
- for group in self.session.query(q_obj).all():
- print(" %s" % group.name)
- else:
- results = self.session.query(q_obj).all()
- else:
- print('error')
- raise SystemExit(1)
- elif args[0] == 'init':
- # Initialize the Snapshots database
- dbpath = Bcfg2.Server.Snapshots.db_from_config(self.cfile)
- engine = sqlalchemy.create_engine(dbpath, echo=True)
- metadata = Base.metadata
- metadata.create_all(engine)
- Session = sqlalchemy.orm.sessionmaker()
- Session.configure(bind=engine)
- session = Session()
- session.commit()
- elif args[0] == 'dump':
- client = args[1]
- snap = Snapshot.get_current(self.session, u_str(client))
- if not snap:
- print("Current snapshot for %s not found" % client)
- sys.exit(1)
- print("Client %s last run at %s" % (client, snap.timestamp))
- for pkg in snap.packages:
- print("C:", pkg.correct, 'M:', pkg.modified)
- print("start", pkg.start.name, pkg.start.version)
- print("end", pkg.end.name, pkg.end.version)
- elif args[0] == 'reports':
- # bcfg2-admin reporting interface for Snapshots
- if '-a' in args[1:]:
- # Query all hosts for Name, Status, Revision, Timestamp
- q = self.session.query(Client.name,
- Snapshot.correct,
- Snapshot.revision,
- Snapshot.timestamp)\
- .filter(Client.id==Snapshot.client_id)\
- .group_by(Client.id)
- rows = []
- labels = ('Client', 'Correct', 'Revision', 'Time')
- for item in q.all():
- cli, cor, time, rev = item
- rows.append([cli, cor, time, rev])
- self.print_table([labels]+rows,
- justify='left',
- hdr=True, vdelim=" ",
- padding=1)
- elif '-b' in args[1:]:
- # Query a single host for bad entries
- if len(args) < 3:
- print("Usage: bcfg2-admin snapshots -b <client>")
- return
- client = args[2]
- snap = Snapshot.get_current(self.session, u_str(client))
- if not snap:
- print("Current snapshot for %s not found" % client)
- sys.exit(1)
- print("Bad entries:")
- bad_pkgs = [self.session.query(Package)
- .filter(Package.id==p.start_id).one().name \
- for p in snap.packages if p.correct == False]
- for p in bad_pkgs:
- print(" Package:%s" % p)
- bad_files = [self.session.query(File)
- .filter(File.id==f.start_id).one().name \
- for f in snap.files if f.correct == False]
- for filename in bad_files:
- print(" File:%s" % filename)
- bad_svcs = [self.session.query(Service)
- .filter(Service.id==s.start_id).one().name \
- for s in snap.services if s.correct == False]
- for svc in bad_svcs:
- print(" Service:%s" % svc)
- elif '-e' in args[1:]:
- # Query a single host for extra entries
- client = args[2]
- snap = Snapshot.get_current(self.session, u_str(client))
- if not snap:
- print("Current snapshot for %s not found" % client)
- sys.exit(1)
- print("Extra entries:")
- for pkg in snap.extra_packages:
- print(" Package:%s" % pkg.name)
- # FIXME: Do we know about extra files yet?
- for f in snap.extra_files:
- print(" File:%s" % f.name)
- for svc in snap.extra_services:
- print(" Service:%s" % svc.name)
- elif '--date' in args[1:]:
- year, month, day = args[2:]
- timestamp = date(int(year), int(month), int(day))
- snaps = []
- for client in self.session.query(Client).filter(Client.active == True):
- snaps.append(Snapshot.get_by_date(self.session,
- client.name,
- timestamp))
- rows = []
- labels = ('Client', 'Correct', 'Revision', 'Time')
- for snap in snaps:
- rows.append([snap.client.name,
- snap.correct,
- snap.revision,
- snap.timestamp])
- self.print_table([labels]+rows,
- justify='left',
- hdr=True,
- vdelim=" ",
- padding=1)
- else:
- print("Unknown options: ", args[1:])
diff --git a/src/lib/Bcfg2/Server/Admin/Viz.py b/src/lib/Bcfg2/Server/Admin/Viz.py
index 1d9d25f16..efbfff96e 100644
--- a/src/lib/Bcfg2/Server/Admin/Viz.py
+++ b/src/lib/Bcfg2/Server/Admin/Viz.py
@@ -29,10 +29,10 @@ class Viz(Bcfg2.Server.Admin.MetadataCore):
'indianred1', 'limegreen', 'orange1', 'lightblue2',
'green1', 'blue1', 'yellow1', 'darkturquoise', 'gray66']
- __plugin_blacklist__ = ['DBStats', 'Snapshots', 'Cfg', 'Pkgmgr',
- 'Packages', 'Rules', 'Account', 'Decisions',
+ __plugin_blacklist__ = ['DBStats', 'Cfg', 'Pkgmgr',
+ 'Packages', 'Rules', 'Decisions',
'Deps', 'Git', 'Svn', 'Fossil', 'Bzr', 'Bundler',
- 'TGenshi', 'Base']
+ 'Base']
def __call__(self, args):
# First get options to the 'viz' subcommand
diff --git a/src/lib/Bcfg2/Server/Admin/__init__.py b/src/lib/Bcfg2/Server/Admin/__init__.py
index 20577633a..0c4764642 100644
--- a/src/lib/Bcfg2/Server/Admin/__init__.py
+++ b/src/lib/Bcfg2/Server/Admin/__init__.py
@@ -12,7 +12,6 @@ __all__ = [
'Pull',
'Query',
'Reports',
- 'Snapshots',
'Syncdb',
'Tidy',
'Viz',
diff --git a/src/lib/Bcfg2/Server/Core.py b/src/lib/Bcfg2/Server/Core.py
index 0ef20dfac..c7797a711 100644
--- a/src/lib/Bcfg2/Server/Core.py
+++ b/src/lib/Bcfg2/Server/Core.py
@@ -17,7 +17,7 @@ import Bcfg2.Statistics
import Bcfg2.Server.FileMonitor
from itertools import chain
from Bcfg2.Cache import Cache
-from Bcfg2.Options import get_option_parser
+from Bcfg2.Options import get_option_parser, SERVER_FAM_IGNORE
from Bcfg2.Compat import xmlrpclib # pylint: disable=W0622
from Bcfg2.Server.Plugin import PluginInitError, PluginExecutionError, \
track_statistics
@@ -120,24 +120,22 @@ class BaseCore(object):
#: A :class:`logging.Logger` object for use by the core
self.logger = logging.getLogger('bcfg2-server')
- try:
- filemonitor = \
- Bcfg2.Server.FileMonitor.available[self.setup['filemonitor']]
- except KeyError:
+ if 'ignore' not in self.setup:
+ self.setup.add_option('ignore', SERVER_FAM_IGNORE)
+ self.setup.reparse()
+ famargs = dict(filemonitor=self.setup['filemonitor'],
+ debug=self.setup['debug'],
+ ignore=self.setup['ignore'])
+ if self.setup['filemonitor'] not in Bcfg2.Server.FileMonitor.available:
self.logger.error("File monitor driver %s not available; "
"forcing to default" % self.setup['filemonitor'])
- filemonitor = Bcfg2.Server.FileMonitor.available['default']
- famargs = dict(ignore=[], debug=False)
- if 'ignore' in self.setup:
- famargs['ignore'] = self.setup['ignore']
- if 'debug' in self.setup:
- famargs['debug'] = self.setup['debug']
+ famargs['filemonitor'] = 'default'
try:
#: The :class:`Bcfg2.Server.FileMonitor.FileMonitor`
#: object used by the core to monitor for Bcfg2 data
#: changes.
- self.fam = filemonitor(**famargs)
+ self.fam = Bcfg2.Server.FileMonitor.get_fam(**famargs)
except IOError:
msg = "Failed to instantiate fam driver %s" % \
self.setup['filemonitor']
diff --git a/src/lib/Bcfg2/Server/FileMonitor/Fam.py b/src/lib/Bcfg2/Server/FileMonitor/Fam.py
deleted file mode 100644
index 253bb2801..000000000
--- a/src/lib/Bcfg2/Server/FileMonitor/Fam.py
+++ /dev/null
@@ -1,105 +0,0 @@
-""" File monitor backend with support for the `File Alteration Monitor
-<http://oss.sgi.com/projects/fam/>`_. The FAM backend is deprecated. """
-
-import os
-import _fam
-import stat
-import logging
-from time import time
-from Bcfg2.Server.FileMonitor import FileMonitor
-
-LOGGER = logging.getLogger(__name__)
-
-
-class Fam(FileMonitor):
- """ **Deprecated** file monitor backend with support for the `File
- Alteration Monitor <http://oss.sgi.com/projects/fam/>`_ (also
- abbreviated "FAM")."""
-
- #: FAM is the worst actual monitor backend, so give it a low
- #: priority.
- __priority__ = 10
-
- def __init__(self, ignore=None, debug=False):
- FileMonitor.__init__(self, ignore=ignore, debug=debug)
- self.filemonitor = _fam.open()
- self.users = {}
- LOGGER.warning("The Fam file monitor backend is deprecated. Please "
- "switch to a supported file monitor.")
- __init__.__doc__ = FileMonitor.__init__.__doc__
-
- def fileno(self):
- return self.filemonitor.fileno()
- fileno.__doc__ = FileMonitor.fileno.__doc__
-
- def handle_event_set(self, _=None):
- self.Service()
- handle_event_set.__doc__ = FileMonitor.handle_event_set.__doc__
-
- def handle_events_in_interval(self, interval):
- now = time()
- while (time() - now) < interval:
- if self.Service():
- now = time()
- handle_events_in_interval.__doc__ = \
- FileMonitor.handle_events_in_interval.__doc__
-
- def AddMonitor(self, path, obj, _=None):
- mode = os.stat(path)[stat.ST_MODE]
- if stat.S_ISDIR(mode):
- handle = self.filemonitor.monitorDirectory(path, None)
- else:
- handle = self.filemonitor.monitorFile(path, None)
- self.handles[handle.requestID()] = handle
- if obj != None:
- self.users[handle.requestID()] = obj
- return handle.requestID()
- AddMonitor.__doc__ = FileMonitor.AddMonitor.__doc__
-
- def Service(self, interval=0.50):
- """ Handle events for the specified period of time (in
- seconds). This call will block for ``interval`` seconds.
-
- :param interval: The interval, in seconds, during which events
- should be handled. Any events that are
- already pending when :func:`Service` is
- called will also be handled.
- :type interval: int
- :returns: None
- """
- count = 0
- collapsed = 0
- rawevents = []
- start = time()
- now = time()
- while (time() - now) < interval:
- if self.filemonitor.pending():
- while self.filemonitor.pending():
- count += 1
- rawevents.append(self.filemonitor.nextEvent())
- now = time()
- unique = []
- bookkeeping = []
- for event in rawevents:
- if self.should_ignore(event):
- continue
- if event.code2str() != 'changed':
- # process all non-change events
- unique.append(event)
- else:
- if (event.filename, event.requestID) not in bookkeeping:
- bookkeeping.append((event.filename, event.requestID))
- unique.append(event)
- else:
- collapsed += 1
- for event in unique:
- if event.requestID in self.users:
- try:
- self.users[event.requestID].HandleEvent(event)
- except: # pylint: disable=W0702
- LOGGER.error("Handling event for file %s" % event.filename,
- exc_info=1)
- end = time()
- LOGGER.info("Processed %s fam events in %03.03f seconds. "
- "%s coalesced" % (count, (end - start), collapsed))
- return count
diff --git a/src/lib/Bcfg2/Server/FileMonitor/__init__.py b/src/lib/Bcfg2/Server/FileMonitor/__init__.py
index 42ad4c041..d77f21b93 100644
--- a/src/lib/Bcfg2/Server/FileMonitor/__init__.py
+++ b/src/lib/Bcfg2/Server/FileMonitor/__init__.py
@@ -311,6 +311,45 @@ class FileMonitor(Debuggable):
raise NotImplementedError
+#: A module-level FAM object that all plugins, etc., can use. This
+#: should not be used directly, but retrieved via :func:`get_fam`.
+_FAM = None
+
+
+def load_fam(filemonitor='default', ignore=None, debug=False):
+ """ Load a new :class:`Bcfg2.Server.FileMonitor.FileMonitor`
+ object, caching it in :attr:`_FAM` for later retrieval via
+ :func:`get_fam`.
+
+ :param filemonitor: Which filemonitor backend to use
+ :type filemonitor: string
+ :param ignore: A list of filenames to ignore
+ :type ignore: list of strings (filename globs)
+ :param debug: Produce debugging information
+ :type debug: bool
+ :returns: :class:`Bcfg2.Server.FileMonitor.FileMonitor`
+ """
+ global _FAM # pylint: disable=W0603
+ if _FAM is None:
+ if ignore is None:
+ ignore = []
+ _FAM = available[filemonitor](ignore=ignore, debug=debug)
+ return _FAM
+
+
+def get_fam():
+ """ Get an already-created
+ :class:`Bcfg2.Server.FileMonitor.FileMonitor` object. If
+ :attr:`_FAM` has not been populated, then a new default
+ FileMonitor will be created.
+
+ :returns: :class:`Bcfg2.Server.FileMonitor.FileMonitor`
+ """
+ if _FAM is None:
+ return load_fam('default')
+ return _FAM
+
+
#: A dict of all available FAM backends. Keys are the human-readable
#: names of the backends, which are used in bcfg2.conf to select a
#: backend; values are the backend classes. In addition, the
@@ -323,12 +362,6 @@ from Bcfg2.Server.FileMonitor.Pseudo import Pseudo
available['pseudo'] = Pseudo
try:
- from Bcfg2.Server.FileMonitor.Fam import Fam
- available['fam'] = Fam
-except ImportError:
- pass
-
-try:
from Bcfg2.Server.FileMonitor.Gamin import Gamin
available['gamin'] = Gamin
except ImportError:
diff --git a/src/lib/Bcfg2/Server/Hostbase/.gitignore b/src/lib/Bcfg2/Server/Hostbase/.gitignore
deleted file mode 100644
index 8e15b5395..000000000
--- a/src/lib/Bcfg2/Server/Hostbase/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-*.pyc
-dev.db
-bcfg2.conf
diff --git a/src/lib/Bcfg2/Server/Hostbase/__init__.py b/src/lib/Bcfg2/Server/Hostbase/__init__.py
deleted file mode 100644
index e69de29bb..000000000
--- a/src/lib/Bcfg2/Server/Hostbase/__init__.py
+++ /dev/null
diff --git a/src/lib/Bcfg2/Server/Hostbase/backends.py b/src/lib/Bcfg2/Server/Hostbase/backends.py
deleted file mode 100644
index cfa9e1e16..000000000
--- a/src/lib/Bcfg2/Server/Hostbase/backends.py
+++ /dev/null
@@ -1,63 +0,0 @@
-from django.contrib.auth.models import User
-#from ldapauth import *
-from nisauth import *
-
-## class LDAPBackend(object):
-
-## def authenticate(self,username=None,password=None):
-## try:
-
-## l = ldapauth(username,password)
-## temp_pass = User.objects.make_random_password(100)
-## ldap_user = dict(username=l.sAMAccountName,
-## )
-## user_session_obj = dict(
-## email=l.email,
-## first_name=l.name_f,
-## last_name=l.name_l,
-## uid=l.badge_no
-## )
-## #fixme: need to add this user session obj to session
-## user,created = User.objects.get_or_create(username=username)
-## return user
-
-## except LDAPAUTHError,e:
-## return None
-
-## def get_user(self,user_id):
-## try:
-## return User.objects.get(pk=user_id)
-## except User.DoesNotExist, e:
-## return None
-
-
-class NISBackend(object):
-
- def authenticate(self, username=None, password=None):
- try:
- n = nisauth(username, password)
- temp_pass = User.objects.make_random_password(100)
- nis_user = dict(username=username,
- )
-
- user_session_obj = dict(
- email = username + "@mcs.anl.gov",
- first_name = None,
- last_name = None,
- uid = n.uid
- )
- user, created = User.objects.get_or_create(username=username)
-
- return user
-
- except NISAUTHError:
- e = sys.exc_info()[1]
- return None
-
-
- def get_user(self, user_id):
- try:
- return User.objects.get(pk=user_id)
- except User.DoesNotExist:
- e = sys.exc_info()[1]
- return None
diff --git a/src/lib/Bcfg2/Server/Hostbase/hostbase/__init__.py b/src/lib/Bcfg2/Server/Hostbase/hostbase/__init__.py
deleted file mode 100644
index e69de29bb..000000000
--- a/src/lib/Bcfg2/Server/Hostbase/hostbase/__init__.py
+++ /dev/null
diff --git a/src/lib/Bcfg2/Server/Hostbase/hostbase/admin.py b/src/lib/Bcfg2/Server/Hostbase/hostbase/admin.py
deleted file mode 100644
index 70a2233cc..000000000
--- a/src/lib/Bcfg2/Server/Hostbase/hostbase/admin.py
+++ /dev/null
@@ -1,15 +0,0 @@
-from django.contrib import admin
-
-from models import Host, Interface, IP, MX, Name, CName, Nameserver, ZoneAddress, Zone, Log, ZoneLog
-
-admin.site.register(Host)
-admin.site.register(Interface)
-admin.site.register(IP)
-admin.site.register(MX)
-admin.site.register(Name)
-admin.site.register(CName)
-admin.site.register(Nameserver)
-admin.site.register(ZoneAddress)
-admin.site.register(Zone)
-admin.site.register(Log)
-admin.site.register(ZoneLog)
diff --git a/src/lib/Bcfg2/Server/Hostbase/hostbase/models.py b/src/lib/Bcfg2/Server/Hostbase/hostbase/models.py
deleted file mode 100644
index 3f08a09a0..000000000
--- a/src/lib/Bcfg2/Server/Hostbase/hostbase/models.py
+++ /dev/null
@@ -1,210 +0,0 @@
-from django.db import models
-
-# Create your models here.
-class Host(models.Model):
- NETGROUP_CHOICES = (
- ('none', 'none'),('cave', 'cave'),('ccst', 'ccst'),('mcs', 'mcs'),
- ('mmlab', 'mmlab'),('sp', 'sp'),('red', 'red'),('virtual', 'virtual'),
- ('win', 'win'),('xterm', 'xterm'),('lcrc', 'lcrc'),('anlext', 'anlext'),
- ('teragrid', 'teragrid')
- )
- STATUS_CHOICES = (
- ('active','active'),('dormant','dormant')
- )
- SUPPORT_CHOICES = (
- ('green','green'),('yellow','yellow'),('red','red')
- )
- CLASS_CHOICES = (
- ('scientific','scientific'),
- ('operations','operations'),('guest','guest'),
- ('confidential','confidential'),('public','public')
- )
- WHATAMI_CHOICES = (
- ('aix-3', 'aix-3'), ('aix-4', 'aix-4'),
- ('aix-5', 'aix-5'), ('baytech', 'baytech'),
- ('decserver', 'decserver'), ('dialup', 'dialup'),
- ('dos', 'dos'), ('freebsd', 'freebsd'),
- ('hpux', 'hpux'), ('irix-5', 'irix-5'),
- ('irix-6', 'irix-6'), ('linux', 'linux'),
- ('linux-2', 'linux-2'), ('linux-rh73', 'linux-rh73'),
- ('linux-rh8', 'linux-rh8'), ('linux-sles8', 'linux-sles8'),
- ('linux-sles8-64', 'linux-sles8-64'), ('linux-sles8-ia32', 'linux-sles8-ia32'),
- ('linux-sles8-ia64', 'linux-sles8-ia64'), ('mac', 'mac'),
- ('network', 'network'), ('next', 'next'),
- ('none', 'none'), ('osf', 'osf'), ('printer', 'printer'),
- ('robot', 'robot'), ('solaris-2', 'solaris-2'),
- ('sun4', 'sun4'), ('unknown', 'unknown'), ('virtual', 'virtual'),
- ('win31', 'win31'), ('win95', 'win95'),
- ('winNTs', 'winNTs'), ('winNTw', 'winNTw'),
- ('win2k', 'win2k'), ('winXP', 'winXP'), ('xterm', 'xterm')
- )
- hostname = models.CharField(max_length=64)
- whatami = models.CharField(max_length=16)
- netgroup = models.CharField(max_length=32, choices=NETGROUP_CHOICES)
- security_class = models.CharField('class', max_length=16)
- support = models.CharField(max_length=8, choices=SUPPORT_CHOICES)
- csi = models.CharField(max_length=32, blank=True)
- printq = models.CharField(max_length=32, blank=True)
- outbound_smtp = models.BooleanField()
- primary_user = models.EmailField()
- administrator = models.EmailField(blank=True)
- location = models.CharField(max_length=16)
- comments = models.TextField(blank=True)
- expiration_date = models.DateField(null=True, blank=True)
- last = models.DateField(auto_now=True, auto_now_add=True)
- status = models.CharField(max_length=7, choices=STATUS_CHOICES)
- dirty = models.BooleanField()
-
- class Admin:
- list_display = ('hostname', 'last')
- search_fields = ['hostname']
-
- def __str__(self):
- return self.hostname
-
- def get_logs(self):
- """
- Get host's log.
- """
- return Log.objects.filter(hostname=self.hostname)
-
-class Interface(models.Model):
- TYPE_CHOICES = (
- ('eth', 'ethernet'), ('wl', 'wireless'), ('virtual', 'virtual'), ('myr', 'myr'),
- ('mgmt', 'mgmt'), ('tape', 'tape'), ('fe', 'fe'), ('ge', 'ge'),
- )
- # FIXME: The new admin interface has change a lot.
- #host = models.ForeignKey(Host, edit_inline=models.TABULAR, num_in_admin=2)
- host = models.ForeignKey(Host)
- # FIXME: The new admin interface has change a lot.
- #mac_addr = models.CharField(max_length=32, core=True)
- mac_addr = models.CharField(max_length=32)
- hdwr_type = models.CharField('type', max_length=16, choices=TYPE_CHOICES, blank=True)
- # FIXME: The new admin interface has change a lot.
- # radio_admin=True, blank=True)
- dhcp = models.BooleanField()
-
- def __str__(self):
- return self.mac_addr
-
- class Admin:
- list_display = ('mac_addr', 'host')
- search_fields = ['mac_addr']
-
-class IP(models.Model):
- interface = models.ForeignKey(Interface)
- # FIXME: The new admin interface has change a lot.
- # edit_inline=models.TABULAR, num_in_admin=1)
- #ip_addr = models.IPAddressField(core=True)
- ip_addr = models.IPAddressField()
-
- def __str__(self):
- return self.ip_addr
-
- class Admin:
- pass
-
- class Meta:
- ordering = ('ip_addr', )
-
-class MX(models.Model):
- priority = models.IntegerField(blank=True)
- # FIXME: The new admin interface has change a lot.
- #mx = models.CharField(max_length=64, blank=True, core=True)
- mx = models.CharField(max_length=64, blank=True)
-
- def __str__(self):
- return (" ".join([str(self.priority), self.mx]))
-
- class Admin:
- pass
-
-class Name(models.Model):
- DNS_CHOICES = (
- ('global','global'),('internal','ANL internal'),
- ('private','private')
- )
- # FIXME: The new admin interface has change a lot.
- #ip = models.ForeignKey(IP, edit_inline=models.TABULAR, num_in_admin=1)
- ip = models.ForeignKey(IP)
- # FIXME: The new admin interface has change a lot.
- #name = models.CharField(max_length=64, core=True)
- name = models.CharField(max_length=64)
- dns_view = models.CharField(max_length=16, choices=DNS_CHOICES)
- only = models.BooleanField(blank=True)
- mxs = models.ManyToManyField(MX)
-
- def __str__(self):
- return self.name
-
- class Admin:
- pass
-
-class CName(models.Model):
- # FIXME: The new admin interface has change a lot.
- #name = models.ForeignKey(Name, edit_inline=models.TABULAR, num_in_admin=1)
- name = models.ForeignKey(Name)
- # FIXME: The new admin interface has change a lot.
- #cname = models.CharField(max_length=64, core=True)
- cname = models.CharField(max_length=64)
-
- def __str__(self):
- return self.cname
-
- class Admin:
- pass
-
-class Nameserver(models.Model):
- name = models.CharField(max_length=64, blank=True)
-
- def __str__(self):
- return self.name
-
- class Admin:
- pass
-
-class ZoneAddress(models.Model):
- ip_addr = models.IPAddressField(blank=True)
-
- def __str__(self):
- return self.ip_addr
-
- class Admin:
- pass
-
-class Zone(models.Model):
- zone = models.CharField(max_length=64)
- serial = models.IntegerField()
- admin = models.CharField(max_length=64)
- primary_master = models.CharField(max_length=64)
- expire = models.IntegerField()
- retry = models.IntegerField()
- refresh = models.IntegerField()
- ttl = models.IntegerField()
- nameservers = models.ManyToManyField(Nameserver, blank=True)
- mxs = models.ManyToManyField(MX, blank=True)
- addresses = models.ManyToManyField(ZoneAddress, blank=True)
- aux = models.TextField(blank=True)
-
- def __str__(self):
- return self.zone
-
- class Admin:
- pass
-
-class Log(models.Model):
- # FIXME: Proposal hostname = models.ForeignKey(Host)
- hostname = models.CharField(max_length=64)
- date = models.DateTimeField(auto_now=True, auto_now_add=True)
- log = models.TextField()
-
- def __str__(self):
- return self.hostname
-
-class ZoneLog(models.Model):
- zone = models.CharField(max_length=64)
- date = models.DateTimeField(auto_now=True, auto_now_add=True)
- log = models.TextField()
-
- def __str__(self):
- return self.zone
diff --git a/src/lib/Bcfg2/Server/Hostbase/hostbase/sql/zone.sql b/src/lib/Bcfg2/Server/Hostbase/hostbase/sql/zone.sql
deleted file mode 100644
index b78187ab2..000000000
--- a/src/lib/Bcfg2/Server/Hostbase/hostbase/sql/zone.sql
+++ /dev/null
@@ -1,2 +0,0 @@
-INSERT INTO hostbase_zone (zone, serial, admin, primary_master, expire, retry, refresh, ttl, aux)
-VALUES ('.rev', 0, '', '', 1209600, 1800, 7200, 7200, ''); \ No newline at end of file
diff --git a/src/lib/Bcfg2/Server/Hostbase/hostbase/urls.py b/src/lib/Bcfg2/Server/Hostbase/hostbase/urls.py
deleted file mode 100644
index 0ee204abe..000000000
--- a/src/lib/Bcfg2/Server/Hostbase/hostbase/urls.py
+++ /dev/null
@@ -1,68 +0,0 @@
-# -*- coding: utf-8 -*-
-from django.conf.urls.defaults import *
-from django.contrib.auth.decorators import login_required
-from django.core.urlresolvers import reverse
-from django.views.generic.create_update import create_object, update_object, delete_object
-from django.views.generic.list_detail import object_detail, object_list
-
-from models import Host, Zone, Log
-
-host_detail_dict = {
- 'queryset':Host.objects.all(),
- 'template_name':'host.html',
- 'template_object_name':'host',
-}
-
-host_delete_dict = {
- 'model':Host,
- 'post_delete_redirect':'/',
-}
-
-host_log_detail_dict = host_detail_dict.copy()
-host_log_detail_dict['template_name'] = 'logviewer.html'
-
-host_dns_detail_dict = host_detail_dict.copy()
-host_dns_detail_dict['template_name'] = 'dns.html'
-
-zone_new_dict = {
- 'model':Zone,
- 'template_name':'zonenew.html',
- 'post_save_redirect':'../%(id)s',
-}
-
-zones_list_dict = {
- 'queryset':Zone.objects.all(),
- 'template_name':'zones.html',
- 'template_object_name':'zone',
-}
-
-zone_detail_dict = {
- 'queryset':Zone.objects.all(),
- 'template_name':'zoneview.html',
- 'template_object_name':'zone',
-}
-
-urlpatterns = patterns('',
- (r'^(?P<object_id>\d+)/$', object_detail, host_detail_dict, 'host_detail'),
- (r'^zones/new/$', login_required(create_object), zone_new_dict, 'zone_new'),
- (r'^zones/(?P<object_id>\d+)/edit', login_required(update_object), zone_new_dict, 'zone_edit'),
- (r'^zones/$', object_list, zones_list_dict, 'zone_list'),
- (r'^zones/(?P<object_id>\d+)/$', object_detail, zone_detail_dict, 'zone_detail'),
- (r'^zones/(?P<object_id>\d+)/$', object_detail, zone_detail_dict, 'zone_detail'),
- (r'^\d+/logs/(?P<object_id>\d+)/', object_detail, { 'queryset':Log.objects.all() }, 'log_detail'),
- (r'^(?P<object_id>\d+)/logs/', object_detail, host_log_detail_dict, 'host_log_list'),
- (r'^(?P<object_id>\d+)/dns', object_detail, host_dns_detail_dict, 'host_dns_list'),
- (r'^(?P<object_id>\d+)/remove', login_required(delete_object), host_delete_dict, 'host_delete'),
-)
-
-urlpatterns += patterns('Bcfg2.Server.Hostbase.hostbase.views',
- (r'^$', 'search'),
- (r'^(?P<host_id>\d+)/edit', 'edit'),
- (r'^(?P<host_id>\d+)/(?P<item>\D+)/(?P<item_id>\d+)/confirm', 'confirm'),
- (r'^(?P<host_id>\d+)/(?P<item>\D+)/(?P<item_id>\d+)/(?P<name_id>\d+)/confirm', 'confirm'),
- (r'^(?P<host_id>\d+)/dns/edit', 'dnsedit'),
- (r'^new', 'new'),
- (r'^(?P<host_id>\d+)/copy', 'copy'),
-# (r'^hostinfo', 'hostinfo'),
- (r'^zones/(?P<zone_id>\d+)/(?P<item>\D+)/(?P<item_id>\d+)/confirm', 'confirm'),
-)
diff --git a/src/lib/Bcfg2/Server/Hostbase/hostbase/views.py b/src/lib/Bcfg2/Server/Hostbase/hostbase/views.py
deleted file mode 100644
index 57ef5eff8..000000000
--- a/src/lib/Bcfg2/Server/Hostbase/hostbase/views.py
+++ /dev/null
@@ -1,970 +0,0 @@
-"""Views.py
-Contains all the views associated with the hostbase app
-Also has does form validation
-"""
-from django.http import HttpResponse, HttpResponseRedirect
-
-from django.contrib.auth.decorators import login_required
-from django.contrib.auth import logout
-from django.template import RequestContext
-from Bcfg2.Server.Hostbase.hostbase.models import *
-from datetime import date
-from django.db import connection
-from django.shortcuts import render_to_response
-from django import forms
-from Bcfg2.Server.Hostbase import settings, regex
-import re, copy
-
-attribs = ['hostname', 'whatami', 'netgroup', 'security_class', 'support',
- 'csi', 'printq', 'primary_user', 'administrator', 'location',
- 'status', 'comments']
-
-zoneattribs = ['zone', 'admin', 'primary_master', 'expire', 'retry',
- 'refresh', 'ttl', 'aux']
-
-dispatch = {'mac_addr':'i.mac_addr LIKE \'%%%%%s%%%%\'',
- 'ip_addr':'p.ip_addr LIKE \'%%%%%s%%%%\'',
- 'name':'n.name LIKE \'%%%%%s%%%%\'',
-## 'hostname':'n.name LIKE \'%%%%%s%%%%\'',
-## 'cname':'n.name LIKE \'%%%%%s%%%%\'',
- 'mx':'m.mx LIKE \'%%%%%s%%%%\'',
- 'dns_view':'n.dns_view = \'%s\'',
- 'hdwr_type':'i.hdwr_type = \'%s\'',
- 'dhcp':'i.dhcp = \'%s\''}
-
-def search(request):
- """Search for hosts in the database
- If more than one field is entered, logical AND is used
- """
- if 'sub' in request.GET:
- querystring = """SELECT DISTINCT h.hostname, h.id, h.status
- 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 n.id = x.name_id)
- INNER JOIN hostbase_mx m ON m.id = x.mx_id)
- LEFT JOIN hostbase_cname c ON n.id = c.name_id
- WHERE """
-
- _and = False
- for field in request.POST:
- if request.POST[field] and field == 'hostname':
- if _and:
- querystring += ' AND '
- querystring += 'n.name LIKE \'%%%%%s%%%%\' or c.cname LIKE \'%%%%%s%%%%\'' % (request.POST[field], request.POST[field])
- _and = True
- elif request.POST[field] and field in dispatch:
- if _and:
- querystring += ' AND '
- querystring += dispatch[field] % request.POST[field]
- _and = True
- elif request.POST[field]:
- if _and:
- querystring += ' AND '
- querystring += "h.%s LIKE \'%%%%%s%%%%\'" % (field, request.POST[field])
- _and = True
-
- if not _and:
- cursor = connection.cursor()
- cursor.execute("""SELECT hostname, id, status
- FROM hostbase_host ORDER BY hostname""")
- results = cursor.fetchall()
- else:
- querystring += " ORDER BY h.hostname"
- cursor = connection.cursor()
- cursor.execute(querystring)
- results = cursor.fetchall()
-
- return render_to_response('results.html',
- {'hosts': results,
- 'logged_in': request.session.get('_auth_user_id', False)},
- context_instance = RequestContext(request))
- else:
- return render_to_response('search.html',
- {'TYPE_CHOICES': Interface.TYPE_CHOICES,
- 'DNS_CHOICES': Name.DNS_CHOICES,
- 'yesno': [(1, 'yes'), (0, 'no')],
- 'logged_in': request.session.get('_auth_user_id', False)},
- context_instance = RequestContext(request))
-
-
-def gethostdata(host_id, dnsdata=False):
- """Grabs the necessary data about a host
- Replaces a lot of repeated code"""
- hostdata = {}
- hostdata['ips'] = {}
- hostdata['names'] = {}
- hostdata['cnames'] = {}
- hostdata['mxs'] = {}
- hostdata['host'] = Host.objects.get(id=host_id)
- hostdata['interfaces'] = hostdata['host'].interface_set.all()
- for interface in hostdata['interfaces']:
- hostdata['ips'][interface.id] = interface.ip_set.all()
- if dnsdata:
- for ip in hostdata['ips'][interface.id]:
- hostdata['names'][ip.id] = ip.name_set.all()
- for name in hostdata['names'][ip.id]:
- hostdata['cnames'][name.id] = name.cname_set.all()
- hostdata['mxs'][name.id] = name.mxs.all()
- return hostdata
-
-def fill(template, hostdata, dnsdata=False):
- """Fills a generic template
- Replaces a lot of repeated code"""
- if dnsdata:
- template.names = hostdata['names']
- template.cnames = hostdata['cnames']
- template.mxs = hostdata['mxs']
- template.host = hostdata['host']
- template.interfaces = hostdata['interfaces']
- template.ips = hostdata['ips']
- return template
-
-def edit(request, host_id):
- """edit general host information"""
- manipulator = Host.ChangeManipulator(host_id)
- changename = False
- if request.method == 'POST':
- host = Host.objects.get(id=host_id)
- before = host.__dict__.copy()
- if request.POST['hostname'] != host.hostname:
- oldhostname = host.hostname.split(".")[0]
- changename = True
- interfaces = host.interface_set.all()
- old_interfaces = [interface.__dict__.copy() for interface in interfaces]
-
- new_data = request.POST.copy()
-
- errors = manipulator.get_validation_errors(new_data)
- if not errors:
-
- # somehow keep track of multiple interface change manipulators
- # as well as multiple ip chnage manipulators??? (add manipulators???)
- # change to many-to-many??????
-
- # dynamically look up mx records?
- text = ''
-
- for attrib in attribs:
- if host.__dict__[attrib] != request.POST[attrib]:
- text = do_log(text, attrib, host.__dict__[attrib], request.POST[attrib])
- host.__dict__[attrib] = request.POST[attrib]
-
- if 'expiration_date' in request.POST:
- ymd = request.POST['expiration_date'].split("-")
- if date(int(ymd[0]), int(ymd[1]), int(ymd[2])) != host.__dict__['expiration_date']:
- text = do_log(text, 'expiration_date', host.__dict__['expiration_date'],
- request.POST['expiration_date'])
- host.__dict__['expiration_date'] = date(int(ymd[0]), int(ymd[1]), int(ymd[2]))
-
- for inter in interfaces:
- changetype = False
- ips = IP.objects.filter(interface=inter.id)
- if inter.mac_addr != request.POST['mac_addr%d' % inter.id]:
- text = do_log(text, 'mac_addr', inter.mac_addr, request.POST['mac_addr%d' % inter.id])
- inter.mac_addr = request.POST['mac_addr%d' % inter.id].lower().replace('-',':')
- if inter.hdwr_type != request.POST['hdwr_type%d' % inter.id]:
- oldtype = inter.hdwr_type
- text = do_log(text, 'hdwr_type', oldtype, request.POST['hdwr_type%d' % inter.id])
- inter.hdwr_type = request.POST['hdwr_type%d' % inter.id]
- changetype = True
- if (('dhcp%d' % inter.id) in request.POST and not inter.dhcp or
- not ('dhcp%d' % inter.id) in request.POST and inter.dhcp):
- text = do_log(text, 'dhcp', inter.dhcp, int(not inter.dhcp))
- inter.dhcp = not inter.dhcp
- for ip in ips:
- names = ip.name_set.all()
- if not ip.ip_addr == request.POST['ip_addr%d' % ip.id]:
- oldip = ip.ip_addr
- oldsubnet = oldip.split(".")[2]
- ip.ip_addr = request.POST['ip_addr%d' % ip.id]
- ip.save()
- text = do_log(text, 'ip_addr', oldip, ip.ip_addr)
- for name in names:
- if name.name.split(".")[0].endswith('-%s' % oldsubnet):
- name.name = name.name.replace('-%s' % oldsubnet, '-%s' % ip.ip_addr.split(".")[2])
- name.save()
- if changetype:
- for name in names:
- if name.name.split(".")[0].endswith('-%s' % oldtype):
- name.name = name.name.replace('-%s' % oldtype, '-%s' % inter.hdwr_type)
- name.save()
- if changename:
- for name in names:
- if name.name.startswith(oldhostname):
- name.name = name.name.replace(oldhostname, host.hostname.split(".")[0])
- name.save()
- if request.POST['%dip_addr' % inter.id]:
- mx, created = MX.objects.get_or_create(priority=settings.PRIORITY, mx=settings.DEFAULT_MX)
- if created:
- mx.save()
- new_ip = IP(interface=inter, ip_addr=request.POST['%dip_addr' % inter.id])
- new_ip.save()
- text = do_log(text, '*new*', 'ip_addr', new_ip.ip_addr)
- new_name = "-".join([host.hostname.split(".")[0],
- new_ip.ip_addr.split(".")[2]])
- new_name += "." + host.hostname.split(".", 1)[1]
- name = Name(ip=new_ip, name=new_name,
- dns_view='global', only=False)
- name.save()
- name.mxs.add(mx)
- new_name = "-".join([host.hostname.split(".")[0],
- inter.hdwr_type])
- new_name += "." + host.hostname.split(".", 1)[1]
- name = Name(ip=new_ip, name=new_name,
- dns_view='global', only=False)
- name.save()
- name.mxs.add(mx)
- name = Name(ip=new_ip, name=host.hostname,
- dns_view='global', only=False)
- name.save()
- name.mxs.add(mx)
- inter.save()
- if request.POST['mac_addr_new']:
- new_inter = Interface(host=host,
- mac_addr=request.POST['mac_addr_new'].lower().replace('-',':'),
- hdwr_type=request.POST['hdwr_type_new'],
- dhcp=request.POST['dhcp_new'])
- text = do_log(text, '*new*', 'mac_addr', new_inter.mac_addr)
- new_inter.save()
- if request.POST['mac_addr_new'] and request.POST['ip_addr_new']:
- mx, created = MX.objects.get_or_create(priority=settings.PRIORITY, mx=settings.DEFAULT_MX)
- if created:
- mx.save()
- new_ip = IP(interface=new_inter, ip_addr=request.POST['ip_addr_new'])
- new_ip.save()
- text = do_log(text, '*new*', 'ip_addr', new_ip.ip_addr)
- new_name = "-".join([host.hostname.split(".")[0],
- new_ip.ip_addr.split(".")[2]])
- new_name += "." + host.hostname.split(".", 1)[1]
- name = Name(ip=new_ip, name=new_name,
- dns_view='global', only=False)
- name.save()
- name.mxs.add(mx)
- new_name = "-".join([host.hostname.split(".")[0],
- new_inter.hdwr_type])
- new_name += "." + host.hostname.split(".", 1)[1]
- name = Name(ip=new_ip, name=new_name,
- dns_view='global', only=False)
- name.save()
- name.mxs.add(mx)
- name = Name(ip=new_ip, name=host.hostname,
- dns_view='global', only=False)
- name.save()
- name.mxs.add(mx)
- if request.POST['ip_addr_new'] and not request.POST['mac_addr_new']:
- mx, created = MX.objects.get_or_create(priority=settings.PRIORITY, mx=settings.DEFAULT_MX)
- if created:
- mx.save()
- new_inter = Interface(host=host, mac_addr="",
- hdwr_type=request.POST['hdwr_type_new'],
- dhcp=False)
- new_inter.save()
- new_ip = IP(interface=new_inter, ip_addr=request.POST['ip_addr_new'])
- new_ip.save()
- text = do_log(text, '*new*', 'ip_addr', new_ip.ip_addr)
- new_name = "-".join([host.hostname.split(".")[0],
- new_ip.ip_addr.split(".")[2]])
- new_name += "." + host.hostname.split(".", 1)[1]
- name = Name(ip=new_ip, name=new_name,
- dns_view='global', only=False)
- name.save()
- name.mxs.add(mx)
- new_name = "-".join([host.hostname.split(".")[0],
- new_inter.hdwr_type])
- new_name += "." + host.hostname.split(".", 1)[1]
- name = Name(ip=new_ip, name=new_name,
- dns_view='global', only=False)
- name.save()
- name.mxs.add(mx)
- name = Name(ip=new_ip, name=host.hostname,
- dns_view='global', only=False)
- name.save()
- name.mxs.add(mx)
- if text:
- log = Log(hostname=host.hostname, log=text)
- log.save()
- host.save()
- return HttpResponseRedirect('/hostbase/%s/' % host.id)
- else:
- return render_to_response('errors.html',
- {'failures': errors,
- 'logged_in': request.session.get('_auth_user_id', False)},
- context_instance = RequestContext(request))
- else:
- host = Host.objects.get(id=host_id)
- interfaces = []
- for interface in host.interface_set.all():
- interfaces.append([interface, interface.ip_set.all()])
- return render_to_response('edit.html',
- {'host': host,
- 'interfaces': interfaces,
- 'TYPE_CHOICES': Interface.TYPE_CHOICES,
- 'logged_in': request.session.get('_auth_user_id', False)},
- context_instance = RequestContext(request))
-
-def confirm(request, item, item_id, host_id=None, name_id=None, zone_id=None):
- """Asks if the user is sure he/she wants to remove an item"""
- if 'sub' in request.GET:
- if item == 'interface':
- for ip in Interface.objects.get(id=item_id).ip_set.all():
- for name in ip.name_set.all():
- name.cname_set.all().delete()
- ip.name_set.all().delete()
- Interface.objects.get(id=item_id).ip_set.all().delete()
- Interface.objects.get(id=item_id).delete()
- elif item=='ip':
- for name in IP.objects.get(id=item_id).name_set.all():
- name.cname_set.all().delete()
- IP.objects.get(id=item_id).name_set.all().delete()
- IP.objects.get(id=item_id).delete()
- elif item=='cname':
- CName.objects.get(id=item_id).delete()
- elif item=='mx':
- mx = MX.objects.get(id=item_id)
- Name.objects.get(id=name_id).mxs.remove(mx)
- elif item=='name':
- Name.objects.get(id=item_id).cname_set.all().delete()
- Name.objects.get(id=item_id).delete()
- elif item=='nameserver':
- nameserver = Nameserver.objects.get(id=item_id)
- Zone.objects.get(id=zone_id).nameservers.remove(nameserver)
- elif item=='zonemx':
- mx = MX.objects.get(id=item_id)
- Zone.objects.get(id=zone_id).mxs.remove(mx)
- elif item=='address':
- address = ZoneAddress.objects.get(id=item_id)
- Zone.objects.get(id=zone_id).addresses.remove(address)
- if item == 'cname' or item == 'mx' or item == 'name':
- return HttpResponseRedirect('/hostbase/%s/dns/edit' % host_id)
- elif item == 'nameserver' or item == 'zonemx' or item == 'address':
- return HttpResponseRedirect('/hostbase/zones/%s/edit' % zone_id)
- else:
- return HttpResponseRedirect('/hostbase/%s/edit' % host_id)
- else:
- interface = None
- ips = []
- names = []
- cnames = []
- mxs = []
- zonemx = None
- nameserver = None
- address = None
- if item == 'interface':
- interface = Interface.objects.get(id=item_id)
- ips = interface.ip_set.all()
- for ip in ips:
- for name in ip.name_set.all():
- names.append((ip.id, name))
- for cname in name.cname_set.all():
- cnames.append((name.id, cname))
- for mx in name.mxs.all():
- mxs.append((name.id, mx))
- elif item=='ip':
- ips = [IP.objects.get(id=item_id)]
- for name in ips[0].name_set.all():
- names.append((ips[0].id, name))
- for cname in name.cname_set.all():
- cnames.append((name.id, cname))
- for mx in name.mxs.all():
- mxs.append((name.id, mx))
- elif item=='name':
- names = [Name.objects.get(id=item_id)]
- for cname in names[0].cname_set.all():
- cnames.append((names[0].id, cname))
- for mx in names[0].mxs.all():
- mxs.append((names[0].id, mx))
- elif item=='cname':
- cnames = [CName.objects.get(id=item_id)]
- elif item=='mx':
- mxs = [MX.objects.get(id=item_id)]
- elif item=='zonemx':
- zonemx = MX.objects.get(id=item_id)
- elif item=='nameserver':
- nameserver = Nameserver.objects.get(id=item_id)
- elif item=='address':
- address = ZoneAddress.objects.get(id=item_id)
- return render_to_response('confirm.html',
- {'interface': interface,
- 'ips': ips,
- 'names': names,
- 'cnames': cnames,
- 'id': item_id,
- 'type': item,
- 'host_id': host_id,
- 'mxs': mxs,
- 'zonemx': zonemx,
- 'nameserver': nameserver,
- 'address': address,
- 'zone_id': zone_id,
- 'logged_in': request.session.get('_auth_user_id', False)},
- context_instance = RequestContext(request))
-
-def dnsedit(request, host_id):
- """Edits specific DNS information
- Data is validated before committed to the database"""
- text = ''
- if 'sub' in request.GET:
- hostdata = gethostdata(host_id, True)
- for ip in hostdata['names']:
- ipaddr = IP.objects.get(id=ip)
- ipaddrstr = ipaddr.__str__()
- for name in hostdata['cnames']:
- for cname in hostdata['cnames'][name]:
- if regex.host.match(request.POST['cname%d' % cname.id]):
- text = do_log(text, 'cname', cname.cname, request.POST['cname%d' % cname.id])
- cname.cname = request.POST['cname%d' % cname.id]
- cname.save()
- for name in hostdata['mxs']:
- for mx in hostdata['mxs'][name]:
- if (mx.priority != request.POST['priority%d' % mx.id] and mx.mx != request.POST['mx%d' % mx.id]):
- text = do_log(text, 'mx', ' '.join([str(mx.priority), str(mx.mx)]),
- ' '.join([request.POST['priority%d' % mx.id], request.POST['mx%d' % mx.id]]))
- nameobject = Name.objects.get(id=name)
- nameobject.mxs.remove(mx)
- newmx, created = MX.objects.get_or_create(priority=request.POST['priority%d' % mx.id], mx=request.POST['mx%d' % mx.id])
- if created:
- newmx.save()
- nameobject.mxs.add(newmx)
- nameobject.save()
- for name in hostdata['names'][ip]:
- name.name = request.POST['name%d' % name.id]
- name.dns_view = request.POST['dns_view%d' % name.id]
- if (request.POST['%dcname' % name.id] and
- regex.host.match(request.POST['%dcname' % name.id])):
- cname = CName(name=name,
- cname=request.POST['%dcname' % name.id])
- text = do_log(text, '*new*', 'cname', cname.cname)
- cname.save()
- if (request.POST['%dpriority' % name.id] and
- request.POST['%dmx' % name.id]):
- mx, created = MX.objects.get_or_create(priority=request.POST['%dpriority' % name.id],
- mx=request.POST['%dmx' % name.id])
- if created:
- mx.save()
- text = do_log(text, '*new*', 'mx',
- ' '.join([request.POST['%dpriority' % name.id],
- request.POST['%dmx' % name.id]]))
- name.mxs.add(mx)
- name.save()
- if request.POST['%sname' % ipaddrstr]:
- name = Name(ip=ipaddr,
- dns_view=request.POST['%sdns_view' % ipaddrstr],
- name=request.POST['%sname' % ipaddrstr], only=False)
- text = do_log(text, '*new*', 'name', name.name)
- name.save()
- if (request.POST['%scname' % ipaddrstr] and
- regex.host.match(request.POST['%scname' % ipaddrstr])):
- cname = CName(name=name,
- cname=request.POST['%scname' % ipaddrstr])
- text = do_log(text, '*new*', 'cname', cname.cname)
- cname.save()
- if (request.POST['%smx' % ipaddrstr] and
- request.POST['%spriority' % ipaddrstr]):
- mx, created = MX.objects.get_or_create(priority=request.POST['%spriority' % ipaddrstr],
- mx=request.POST['%smx' % ipaddrstr])
- if created:
- mx.save()
- text = do_log(text, '*new*', 'mx',
- ' '.join([request.POST['%spriority' % ipaddrstr], request.POST['%smx' % ipaddrstr]]))
- name.mxs.add(mx)
- if text:
- log = Log(hostname=hostdata['host'].hostname, log=text)
- log.save()
- return HttpResponseRedirect('/hostbase/%s/dns' % host_id)
- else:
- host = Host.objects.get(id=host_id)
- ips = []
- info = []
- cnames = []
- mxs = []
- interfaces = host.interface_set.all()
- for interface in host.interface_set.all():
- ips.extend(interface.ip_set.all())
- for ip in ips:
- info.append([ip, ip.name_set.all()])
- for name in ip.name_set.all():
- cnames.extend(name.cname_set.all())
- mxs.append((name.id, name.mxs.all()))
- return render_to_response('dnsedit.html',
- {'host': host,
- 'info': info,
- 'cnames': cnames,
- 'mxs': mxs,
- 'request': request,
- 'interfaces': interfaces,
- 'DNS_CHOICES': Name.DNS_CHOICES,
- 'logged_in': request.session.get('_auth_user_id', False)},
- context_instance = RequestContext(request))
-
-def new(request):
- """Function for creating a new host in hostbase
- Data is validated before committed to the database"""
- if 'sub' in request.GET:
- try:
- Host.objects.get(hostname=request.POST['hostname'].lower())
- return render_to_response('errors.html',
- {'failures': ['%s already exists in hostbase' % request.POST['hostname']],
- 'logged_in': request.session.get('_auth_user_id', False)},
- context_instance = RequestContext(request))
- except:
- pass
- if not validate(request, True):
- if not request.POST['ip_addr_new'] and not request.POST['ip_addr_new2']:
- return render_to_response('errors.html',
- {'failures': ['ip_addr: You must enter an ip address'],
- 'logged_in': request.session.get('_auth_user_id', False)},
- context_instance = RequestContext(request))
- host = Host()
- # this is the stuff that validate() should take care of
- # examine the check boxes for any changes
- host.outbound_smtp = 'outbound_smtp' in request.POST
- for attrib in attribs:
- if attrib in request.POST:
- host.__dict__[attrib] = request.POST[attrib].lower()
- if 'comments' in request.POST:
- host.comments = request.POST['comments']
- if 'expiration_date' in request.POST:
-# ymd = request.POST['expiration_date'].split("-")
-# host.__dict__['expiration_date'] = date(int(ymd[0]), int(ymd[1]), int(ymd[2]))
- host.__dict__['expiration_date'] = date(2000, 1, 1)
- host.status = 'active'
- host.save()
- else:
- return render_to_response('errors.html',
- {'failures': validate(request, True),
- 'logged_in': request.session.get('_auth_user_id', False)},
- context_instance = RequestContext(request))
-
- if request.POST['mac_addr_new']:
- new_inter = Interface(host=host,
- mac_addr = request.POST['mac_addr_new'].lower().replace('-',':'),
- hdwr_type = request.POST['hdwr_type_new'],
- dhcp = 'dhcp_new' in request.POST)
- new_inter.save()
- if request.POST['mac_addr_new'] and request.POST['ip_addr_new']:
- new_ip = IP(interface=new_inter, ip_addr=request.POST['ip_addr_new'])
-# Change all this things. Use a "post_save" signal handler for model Host to create all sociate models
-# and use a generi view.
- new_ip.save()
- mx, created = MX.objects.get_or_create(priority=settings.PRIORITY, mx=settings.DEFAULT_MX)
- if created:
- mx.save()
- new_name = "-".join([host.hostname.split(".")[0],
- new_ip.ip_addr.split(".")[2]])
- new_name += "." + host.hostname.split(".", 1)[1]
- name = Name(ip=new_ip, name=new_name, dns_view='global', only=False)
- name.save()
- name.mxs.add(mx)
- new_name = "-".join([host.hostname.split(".")[0],
- new_inter.hdwr_type])
- new_name += "." + host.hostname.split(".", 1)[1]
- name = Name(ip=new_ip, name=new_name,
- dns_view='global', only=False)
- name.save()
- name.mxs.add(mx)
- name = Name(ip=new_ip, name=host.hostname,
- dns_view='global', only=False)
- name.save()
- name.mxs.add(mx)
- if request.POST['ip_addr_new'] and not request.POST['mac_addr_new']:
- new_inter = Interface(host=host,
- mac_addr="",
- hdwr_type=request.POST['hdwr_type_new'],
- dhcp=False)
- new_inter.save()
- new_ip = IP(interface=new_inter, ip_addr=request.POST['ip_addr_new'])
- new_ip.save()
- mx, created = MX.objects.get_or_create(priority=settings.PRIORITY, mx=settings.DEFAULT_MX)
- if created:
- mx.save()
- new_name = "-".join([host.hostname.split(".")[0],
- new_ip.ip_addr.split(".")[2]])
- new_name += "." + host.hostname.split(".", 1)[1]
- name = Name(ip=new_ip, name=new_name,
- dns_view='global', only=False)
- name.save()
- name.mxs.add(mx)
- new_name = "-".join([host.hostname.split(".")[0],
- new_inter.hdwr_type])
- new_name += "." + host.hostname.split(".", 1)[1]
- name = Name(ip=new_ip, name=new_name,
- dns_view='global', only=False)
- name.save()
- name.mxs.add(mx)
- name = Name(ip=new_ip, name=host.hostname,
- dns_view='global', only=False)
- name.save()
- name.mxs.add(mx)
- if request.POST['mac_addr_new2']:
- new_inter = Interface(host=host,
- mac_addr = request.POST['mac_addr_new2'].lower().replace('-',':'),
- hdwr_type = request.POST['hdwr_type_new2'],
- dhcp = 'dhcp_new2' in request.POST)
- new_inter.save()
- if request.POST['mac_addr_new2'] and request.POST['ip_addr_new2']:
- new_ip = IP(interface=new_inter, ip_addr=request.POST['ip_addr_new2'])
- new_ip.save()
- mx, created = MX.objects.get_or_create(priority=settings.PRIORITY, mx=settings.DEFAULT_MX)
- if created:
- mx.save()
- new_name = "-".join([host.hostname.split(".")[0],
- new_ip.ip_addr.split(".")[2]])
- new_name += "." + host.hostname.split(".", 1)[1]
- name = Name(ip=new_ip, name=new_name,
- dns_view='global', only=False)
- name.save()
- name.mxs.add(mx)
- new_name = "-".join([host.hostname.split(".")[0],
- new_inter.hdwr_type])
- new_name += "." + host.hostname.split(".", 1)[1]
- name = Name(ip=new_ip, name=new_name,
- dns_view='global', only=False)
- name.save()
- name.mxs.add(mx)
- name = Name(ip=new_ip, name=host.hostname,
- dns_view='global', only=False)
- name.save()
- name.mxs.add(mx)
- if request.POST['ip_addr_new2'] and not request.POST['mac_addr_new2']:
- new_inter = Interface(host=host,
- mac_addr="",
- hdwr_type=request.POST['hdwr_type_new2'],
- dhcp=False)
- new_inter.save()
- new_ip = IP(interface=new_inter, ip_addr=request.POST['ip_addr_new2'])
- new_ip.save()
- mx, created = MX.objects.get_or_create(priority=settings.PRIORITY, mx=settings.DEFAULT_MX)
- if created:
- mx.save()
- new_name = "-".join([host.hostname.split(".")[0],
- new_ip.ip_addr.split(".")[2]])
- new_name += "." + host.hostname.split(".", 1)[1]
- name = Name(ip=new_ip, name=new_name,
- dns_view='global', only=False)
- name.save()
- name.mxs.add(mx)
- new_name = "-".join([host.hostname.split(".")[0],
- new_inter.hdwr_type])
- new_name += "." + host.hostname.split(".", 1)[1]
- name = Name(ip=new_ip, name=new_name,
- dns_view='global', only=False)
- name.save()
- name.mxs.add(mx)
- name = Name(ip=new_ip, name=host.hostname,
- dns_view='global', only=False)
- name.save()
- name.mxs.add(mx)
- host.save()
- return HttpResponseRedirect('/hostbase/%s/' % host.id)
- else:
- return render_to_response('new.html',
- {'TYPE_CHOICES': Interface.TYPE_CHOICES,
- 'NETGROUP_CHOICES': Host.NETGROUP_CHOICES,
- 'CLASS_CHOICES': Host.CLASS_CHOICES,
- 'SUPPORT_CHOICES': Host.SUPPORT_CHOICES,
- 'WHATAMI_CHOICES': Host.WHATAMI_CHOICES,
- 'logged_in': request.session.get('_auth_user_id', False)},
- context_instance = RequestContext(request))
-
-def copy(request, host_id):
- """Function for creating a new host in hostbase
- Data is validated before committed to the database"""
- if 'sub' in request.GET:
- try:
- Host.objects.get(hostname=request.POST['hostname'].lower())
- return render_to_response('errors.html',
- {'failures': ['%s already exists in hostbase' % request.POST['hostname']],
- 'logged_in': request.session.get('_auth_user_id', False)},
- context_instance = RequestContext(request))
- except:
- pass
- if not validate(request, True):
- if not request.POST['ip_addr_new'] and not request.POST['ip_addr_new2']:
- return render_to_response('errors.html',
- {'failures': ['ip_addr: You must enter an ip address'],
- 'logged_in': request.session.get('_auth_user_id', False)},
- context_instance = RequestContext(request))
- host = Host()
- # this is the stuff that validate() should take care of
- # examine the check boxes for any changes
- host.outbound_smtp = 'outbound_smtp' in request.POST
- for attrib in attribs:
- if attrib in request.POST:
- host.__dict__[attrib] = request.POST[attrib].lower()
- if 'comments' in request.POST:
- host.comments = request.POST['comments']
- if 'expiration_date' in request.POST:
-# ymd = request.POST['expiration_date'].split("-")
-# host.__dict__['expiration_date'] = date(int(ymd[0]), int(ymd[1]), int(ymd[2]))
- host.__dict__['expiration_date'] = date(2000, 1, 1)
- host.status = 'active'
- host.save()
- else:
- return render_to_response('errors.html',
- {'failures': validate(request, True),
- 'logged_in': request.session.get('_auth_user_id', False)},
- context_instance = RequestContext(request))
-
- if request.POST['mac_addr_new']:
- new_inter = Interface(host=host,
- mac_addr = request.POST['mac_addr_new'].lower().replace('-',':'),
- hdwr_type = request.POST['hdwr_type_new'],
- dhcp = 'dhcp_new' in request.POST)
- new_inter.save()
- if request.POST['mac_addr_new'] and request.POST['ip_addr_new']:
- new_ip = IP(interface=new_inter, ip_addr=request.POST['ip_addr_new'])
- new_ip.save()
- mx, created = MX.objects.get_or_create(priority=settings.PRIORITY, mx=settings.DEFAULT_MX)
- if created:
- mx.save()
- new_name = "-".join([host.hostname.split(".")[0],
- new_ip.ip_addr.split(".")[2]])
- new_name += "." + host.hostname.split(".", 1)[1]
- name = Name(ip=new_ip, name=new_name, dns_view='global', only=False)
- name.save()
- name.mxs.add(mx)
- new_name = "-".join([host.hostname.split(".")[0],
- new_inter.hdwr_type])
- new_name += "." + host.hostname.split(".", 1)[1]
- name = Name(ip=new_ip, name=new_name,
- dns_view='global', only=False)
- name.save()
- name.mxs.add(mx)
- name = Name(ip=new_ip, name=host.hostname,
- dns_view='global', only=False)
- name.save()
- name.mxs.add(mx)
- if request.POST['ip_addr_new'] and not request.POST['mac_addr_new']:
- new_inter = Interface(host=host,
- mac_addr="",
- hdwr_type=request.POST['hdwr_type_new'],
- dhcp=False)
- new_inter.save()
- new_ip = IP(interface=new_inter, ip_addr=request.POST['ip_addr_new'])
- new_ip.save()
- mx, created = MX.objects.get_or_create(priority=settings.PRIORITY, mx=settings.DEFAULT_MX)
- if created:
- mx.save()
- new_name = "-".join([host.hostname.split(".")[0],
- new_ip.ip_addr.split(".")[2]])
- new_name += "." + host.hostname.split(".", 1)[1]
- name = Name(ip=new_ip, name=new_name,
- dns_view='global', only=False)
- name.save()
- name.mxs.add(mx)
- new_name = "-".join([host.hostname.split(".")[0],
- new_inter.hdwr_type])
- new_name += "." + host.hostname.split(".", 1)[1]
- name = Name(ip=new_ip, name=new_name,
- dns_view='global', only=False)
- name.save()
- name.mxs.add(mx)
- name = Name(ip=new_ip, name=host.hostname,
- dns_view='global', only=False)
- name.save()
- name.mxs.add(mx)
- if request.POST['mac_addr_new2']:
- new_inter = Interface(host=host,
- mac_addr = request.POST['mac_addr_new2'].lower().replace('-',':'),
- hdwr_type = request.POST['hdwr_type_new2'],
- dhcp = 'dhcp_new2' in request.POST)
- new_inter.save()
- if request.POST['mac_addr_new2'] and request.POST['ip_addr_new2']:
- new_ip = IP(interface=new_inter, ip_addr=request.POST['ip_addr_new2'])
- new_ip.save()
- mx, created = MX.objects.get_or_create(priority=settings.PRIORITY, mx=settings.DEFAULT_MX)
- if created:
- mx.save()
- new_name = "-".join([host.hostname.split(".")[0],
- new_ip.ip_addr.split(".")[2]])
- new_name += "." + host.hostname.split(".", 1)[1]
- name = Name(ip=new_ip, name=new_name,
- dns_view='global', only=False)
- name.save()
- name.mxs.add(mx)
- new_name = "-".join([host.hostname.split(".")[0],
- new_inter.hdwr_type])
- new_name += "." + host.hostname.split(".", 1)[1]
- name = Name(ip=new_ip, name=new_name,
- dns_view='global', only=False)
- name.save()
- name.mxs.add(mx)
- name = Name(ip=new_ip, name=host.hostname,
- dns_view='global', only=False)
- name.save()
- name.mxs.add(mx)
- if request.POST['ip_addr_new2'] and not request.POST['mac_addr_new2']:
- new_inter = Interface(host=host,
- mac_addr="",
- hdwr_type=request.POST['hdwr_type_new2'],
- dhcp=False)
- new_inter.save()
- new_ip = IP(interface=new_inter, ip_addr=request.POST['ip_addr_new2'])
- new_ip.save()
- mx, created = MX.objects.get_or_create(priority=settings.PRIORITY, mx=settings.DEFAULT_MX)
- if created:
- mx.save()
- new_name = "-".join([host.hostname.split(".")[0],
- new_ip.ip_addr.split(".")[2]])
- new_name += "." + host.hostname.split(".", 1)[1]
- name = Name(ip=new_ip, name=new_name,
- dns_view='global', only=False)
- name.save()
- name.mxs.add(mx)
- new_name = "-".join([host.hostname.split(".")[0],
- new_inter.hdwr_type])
- new_name += "." + host.hostname.split(".", 1)[1]
- name = Name(ip=new_ip, name=new_name,
- dns_view='global', only=False)
- name.save()
- name.mxs.add(mx)
- name = Name(ip=new_ip, name=host.hostname,
- dns_view='global', only=False)
- name.save()
- name.mxs.add(mx)
- host.save()
- return HttpResponseRedirect('/hostbase/%s/' % host.id)
- else:
- host = Host.objects.get(id=host_id)
- return render_to_response('copy.html',
- {'host': host,
- 'TYPE_CHOICES': Interface.TYPE_CHOICES,
- 'NETGROUP_CHOICES': Host.NETGROUP_CHOICES,
- 'CLASS_CHOICES': Host.CLASS_CHOICES,
- 'SUPPORT_CHOICES': Host.SUPPORT_CHOICES,
- 'WHATAMI_CHOICES': Host.WHATAMI_CHOICES,
- 'logged_in': request.session.get('_auth_user_id', False)},
- context_instance = RequestContext(request))
-
-# FIXME: delete all this things in a signal handler "pre_delete"
-#def remove(request, host_id):
-# host = Host.objects.get(id=host_id)
-# if 'sub' in request:
-# for interface in host.interface_set.all():
-# for ip in interface.ip_set.all():
-# for name in ip.name_set.all():
-# name.cname_set.all().delete()
-# ip.name_set.all().delete()
-# interface.ip_set.all().delete()
-# interface.delete()
-# host.delete()
-
-def validate(request, new=False, host_id=None):
- """Function for checking form data"""
- failures = []
- if (request.POST['expiration_date']
- and regex.date.match(request.POST['expiration_date'])):
- try:
- (year, month, day) = request.POST['expiration_date'].split("-")
- date(int(year), int(month), int(day))
- except (ValueError):
- failures.append('expiration_date')
- elif request.POST['expiration_date']:
- failures.append('expiration_date')
-
- if not (request.POST['hostname']
- and regex.host.match(request.POST['hostname'])):
- failures.append('hostname')
-
-## if not regex.printq.match(request.POST['printq']) and request.POST['printq']:
-## failures.append('printq')
-
-## if not regex.user.match(request.POST['primary_user']):
-## failures.append('primary_user')
-
-## if (not regex.user.match(request.POST['administrator'])
-## and request.POST['administrator']):
-## failures.append('administrator')
-
-## if not (request.POST['location']
-## and regex.location.match(request.POST['location'])):
-## failures.append('location')
-
- if new:
- if (not regex.macaddr.match(request.POST['mac_addr_new'])
- and request.POST['mac_addr_new']):
- failures.append('mac_addr (#1)')
- if ((request.POST['mac_addr_new'] or request.POST['ip_addr_new']) and
- not 'hdwr_type_new' in request.REQUEST):
- failures.append('hdwr_type (#1)')
- if ((request.POST['mac_addr_new2'] or request.POST['ip_addr_new2']) and
- not 'hdwr_type_new2' in request.REQUEST):
- failures.append('hdwr_type (#2)')
-
- if (not regex.macaddr.match(request.POST['mac_addr_new2'])
- and request.POST['mac_addr_new2']):
- failures.append('mac_addr (#2)')
-
- if (not regex.ipaddr.match(request.POST['ip_addr_new'])
- and request.POST['ip_addr_new']):
- failures.append('ip_addr (#1)')
- if (not regex. ipaddr.match(request.POST['ip_addr_new2'])
- and request.POST['ip_addr_new2']):
- failures.append('ip_addr (#2)')
-
- [failures.append('ip_addr (#1)') for number in
- request.POST['ip_addr_new'].split(".")
- if number.isdigit() and int(number) > 255
- and 'ip_addr (#1)' not in failures]
- [failures.append('ip_addr (#2)') for number in
- request.POST['ip_addr_new2'].split(".")
- if number.isdigit() and int(number) > 255
- and 'ip_addr (#2)' not in failures]
-
- elif host_id:
- interfaces = Interface.objects.filter(host=host_id)
- for interface in interfaces:
- if (not regex.macaddr.match(request.POST['mac_addr%d' % interface.id])
- and request.POST['mac_addr%d' % interface.id]):
- failures.append('mac_addr (%s)' % request.POST['mac_addr%d' % interface.id])
- for ip in interface.ip_set.all():
- if not regex.ipaddr.match(request.POST['ip_addr%d' % ip.id]):
- failures.append('ip_addr (%s)' % request.POST['ip_addr%d' % ip.id])
- [failures.append('ip_addr (%s)' % request.POST['ip_addr%d' % ip.id])
- for number in request.POST['ip_addr%d' % ip.id].split(".")
- if (number.isdigit() and int(number) > 255 and
- 'ip_addr (%s)' % request.POST['ip_addr%d' % ip.id] not in failures)]
- if (request.POST['%dip_addr' % interface.id]
- and not regex.ipaddr.match(request.POST['%dip_addr' % interface.id])):
- failures.append('ip_addr (%s)' % request.POST['%dip_addr' % interface.id])
- if (request.POST['mac_addr_new']
- and not regex.macaddr.match(request.POST['mac_addr_new'])):
- failures.append('mac_addr (%s)' % request.POST['mac_addr_new'])
- if (request.POST['ip_addr_new']
- and not regex.ipaddr.match(request.POST['ip_addr_new'])):
- failures.append('ip_addr (%s)' % request.POST['ip_addr_new'])
-
- if not failures:
- return 0
- return failures
-
-def do_log(text, attribute, previous, new):
- if previous != new:
- text += "%-20s%-20s -> %s\n" % (attribute, previous, new)
- return text
-
-## login required stuff
-## uncomment the views below that you would like to restrict access to
-
-## uncomment the lines below this point to restrict access to pages that modify the database
-## anonymous users can still view data in Hostbase
-
-edit = login_required(edit)
-confirm = login_required(confirm)
-dnsedit = login_required(dnsedit)
-new = login_required(new)
-copy = login_required(copy)
-#remove = login_required(remove)
-#zoneedit = login_required(zoneedit)
-#zonenew = login_required(zonenew)
-
-## uncomment the lines below this point to restrict access to all of hostbase
-
-## search = login_required(search)
-## look = login_required(look)
-## dns = login_required(dns)
-## zones = login_required(zones)
-## zoneview = login_required(zoneview)
-
diff --git a/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/base.html b/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/base.html
deleted file mode 100644
index 1d7c5565b..000000000
--- a/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/base.html
+++ /dev/null
@@ -1,34 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-<head>
- <title>{% block title %}BCFG2 - Hostbase{% endblock %}</title>
- <link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}/boxypastel.css" />
- <link rel="stylesheet" type="text/css" href="{{ MEDIA_URL }}/base.css" />
- <!--<script type="text/javascript" src="http://hostbase.mcs.anl.gov/site_media/main.js"> -->
- {% block extra_header_info %}{% endblock %}
-</head>
-
-<body>
- <div id="header">
- <div id="branding">
- <h1>BCFG2</h1>
- </div>
- <div id="user-tools">...Change is Coming...</div>
- </div>
- <div id="sidebar">
- {% block sidebar %}
- <ul class="sidebar">
- </ul>
- {% endblock %}
- </div>
-
- <div id="content-main">
- <div id="container">
- {% block pagebanner %}{% endblock %}
- {% block content %}{% endblock %}
-
- </div>
- </div>
-</body>
-</html>
diff --git a/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/confirm.html b/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/confirm.html
deleted file mode 100644
index ca8b0cc07..000000000
--- a/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/confirm.html
+++ /dev/null
@@ -1,117 +0,0 @@
-{% extends "base.html" %}
-
-{% block pagebanner %}
- <div class="header">
- <h2>Confirm Removal</h2>
- </div>
- <br/>
-{% endblock %}
-
-{% block sidebar %}
-{% include "navbar.tmpl" %}
-{% include "logout.tmpl" %}
-{% endblock %}
-
-{% block content %}
-
-<form name="input" action="confirm.html?sub=true" method="post">
-Are you sure you want to remove these items?
-
-{% if interface %}
-<ul>
-<li> interface: {{ interface.mac_addr }} </li>
-{% endif %}
-
-
-{% if ips %}
-<ul>
-{% for ip in ips %}
-<li> ip: {{ ip.ip_addr }} </li>
-<ul>
-{% for name in names %}
-{% ifequal name.0 ip.id %}
-<li> name: {{ name.1.name }} </li>
-<ul>
-{% endifequal %}
-{% for cname in cnames %}
-{% ifequal cname.0 name.1.id %}
-<li> cname: {{ cname.1.name }} </li>
-{% endifequal %}
-{% endfor %}
-</ul>
-<ul>
-{% for mx in mxs %}
-{% ifequal mx.0 name.1.id %}
-<li> mx: {{ mx.1.priority }} {{ mx.1.mx }} </li>
-{% endifequal %}
-{% endfor %}
-</ul>
-{% endfor %}
-</ul>
-{% endfor %}
-</ul>
-{% endif %}
-
-{% if names and not ips %}
-<ul>
-{% for name in names %}
-<li> name: {{ name.name }} </li>
-<ul>
-{% for cname in cnames %}
-{% ifequal cname.0 name.id %}
-<li> cname: {{ cname.1.cname }} </li>
-{% endifequal %}
-{% endfor %}
-</ul>
-<ul>
-{% for mx in mxs %}
-{% ifequal mx.0 name.id %}
-<li> mx: {{ mx.1.priority }} {{ mx.1.mx }} </li>
-{% endifequal %}
-{% endfor %}
-</ul>
-{% endfor %}
-</ul>
-{% endif %}
-
-{% if cnames and not names %}
-<ul>
-{% for cname in cnames %}
-<li> cname: {{ cname.cname }} </li>
-{% endfor %}
-</ul>
-{% endif %}
-
-{% if mxs and not names %}
-<ul>
-{% for mx in mxs %}
-<li> mx: {{ mx.priority }} {{ mx.mx }} </li>
-{% endfor %}
-</ul>
-{% endif %}
-
-{% if interface %}
-</ul>
-{% endif %}
-
-{% if zone_id %}
-<ul>
-{% ifequal type 'zonemx' %}
-<li> mx: {{ zonemx.priority }} {{ zonemx.mx }} </li>
-{% endifequal %}
-
-{% ifequal type 'nameserver' %}
-<li> nameserver: {{ nameserver.name }} </li>
-{% endifequal %}
-
-{% ifequal type 'address' %}
-<li> address: {{ address.ip_addr }} </li>
-{% endifequal %}
-</ul>
-{% endif %}
-
-<input type="submit" value="confirm">
-<input type="reset" value="cancel" onclick="history.back()">
-</form>
-
-{% endblock %}
diff --git a/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/copy.html b/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/copy.html
deleted file mode 100644
index 400ef58f2..000000000
--- a/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/copy.html
+++ /dev/null
@@ -1,122 +0,0 @@
-{% extends "base.html" %}
-
-{% block pagebanner %}
- <div class="header">
- <h2>new host information</h2>
- </div>
- <br/>
-{% endblock %}
-
-{% block sidebar %}
-<a href="/hostbase/" class="sidebar">search hostbase</a>
-{% include "logout.tmpl" %}
-{% endblock %}
-
-{% block content %}
-
-<form name="hostdata" action="?sub=true" method="post">
-<input type="hidden" name="host">
-<table border="0" width="100%">
- <colgroup>
- <col width="150">
- <col width="*">
- <tr> <td> <b>hostname</b></td>
- <td> <input name="hostname" type="text" value="{{ host.hostname }}" ></td></tr>
- <tr> <td> <b>whatami</b></td>
- <td>
- <select name="whatami">
- {% for choice in WHATAMI_CHOICES %}
- {% ifequal host.whatami choice.0 %}
- <option value="{{ choice.0 }}" selected="selected" >{{ choice.1 }}
- {% else %}
- <option value="{{ choice.0 }}">{{ choice.1 }}
- {% endifequal %}
- {% endfor %}
- </select>
- </td></tr>
- <tr> <td> <b>netgroup</b></td>
- <td>
- <select name="netgroup">
- {% for choice in NETGROUP_CHOICES %}
- {% ifequal host.netgroup choice.0 %}
- <option value="{{ choice.0 }}" selected="selected" >{{ choice.1 }}
- {% else %}
- <option value="{{ choice.0 }}">{{ choice.1 }}
- {% endifequal %}
- {% endfor %}
- </select>
- </td></tr>
- <tr> <td> <b>class</b></td>
- <td>
- <select name="security_class">
- {% for choice in CLASS_CHOICES %}
- {% ifequal host.security_class choice.0 %}
- <option value="{{ choice.0 }}" selected="selected" >{{ choice.1 }}
- {% else %}
- <option value="{{ choice.0 }}">{{ choice.1 }}
- {% endifequal %}
- {% endfor %}
- </select></td></tr>
- <tr> <td> <b>support</b></td>
- <td>
- <select name="support">
- {% for choice in SUPPORT_CHOICES %}
- {% ifequal host.support choice.0 %}
- <option value="{{ choice.0 }}" selected="selected" >{{ choice.1 }}
- {% else %}
- <option value="{{ choice.0 }}">{{ choice.1 }}
- {% endifequal %}
- {% endfor %}
- </select></td></tr>
- <tr> <td> <b>csi</b></td>
- <td> <input name="csi" type="text" value="{{ host.csi }}" ></td></tr>
- <tr> <td> <b>printq</b></td>
- <td> <input name="printq" type="text" value="{{ host.printq }}" ></td></tr>
- <tr> <td> <b>outbound_smtp</b></td>
- <td>
- {% if host.outbound_smtp %}
- <input type="checkbox" name="outbound_smtp" checked="checked" ></td></tr>
- {% else %}
- <input type="checkbox" name="outbound_smtp" ></td></tr>
- {% endif %}
- <tr> <td> <b>primary_user</b></td>
- <td> <input name="primary_user" type="text" size="32" value="{{ host.primary_user }}"> (email address)</td></tr>
- <tr> <td> <b>administrator</b></td>
- <td> <input name="administrator" type="text" size="32" value="{{ host.administrator }}"> (email address)</td></tr>
- <tr> <td> <b>location</b></td>
- <td> <input name="location" type="text" value="{{ host.location }}"></td></tr>
- <tr> <td> <b>expiration_date</b></td>
- <td> <input name="expiration_date" type="text" size="10" value="{{ host.expiration_date }}">YYYY-MM-DD</td></tr>
- <tr> <td><br><b>Interface</b></td><td><br>
- {% for choice in TYPE_CHOICES %}
- <input type="radio" name="hdwr_type_new" value="{{ choice.0 }}" >{{ choice.1 }}
- {% endfor %}
- </td></tr>
- <tr> <td> <b>dhcp</b></td>
- <td>
- <input type="checkbox" name="dhcp_new"></td></tr>
- <tr> <td> <b>mac_addr</b></td>
- <td> <input name="mac_addr_new" type="text"></td></tr>
- <tr> <td> <b>ip_addr</b></td>
- <td> <input name="ip_addr_new" type="text"></td></tr>
- <tr> <td><br><b>Interface</b></td><td><br>
- {% for choice in TYPE_CHOICES %}
- <input type="radio" name="hdwr_type_new2" value="{{ choice.0 }}" >{{ choice.1 }}
- {% endfor %}
- </td></tr>
- <tr> <td> <b>dhcp</b></td>
- <td>
- <input type="checkbox" name="dhcp_new2"></td></tr>
- <tr> <td> <b>mac_addr</b></td>
- <td> <input name="mac_addr_new2" type="text"></td></tr>
- <tr> <td> <b>ip_addr</b></td>
- <td> <input name="ip_addr_new2" type="text"></td></tr>
- <tr> <td> <b>comments</b></td>
- <td> <textarea rows="10" cols="50" name="comments"></textarea></td></tr>
-</table>
-<br>
-<p><input type="submit" value="Submit">
-</form>
-
-{% endblock %}
-
diff --git a/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/dns.html b/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/dns.html
deleted file mode 100644
index da179e5a1..000000000
--- a/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/dns.html
+++ /dev/null
@@ -1,40 +0,0 @@
-{% extends "base.html" %}
-
-{% block pagebanner %}
- <div class="header">
- <h2>dns info for {{ host.hostname }}</h2>
- </div>
- <br/>
-{% endblock %}
-
-{% block sidebar %}
-{% include "navbar.tmpl" %}
-<ul class="sidebar">
- <li><a href="/hostbase/{{ host.id }}/" class="sidebar">host info</a></li>
- <li><a href="/hostbase/{{ host.id }}/edit/" class="sidebar">edit host info</a></li>
- <li><a href="edit/" class="sidebar">edit dns info</a></li>
- <li><a href="/hostbase/{{ host.id }}/logs/" class="sidebar">change logs</a></li>
-</ul>
-{% include "logout.tmpl" %}
-{% endblock %}
-
-{% block content %}
-
-{% for interface in host.interface_set.all %}
- {% for ip in interface.ip_set.all %}
- <ul><li> <b>ip_addr:</b> {{ ip.ip_addr }}</li>
- {% for name in ip.name_set.all %}
- <ul> <li><b>name:</b> {{ name.name }}</li> <ul>
- {% for cname in name.cname_set.all %}
- <li> <b>cname:</b> {{ cname.cname }}</li>
- {% endfor %}
- {% for mx in name.mxs.all %}
- <li> <b>mx:</b> {{ mx.priority }} {{ mx.mx }}</li>
- {% endfor %}
- </ul></ul>
- {% endfor %}
- </ul>
- {% endfor %}
-{% endfor %}
-{% endblock %}
-
diff --git a/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/dnsedit.html b/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/dnsedit.html
deleted file mode 100644
index b1b71ab67..000000000
--- a/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/dnsedit.html
+++ /dev/null
@@ -1,98 +0,0 @@
-{% extends "base.html" %}
-
-{% block pagebanner %}
- <div class="header">
- <h2>dns info for {{ host.hostname }}</h2>
- </div>
- <br/>
-{% endblock %}
-
-{% block sidebar %}
-{% include "navbar.tmpl" %}
-<ul class="sidebar">
- <li><a href="/hostbase/{{ host.id }}/" class="sidebar">host info</a></li>
- <li><a href="/hostbase/{{ host.id }}/edit/" class="sidebar">edit host info</a></li>
- <li><a href="/hostbase/{{ host.id }}/dns/" class="sidebar">see dns info</a></li>
- <li><a href="/hostbase/{{ host.id }}/logs/" class="sidebar">change logs</a></li>
-</ul>
-{% include "logout.tmpl" %}
-{% endblock %}
-
-{% block content %}
-
-<form name="dns" action="?sub=true" method="post">
-<input type="hidden" name="host" value="{{ host.id }}">
-<table border="0" width="100%">
- <colgroup>
- <col width="150">
- <col width="*">
- {% for interface in interfaces %}
- <tr><td><br></td></tr>
- <tr> <td> <b>interface type</b> </td>
- <td> {{ interface.hdwr_type }} </td></tr>
- <tr> <td> <b>mac_addr</b> </td>
- <td> {{ interface.mac_addr }} </td></tr>
- <tr><td><hr></td><td><hr></td></tr>
- {% for ip in info %}
- {% ifequal ip.0.interface interface %}
- <tr> <td> <b>ip_addr</b></td>
- <td>{{ ip.0.ip_addr }}</td></tr>
- {% for name in ip.1 %}
- <tr> <td><b>name(dns)</b></td>
- <td> <input name="name{{ name.id }}" type="text" value="{{ name.name }}">
- <select name="dns_view{{ name.id }}">
- {% for choice in DNS_CHOICES %}
- {% ifequal name.dns_view choice.0 %}
- <option value="{{ choice.0 }}" selected="selected">{{ choice.1 }}
- {% else %}
- <option value="{{ choice.0 }}">{{ choice.1 }}
- {% endifequal %}
- {% endfor %}
- </select>
- <a style="font-size:75%" href="/hostbase/{{ host.id }}/name/{{ name.id }}/confirm">remove</a></td></tr>
- {% for cname in cnames %}
- {% ifequal name cname.name %}
- <tr> <td> <b>cname</b></td>
- <td> <input name="cname{{ cname.id }}" type="text" value="{{ cname.cname }}">
- <a style="font-size:75%" href="/hostbase/{{ host.id }}/cname/{{ cname.id }}/confirm">remove</a></td></tr>
- {% endifequal %}
- {% endfor %}
- <tr> <td> <b>cname</b></td>
- <td> <input name="{{ name.id }}cname" type="text"></td></tr>
- {% for mx in mxs %}
- {% ifequal mx.0 name.id %}
- {% for record in mx.1 %}
- <tr> <td> <b>mx</b></td>
- <td> <input name="priority{{ record.id }}" type="text" size="6" value="{{ record.priority }}">
- <input name="mx{{ record.id }}" type="text" value="{{ record.mx }}">
- <a style="font-size:75%" href="/hostbase/{{ host.id }}/mx/{{ record.id }}/{{ name.id }}/confirm">remove</a></td></tr>
- {% endfor %}
- {% endifequal %}
- {% endfor %}
- <tr> <td> <b>mx</b></td>
- <td> <input name="{{ name.id }}priority" type="text" size="6">
- <input name="{{ name.id }}mx" type="text"></td></tr>
- {% endfor %}
- <tr> <td> <b>name</b></td>
- <td> <input name="{{ ip.0.ip_addr }}name" type="text">
- <select name="{{ ip.0.ip_addr }}dns_view">
- {% for choice in DNS_CHOICES %}
- <option value="{{ choice.0 }}">{{ choice.1 }}
- {% endfor %}
- </select></td></tr>
- <tr> <td> <b>cname</b></td>
- <td> <input name="{{ ip.0.ip_addr }}cname" type="text"></td></tr>
- <tr> <td> <b>mx</b></td>
- <td> <input name="{{ ip.0.ip_addr }}priority" type="text" size="6">
- <input name="{{ ip.0.ip_addr }}mx" type="text"></td></tr>
- <tr><td></td></tr>
- <tr><td><hr></td><td><hr></td></tr>
- {% endifequal %}
- {% endfor %}
- {% endfor %}
- </table>
-
-<p><input type="submit" value="Submit">
-</form>
-
-{% endblock %}
diff --git a/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/edit.html b/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/edit.html
deleted file mode 100644
index 961c9d143..000000000
--- a/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/edit.html
+++ /dev/null
@@ -1,191 +0,0 @@
-{% extends "base.html" %}
-
-{% block pagebanner %}
- <div class="header">
- <h2>{{ host.hostname }}</h2>
- </div>
- <br/>
-{% endblock %}
-
-{% block sidebar %}
-{% include "navbar.tmpl" %}
-<ul class="sidebar">
-<li><a href="/hostbase/{{ host.id }}/" class="sidebar">host info</a></li>
-<li><a href="/hostbase/{{ host.id }}/dns/" class="sidebar">detailed dns info</a></li>
-<li><a href="/hostbase/{{ host.id }}/dns/edit/" class="sidebar">edit dns info</a></li>
-<li><a href="/hostbase/{{ host.id }}/logs/" class="sidebar">change logs</a></li>
-</ul>
-{% include "logout.tmpl" %}
-{% endblock %}
-
-{% block content %}
-
-<script language="JavaScript" type="text/Javascript">
-function toggleAddr(interface_id){
- if(document.getElementById){
- var style = document.getElementById('ipaddr'+interface_id).style;
- style.display = style.display? "":"block";
- }
-}
-function toggleInter(){
- if(document.getElementById){
- var style = document.getElementById('interface').style;
- style.display = style.display? "":"block";
- }
-}
-</script>
-
-<style type=text/css>
-{% for interface in interfaces %}
-div#ipaddr{{ interface.0.id }}{
- display: none;
-}
-{% endfor %}
-div#interface{
- display: none;
-}
-</style>
-
-<form name="hostdata" action="" method="post">
-<fieldset class="module aligned ()">
-<input type="hidden" name="host" value="{{ host.id }}">
- <label for="id_hostname">hostname:</label>
- <input name="hostname" value="{{ host.hostname }}"><br>
- <label for="id_whatami">whatami:</label>
- <select name="whatami">
- {% for choice in host.WHATAMI_CHOICES %}
- {% ifequal host.whatami choice.0 %}
- <option value="{{ choice.0 }}" selected="selected">{{ choice.1 }}
- {% else %}
- <option value="{{ choice.0 }}">{{ choice.1 }}
- {% endifequal %}
- {% endfor %}
- </select><br>
- <label for="id_netgroup">netgroup:</label>
- <select name="netgroup">
- {% for choice in host.NETGROUP_CHOICES %}
- {% ifequal host.netgroup choice.0 %}
- <option value="{{ choice.0 }}" selected="selected">{{ choice.1 }}
- {% else %}
- <option value="{{ choice.0 }}">{{ choice.1 }}
- {% endifequal %}
- {% endfor %}
- </select><br>
- <label for="id_security_class">class:</label>
- <select name="security_class">
- {% for choice in host.CLASS_CHOICES %}
- {% ifequal host.security_class choice.0 %}
- <option value="{{ choice.0 }}" selected="selected">{{ choice.1 }}
- {% else %}
- <option value="{{ choice.0 }}">{{ choice.1 }}
- {% endifequal %}
- {% endfor %}
- </select><br>
- <label for="id_support">support:</label>
- <select name="support">
- {% for choice in host.SUPPORT_CHOICES %}
- {% ifequal host.support choice.0 %}
- <option value="{{ choice.0 }}" selected="selected">{{ choice.1 }}
- {% else %}
- <option value="{{ choice.0 }}">{{ choice.1 }}
- {% endifequal %}
- {% endfor %}
- </select><br>
- <label for="id_csi">csi:</label>
- <input name="csi" type="text" value="{{ host.csi }}"><br>
- <label for="id_printq">printq:</label>
- <input name="printq" type="text" value="{{ host.printq }}"><br>
- <label for="id_outbound_smtp">outbound_smtp:</label>
- {% if host.outbound_smtp %}
- <input type="checkbox" checked="checked" name="outbound_smtp">
- {% else %}
- <input type="checkbox" name="outbound_smtp">
- {% endif %}<br>
- <label for="id_primary_user">primary_user:</label>
- <input name="primary_user" type="text" size="32" value="{{ host.primary_user }}"><br>
- <label for="id_administrator">administrator:</label>
- <input name="administrator" type="text" size="32" value="{{ host.administrator }}"><br>
- <label for="id_location">location:</label>
- <input name="location" type="text" value="{{ host.location }}"><br>
- <label for="id_expiration_date">expiration_date:</label>
- <input name="expiration_date" type="text" value="{{ host.expiration_date }}"> YYYY-MM-DD<br>
- {% for interface in interfaces %}
- <label for="id_interface">Interface:</label>
- <select name="hdwr_type{{ interface.0.id }}">
- {% for choice in interface.0.TYPE_CHOICES %}
- {% ifequal interface.0.hdwr_type choice.0 %}
- <option value="{{ choice.0 }}" selected="selected">{{ choice.1 }}
- {% else %}
- <option value="{{ choice.0 }}">{{ choice.1 }}
- {% endifequal %}
- {% endfor %}
- </select><br>
- <label for="id_dhcp">dhcp:</label>
- {% if interface.0.dhcp %}
- <input type="checkbox" checked="checked" name="dhcp{{ interface.0.id }}">
- {% else %}
- <input type="checkbox" name="dhcp{{ interface.0.id }}">
- {% endif %}<br>
- <label for="id_mac_addr">mac_addr:</label>
- <input name="mac_addr{{ interface.0.id }}" type="text" value="{{ interface.0.mac_addr }}">
- <a style="font-size:75%" href="/hostbase/{{ host.id }}/interface/{{ interface.0.id }}/confirm">remove</a><br>
- {% for ip in interface.1 %}
- <label for="id_ip_addr">ip_addr:</label>
- <input name="ip_addr{{ ip.id }}" type="text" value="{{ ip.ip_addr }}">
- <a style="font-size:75%" href="/hostbase/{{ host.id }}/ip/{{ ip.id }}/confirm">remove</a><br>
- {% endfor %}
-
-<!-- Section for adding a new IP address to an existing interface -->
-<!-- By default, section is hidden -->
- <div id=ipaddr{{ interface.0.id }}>
- <label for="id_ip_addr">ip_addr:</label>
- <input name="{{ interface.0.id }}ip_addr" type="text"><br>
- </div>
- <a style="font-size:75%" href=# onclick="toggleAddr({{ interface.0.id }})">Add a New IP Address</a><br>
- {% endfor %}
-<!-- End section for new IP address -->
-
-<!-- Section for add an entirely new interface to a host -->
-<!-- By default, section is hidden -->
- <div id=interface>
- <label for="id_interface">Interface:</label>
- <select name="hdwr_type_new">
- {% for choice in TYPE_CHOICES %}
- <option value="{{ choice.0 }}">{{ choice.1 }}
- {% endfor %}
- </select><br>
- <label for="id_dhcp">dhcp:</label>
- {% if host.dhcp %}
- <input type="checkbox" checked="checked" name="dhcp_new">
- {% else %}
- <input type="checkbox" name="dhcp_new">
- {% endif %}<br>
- <label for="id_mac_addr">mac_addr:</label>
- <td> <input name="mac_addr_new" type="text"><br>
- <label for="id_ip_addr">ip_addr:</label>
- <td> <input name="ip_addr_new" type="text"><br>
-</div>
-<a style="font-size:75%" href=# onclick="toggleInter()">Add a New Interface</a><br>
-<!-- End new interface section -->
-
-
-<label for="id_comments">comments:</label>
-<textarea rows="10" cols="50" name="comments">{{ host.comments }}</textarea><br>
-<a style="font-size:75%" href="/hostbase/{{ host.id }}/dns/edit">edit detailed DNS information for this host</a>
-<br>
-this host is
-<select name="status">
-{% for choice in host.STATUS_CHOICES %}
-{% ifequal host.status choice.0 %}
-<option value="{{ choice.0 }}" selected="selected">{{ choice.1 }}
-{% else %}
-<option value="{{ choice.0 }}">{{ choice.1 }}
-{% endifequal %}
-{% endfor %}
-</select><br>
-last update on {{ host.last }}<br>
-<input type="submit" value="submit">
-<input type="reset" value="cancel" onclick="history.back()">
-</form>
-
-{% endblock %}
diff --git a/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/errors.html b/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/errors.html
deleted file mode 100644
index e5429b86c..000000000
--- a/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/errors.html
+++ /dev/null
@@ -1,31 +0,0 @@
-{% extends "base.html" %}
-
-{% block pagebanner %}
- <div class="header">
- <h2>Search Results</h2>
- </div>
- <br/>
-{% endblock %}
-
-{% block sidebar %}
-{% include "navbar.tmpl" %}
-{% include "logout.tmpl" %}
-{% endblock %}
-
-{% block content %}
-
-{% if failures %}
-There were errors in the following fields<br><br>
-{% for failure in failures %}
-
-<font color="#FF0000">{{ failure }}</font><br>
-{% comment %}
-{{ failure.1|join:", " }}
-{% endcomment %}
-
-{% endfor %}
-{% endif %}
-<br>
-Press the back button on your browser and edit those field(s)
-
-{% endblock %}
diff --git a/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/host.html b/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/host.html
deleted file mode 100644
index d6b8873bc..000000000
--- a/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/host.html
+++ /dev/null
@@ -1,80 +0,0 @@
-{% extends "base.html" %}
-
-{% block pagebanner %}
- <div class="header">
- <h2>{{ host.hostname }}</h2>
- </div>
- <br/>
-{% endblock %}
-
-{% block sidebar %}
-{% include "navbar.tmpl" %}
-<ul class="sidebar">
- <li><a href="dns/" class="sidebar">detailed dns info</a></li>
- <li><a href="edit/" class="sidebar">edit host info</a></li>
- <li><a href="dns/edit/" class="sidebar">edit dns info</a></li>
- <li><a href="logs/" class="sidebar">change logs</a></li>
-</ul>
-{% include "logout.tmpl" %}
-{% endblock %}
-
-{% block content %}
-
-<table border="0" width="100%">
- <colgroup>
- <col width="150">
- <col width="*">
- <tr> <td> <b>hostname</b></td>
- <td> {{ host.hostname }}</td></tr>
- <tr> <td> <b>whatami</b></td>
- <td> {{ host.whatami }}</td></tr>
- <tr> <td> <b>netgroup</b></td>
- <td> {{ host.netgroup }}</td></tr>
- <tr> <td> <b>class</b></td>
- <td> {{ host.security_class }}</td></tr>
- <tr> <td> <b>support</b></td>
- <td> {{ host.support }}</td></tr>
- <tr> <td> <b>csi</b></td>
- <td> {{ host.csi }}</td></tr>
- <tr> <td> <b>printq</b></td>
- <td> {{ host.printq }}</td></tr>
- <tr> <td> <b>outbound_smtp</b></td>
- {% if host.outbound_smtp %}
- <td> y </td></tr>
- {% else %}
- <td> n </td></tr>
- {% endif %}
- <tr> <td> <b>primary_user</b></td>
- <td> {{ host.primary_user }}</td></tr>
- <tr> <td> <b>administrator</b></td>
- <td> {{ host.administrator }}</td></tr>
- <tr> <td> <b>location</b></td>
- <td> {{ host.location }}</td></tr>
- <tr> <td> <b>expiration_date</b></td>
- <td> {{ host.expiration_date }}</td></tr>
- {% for interface in host.inserface_set.all %}
- <tr> <td><br><b>Interface</b></td>
- {% ifnotequal interface.0.hdwr_type 'no' %}
- <td><br>{{ interface.0.hdwr_type }}</td></tr>
- {% endifnotequal %}
- {% if interface.0.dhcp %}
- <tr> <td> <b>mac_addr</b></td>
- <td> {{ interface.0.mac_addr }}</b></td></tr>
- {% endif %}
- {% for ip in interface.1 %}
- <tr> <td> <b>ip_addr</b></td>
- <td> {{ ip.ip_addr }}</td></tr>
- {% endfor %}
- {% endfor %}
- <tr> <td valign="top"> <b>comments</b></td>
- <td>
- {{ host.comments|linebreaksbr }}<br>
- </td></tr>
-
-</table>
-<a style="font-size:75%" href="/hostbase/{{ host.id }}/dns/">see detailed DNS information for this host</a>
-<br><br>
-this host is {{ host.status }}<br>
-last update on {{ host.last }}<br>
-
-{% endblock %}
diff --git a/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/hostbase/host_confirm_delete.html b/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/hostbase/host_confirm_delete.html
deleted file mode 100644
index b5d794b50..000000000
--- a/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/hostbase/host_confirm_delete.html
+++ /dev/null
@@ -1,89 +0,0 @@
-{% extends "base.html" %}
-
-{% block pagebanner %}
- <div class="header">
- <h2>Are you sure you want to remove {{ object.hostname }}?</h2>
- </div>
- <br/>
-{% endblock %}
-
-{% block sidebar %}
-{% include "navbar.tmpl" %}
-<ul class="sidebar">
- <li><a href="dns/" class="sidebar">detailed dns info</a></li>
- <li><a href="edit/" class="sidebar">edit host info</a></li>
- <li><a href="dns/edit/" class="sidebar">edit dns info</a></li>
-</ul>
-{% include "logout.tmpl" %}
-{% endblock %}
-
-{% block content %}
-
-<table border="0" width="100%">
- <colgroup>
- <col width="150">
- <col width="*">
- <tr> <td> <b>hostname</b></td>
- <td> {{ object.hostname }}</td></tr>
- <tr> <td> <b>whatami</b></td>
- <td> {{ object.whatami }}</td></tr>
- <tr> <td> <b>netgroup</b></td>
- <td> {{ object.netgroup }}</td></tr>
- <tr> <td> <b>class</b></td>
- <td> {{ object.security_class }}</td></tr>
- <tr> <td> <b>support</b></td>
- <td> {{ object.support }}</td></tr>
- <tr> <td> <b>csi</b></td>
- <td> {{ object.csi }}</td></tr>
- <tr> <td> <b>printq</b></td>
- <td> {{ object.printq }}</td></tr>
- <tr> <td> <b>dhcp</b></td>
- {% if host.dhcp %}
- <td> y </td></tr>
- {% else %}
- <td> n </td></tr>
- {% endif %}
- <tr> <td> <b>outbound_smtp</b></td>
- {% if host.outbound_smtp %}
- <td> y </td></tr>
- {% else %}
- <td> n </td></tr>
- {% endif %}
- <tr> <td> <b>primary_user</b></td>
- <td> {{ object.primary_user }}</td></tr>
- <tr> <td> <b>administrator</b></td>
- <td> {{ object.administrator }}</td></tr>
- <tr> <td> <b>location</b></td>
- <td> {{ object.location }}</td></tr>
- <tr> <td> <b>expiration_date</b></td>
- <td> {{ object.expiration_date }}</td></tr>
- {% for interface in interfaces %}
- <tr> <td><br><b>Interface</b></td>
- {% ifnotequal interface.0.hdwr_type 'no' %}
- <td><br>{{ interface.0.hdwr_type }}</td></tr>
- {% endifnotequal %}
- <tr> <td> <b>mac_addr</b></td>
- <td> {{ interface.0.mac_addr }}</b></td></tr>
- {% for ip in interface.1 %}
- <tr> <td> <b>ip_addr</b></td>
- <td> {{ ip.ip_addr }}</td></tr>
- {% endfor %}
- {% endfor %}
- <tr> <td valign="top"> <b>comments</b></td>
- <td>
- {{ object.comments|linebreaksbr }}<br>
- </td></tr>
-
-</table>
-<a style="font-size:75%" href="/hostbase/{{ object.id }}/dns/">see detailed DNS information for this host</a>
-<br><br>
-this host is {{ object.status }}<br>
-last update on {{ object.last }}<br>
-
-<form name="input" action="remove.html?sub=true" method="post">
-<input type="submit" value="remove">
-<input type="reset" value="cancel" onclick="history.back()">
-</form>
-
-{% endblock %}
-
diff --git a/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/hostbase/log_detail.html b/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/hostbase/log_detail.html
deleted file mode 100644
index aa9679cbd..000000000
--- a/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/hostbase/log_detail.html
+++ /dev/null
@@ -1,23 +0,0 @@
-{% extends "base.html" %}
-
-{% block pagebanner %}
- <div class="header">
- <h2>Change Logs for {{ object.hostname }}</h2>
- </div>
- <br/>
-{% endblock %}
-
-{% block sidebar %}
-{% include "navbar.tmpl" %}
-{% include "logout.tmpl" %}
-{% endblock %}
-
-{% block content %}
-
-<ul>
-<li><b>Hostname:</b>{{ object.hostname }}</li>
-<li><b>Date:</b>{{ object.date }}</li>
-<li><b>Log:</b>{{ object.log }}</li>
-</ul>
-
-{% endblock %}
diff --git a/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/index.html b/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/index.html
deleted file mode 100644
index 92258b648..000000000
--- a/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/index.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{% extends "base.html" %}
-{% block pagebanner %}
- <div class="header">
- <h2>Welcome to Hostbase!</h2>
- <p>Hostbase is a web based management tools for Bcfg2 Hosts</p>
- </div>
- <br/>
-{% endblock %}
-{% block sidebar %}
-<a href="/login/" class="sidebar">login to hostbase</a><br>
-<a href="/hostbase/" class="sidebar">search for hosts</a><br>
-<a href="hostbase/zones/" class="sidebar">zone file information</a>
-{% endblock %}
-{% block content %}
-{% endblock %}
-
diff --git a/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/login.html b/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/login.html
deleted file mode 100644
index ec24a0fc0..000000000
--- a/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/login.html
+++ /dev/null
@@ -1,37 +0,0 @@
-{% extends "base.html" %}
-{% block pagebanner %}
- <div class="header">
- <h2>Login to Hostbase!</h2>
- <p>You must login to manage hosts</p>
- </div>
- <br/>
-{% endblock %}
-{% block sidebar %}
-<a href="/hostbase/" class="sidebar">search for hosts</a><br>
-<a href="/hostbase/new" class="sidebar">add a new host</a><br>
-<a href="hostbase/zones/" class="sidebar">zone file information</a>
-{% endblock %}
-{% block content %}
- {% if form.has_errors %}
- {{ form.username.errors|join:", " }}
- <p>Login Failed.</p>
- {% endif %}
- {% if user.is_authenticated %}
- <p>Welcome, {{ user.username }}. Thanks for logging in.</p>
- {% else %}
- <p>Welcome, user. Please log in.</p>
- <form name="input" action="." method="post">
- <input name="username" type="text">
- <br />
- <input name="password" type="password">
- <br />
- <input type="submit" value="Login">
- {% if next %}
- <input type="hidden" name="next" value="{{ next }}" />
- {% else %}
- <input type="hidden" name="next" value="/hostbase/" />
- {% endif %}
-
- </form>
- {% endif %}
-{% endblock %}
diff --git a/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/logout.html b/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/logout.html
deleted file mode 100644
index 994f631a8..000000000
--- a/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/logout.html
+++ /dev/null
@@ -1,13 +0,0 @@
-{% extends "base.html" %}
-{% block pagebanner %}
- <div class="header">
- <h2>You are logged out of Hostbase!</h2>
- </div>
- <br/>
-{% endblock %}
-{% block sidebar %}
-<a href="/login/" class="sidebar">Login to Hostbase</a>
-{% endblock %}
-{% block content %}
-{% endblock %}
-
diff --git a/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/logout.tmpl b/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/logout.tmpl
deleted file mode 100644
index e71e90e76..000000000
--- a/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/logout.tmpl
+++ /dev/null
@@ -1,6 +0,0 @@
-<p>
-{% if logged_in %}
-<a href="/logout/" class="sidebar">logout</a>
-{% else %}
-<a href="/login/" class="sidebar">login</a>
-{% endif %}
diff --git a/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/logviewer.html b/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/logviewer.html
deleted file mode 100644
index 806ccd63d..000000000
--- a/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/logviewer.html
+++ /dev/null
@@ -1,27 +0,0 @@
-{% extends "base.html" %}
-
-{% block pagebanner %}
- <div class="header">
- <h2>Change Logs for {{ hostname }}</h2>
- </div>
- <br/>
-{% endblock %}
-
-{% block sidebar %}
-{% include "navbar.tmpl" %}
-{% include "logout.tmpl" %}
-{% endblock %}
-
-{% block content %}
-
-{% if host.get_logs %}
-<ul>
-{% for log in host.get_logs %}
-<li><a href="{{ log.id }}/">{{ log.date }}</li>
-{% endfor %}
-</ul>
-{% else %}
-There are no logs for this host<br>
-{% endif %}
-
-{% endblock %}
diff --git a/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/navbar.tmpl b/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/navbar.tmpl
deleted file mode 100644
index 877d427d0..000000000
--- a/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/navbar.tmpl
+++ /dev/null
@@ -1,5 +0,0 @@
-<a href="/hostbase/" class="sidebar">host search</a><br>
-<a href="/hostbase/new" class="sidebar">add a new host</a><br>
-<a href="/hostbase/zones" class="sidebar">zone file information</a><br>
-<a href="/hostbase/zones/new" class="sidebar">add a zone</a><br>
-
diff --git a/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/new.html b/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/new.html
deleted file mode 100644
index 2dcd6271f..000000000
--- a/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/new.html
+++ /dev/null
@@ -1,102 +0,0 @@
-{% extends "base.html" %}
-
-{% block pagebanner %}
- <div class="header">
- <h2>new host information</h2>
- </div>
- <br/>
-{% endblock %}
-
-{% block sidebar %}
-<a href="/hostbase/" class="sidebar">search hostbase</a>
-{% include "logout.tmpl" %}
-{% endblock %}
-
-{% block content %}
-
-<form name="hostdata" action="?sub=true" method="post">
-<input type="hidden" name="host">
-<table border="0" width="100%">
- <colgroup>
- <col width="150">
- <col width="*">
- <tr> <td> <b>hostname</b></td>
- <td> <input name="hostname" type="text" ></td></tr>
- <tr> <td> <b>whatami</b></td>
- <td>
- <select name="whatami">
- {% for choice in WHATAMI_CHOICES %}
- <option value="{{ choice.0 }}">{{ choice.1 }}
- {% endfor %}
- </select>
- </td></tr>
- <tr> <td> <b>netgroup</b></td>
- <td>
- <select name="netgroup">
- {% for choice in NETGROUP_CHOICES %}
- <option value="{{ choice.0 }}">{{ choice.1 }}
- {% endfor %}
- </select>
- </td></tr>
- <tr> <td> <b>class</b></td>
- <td>
- <select name="security_class">
- {% for choice in CLASS_CHOICES %}
- <option value="{{ choice.0 }}">{{ choice.1 }}
- {% endfor %}
- </select></td></tr>
- <tr> <td> <b>support</b></td>
- <td>
- <select name="support">
- {% for choice in SUPPORT_CHOICES %}
- <option value="{{ choice.0 }}">{{ choice.1 }}
- {% endfor %}
- </select></td></tr>
- <tr> <td> <b>csi</b></td>
- <td> <input name="csi" type="text" ></td></tr>
- <tr> <td> <b>printq</b></td>
- <td> <input name="printq" type="text" ></td></tr>
- <tr> <td> <b>outbound_smtp</b></td>
- <td>
- <input type="checkbox" name="outbound_smtp"></td></tr>
- <tr> <td> <b>primary_user</b></td>
- <td> <input name="primary_user" type="text" size="32" > (email address)</td></tr>
- <tr> <td> <b>administrator</b></td>
- <td> <input name="administrator" type="text" size="32" > (email address)</td></tr>
- <tr> <td> <b>location</b></td>
- <td> <input name="location" type="text" ></td></tr>
- <tr> <td> <b>expiration_date</b></td>
- <td> <input name="expiration_date" type="text" size="10" >YYYY-MM-DD</td></tr>
- <tr> <td><br><b>Interface</b></td><td><br>
- {% for choice in TYPE_CHOICES %}
- <input type="radio" name="hdwr_type_new" value="{{ choice.0 }}" >{{ choice.1 }}
- {% endfor %}
- </td></tr>
- <tr> <td> <b>dhcp</b></td>
- <td>
- <input type="checkbox" name="dhcp_new"></td></tr>
- <tr> <td> <b>mac_addr</b></td>
- <td> <input name="mac_addr_new" type="text"></td></tr>
- <tr> <td> <b>ip_addr</b></td>
- <td> <input name="ip_addr_new" type="text"></td></tr>
- <tr> <td><br><b>Interface</b></td><td><br>
- {% for choice in TYPE_CHOICES %}
- <input type="radio" name="hdwr_type_new2" value="{{ choice.0 }}" >{{ choice.1 }}
- {% endfor %}
- </td></tr>
- <tr> <td> <b>dhcp</b></td>
- <td>
- <input type="checkbox" name="dhcp_new2"></td></tr>
- <tr> <td> <b>mac_addr</b></td>
- <td> <input name="mac_addr_new2" type="text"></td></tr>
- <tr> <td> <b>ip_addr</b></td>
- <td> <input name="ip_addr_new2" type="text"></td></tr>
- <tr> <td> <b>comments</b></td>
- <td> <textarea rows="10" cols="50" name="comments"></textarea></td></tr>
-</table>
-<br>
-<p><input type="submit" value="Submit">
-</form>
-
-{% endblock %}
-
diff --git a/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/remove.html b/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/remove.html
deleted file mode 100644
index 4329200dd..000000000
--- a/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/remove.html
+++ /dev/null
@@ -1,89 +0,0 @@
-{% extends "base.html" %}
-
-{% block pagebanner %}
- <div class="header">
- <h2>Are you sure you want to remove {{ host.hostname }}?</h2>
- </div>
- <br/>
-{% endblock %}
-
-{% block sidebar %}
-{% include "navbar.tmpl" %}
-<ul class="sidebar">
- <li><a href="dns/" class="sidebar">detailed dns info</a></li>
- <li><a href="edit/" class="sidebar">edit host info</a></li>
- <li><a href="dns/edit/" class="sidebar">edit dns info</a></li>
-</ul>
-{% include "logout.tmpl" %}
-{% endblock %}
-
-{% block content %}
-
-<table border="0" width="100%">
- <colgroup>
- <col width="150">
- <col width="*">
- <tr> <td> <b>hostname</b></td>
- <td> {{ host.hostname }}</td></tr>
- <tr> <td> <b>whatami</b></td>
- <td> {{ host.whatami }}</td></tr>
- <tr> <td> <b>netgroup</b></td>
- <td> {{ host.netgroup }}</td></tr>
- <tr> <td> <b>class</b></td>
- <td> {{ host.security_class }}</td></tr>
- <tr> <td> <b>support</b></td>
- <td> {{ host.support }}</td></tr>
- <tr> <td> <b>csi</b></td>
- <td> {{ host.csi }}</td></tr>
- <tr> <td> <b>printq</b></td>
- <td> {{ host.printq }}</td></tr>
- <tr> <td> <b>dhcp</b></td>
- {% if host.dhcp %}
- <td> y </td></tr>
- {% else %}
- <td> n </td></tr>
- {% endif %}
- <tr> <td> <b>outbound_smtp</b></td>
- {% if host.outbound_smtp %}
- <td> y </td></tr>
- {% else %}
- <td> n </td></tr>
- {% endif %}
- <tr> <td> <b>primary_user</b></td>
- <td> {{ host.primary_user }}</td></tr>
- <tr> <td> <b>administrator</b></td>
- <td> {{ host.administrator }}</td></tr>
- <tr> <td> <b>location</b></td>
- <td> {{ host.location }}</td></tr>
- <tr> <td> <b>expiration_date</b></td>
- <td> {{ host.expiration_date }}</td></tr>
- {% for interface in interfaces %}
- <tr> <td><br><b>Interface</b></td>
- {% ifnotequal interface.0.hdwr_type 'no' %}
- <td><br>{{ interface.0.hdwr_type }}</td></tr>
- {% endifnotequal %}
- <tr> <td> <b>mac_addr</b></td>
- <td> {{ interface.0.mac_addr }}</b></td></tr>
- {% for ip in interface.1 %}
- <tr> <td> <b>ip_addr</b></td>
- <td> {{ ip.ip_addr }}</td></tr>
- {% endfor %}
- {% endfor %}
- <tr> <td valign="top"> <b>comments</b></td>
- <td>
- {{ host.comments|linebreaksbr }}<br>
- </td></tr>
-
-</table>
-<a style="font-size:75%" href="/hostbase/{{ host.id }}/dns/">see detailed DNS information for this host</a>
-<br><br>
-this host is {{ host.status }}<br>
-last update on {{ host.last }}<br>
-
-<form name="input" action="remove.html?sub=true" method="post">
-<input type="submit" value="remove">
-<input type="reset" value="cancel" onclick="history.back()">
-</form>
-
-{% endblock %}
-
diff --git a/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/results.html b/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/results.html
deleted file mode 100644
index 45b22058d..000000000
--- a/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/results.html
+++ /dev/null
@@ -1,45 +0,0 @@
-{% extends "base.html" %}
-
-{% block pagebanner %}
- <div class="header">
- <h2>Search Results</h2>
- </div>
- <br/>
-{% endblock %}
-
-{% block sidebar %}
-{% include "navbar.tmpl" %}
-{% include "logout.tmpl" %}
-{% endblock %}
-
-{% block content %}
-
-{% if hosts %}
-<table border="0" width="100%">
- <colgroup>
- <col width="200">
- <col width="75">
- <col width="50">
- <col width="50">
- <col width="50">
- <col width="*">
- <tr> <td><b>hostname</b></td>
- <td> <b>status</b> </td>
- </tr>
- {% for host in hosts %}
- <tr> <td>{{ host.0 }}</td>
- <td> {{ host.2 }} </td>
- <td> <a href="{{ host.1 }}">view</a> </td>
- <td> <a href="{{ host.1 }}/edit">edit</a> </td>
- <td> <a href="{{ host.1 }}/copy">copy</a> </td>
- <td> <a href="{{ host.1 }}/logs">logs</a> </td>
-<!-- <td> <a href="{{ host.1 }}/remove">remove</a> </td> -->
- </tr>
- {% endfor %}
-</table>
-{% else %}
-No hosts matched your query<br>
-Click the back button on your browser to edit your search
-{% endif %}
-
-{% endblock %}
diff --git a/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/search.html b/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/search.html
deleted file mode 100644
index 409d418fe..000000000
--- a/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/search.html
+++ /dev/null
@@ -1,57 +0,0 @@
-{% extends "base.html" %}
-
-{% block pagebanner %}
- <div class="header">
- <h2>Welcome to Hostbase!</h2>
- <p>search for hosts using one or more of the fields below
- </div>
- <br/>
-{% endblock %}
-
-{% block sidebar %}
-<a href="/hostbase/new" class="sidebar">add a new host</a><br>
-<a href="/hostbase/zones" class="sidebar">zone file information</a><br>
-{% include "logout.tmpl" %}
-{% endblock %}
-
-{% block content %}
-{% comment %}
- ...or go to <a href="hostinfo">this</a>
- page to enter hostinfo-like queries<br><br>
-{% endcomment %}
-
-<form name="input" action="?sub=true" method="post">
- <fieldset class="module aligned ()">
- <label for="hostname">hostname:</label><input name="hostname" type="text" ><br>
- <label for="netgroup">netgroup:</label><input name="netgroup" type="text" ><br>
- <label for="security_class">class:</label><input name="security_class" type="text" ><br>
- <label for="support">support:</label><input name="support" type="text" ><br>
- <label for="csi">csi:</label><input name="csi" type="text" ><br>
- <label for="printq">printq:</label><input name="printq" type="text" ><br>
- <label for="outbound_smtp">outbound_smtp:</label>
- {% for choice in yesno %}
- <input type="radio" name="outbound_smtp" value="{{ choice.0 }}" >{{ choice.1 }}
- {% endfor %}<br>
- <label for="primary_user">primary_user:</label><input name="primary_user" type="text" ><br>
- <label for="administrator">administrator:</label><input name="administrator" type="text" ><br>
- <label for="location">location:</label><input name="location" type="text" ><br>
- <label for="expiration_date">expiration_date:</label><input name="expiration_date" type="text" ><br>
- <br><label for="Interface">Interface:</label>
- {% for choice in TYPE_CHOICES %}
- <input type="radio" name="hdwr_type" value="{{ choice.0 }}" >{{ choice.1 }}
- {% endfor %}<br>
- <label for="dhcp">dhcp:</label>
- {% for choice in yesno %}
- <input type="radio" name="dhcp" value="{{ choice.0 }}" >{{ choice.1 }}
- {% endfor %}<br>
- <label for="mac_addr">mac_addr:</label><input name="mac_addr" type="text" ><br>
- <label for="ip_addr">ip_addr:</label><input name="ip_addr" type="text" ><br>
- <label for="dns_view">dns_viewer:</label>
- {% for choice in DNS_CHOICES %}
- <input type="radio" name="dns_view" value="{{ choice.0 }}" >{{ choice.1 }}
- {% endfor %}<br>
- <label for="mx">mx:</label><input name="mx" type="text" ><br>
-<p>
-<input type="submit" value="Search">
-</form>
-{% endblock %}
diff --git a/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/zoneedit.html b/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/zoneedit.html
deleted file mode 100644
index ee355ee87..000000000
--- a/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/zoneedit.html
+++ /dev/null
@@ -1,81 +0,0 @@
-{% extends "base.html" %}
-
-{% block pagebanner %}
- <div class="header">
- <h2>Zones</h2>
- <p>Edit information for {{ zone }}
- </div>
- <br/>
-{% endblock %}
-
-{% block sidebar %}
-{% include "navbar.tmpl" %}
-<ul>
-<li><a href="/hostbase/zones/{{ zone_id }}/" class="sidebar">view zone</a><br>
-</li>
-</ul>
-{% include "logout.tmpl" %}
-{% endblock %}
-
-{% block content %}
-
-<script language="JavaScript" type="text/Javascript">
-function toggleField(fieldname){
- if(document.getElementById){
- var style = document.getElementById(fieldname).style;
- style.display = style.display? "":"block";
- }
-}
-</script>
-
-<style type=text/css>
-div#nameserver{
- display: none;
-}
-div#mx{
- display: none;
-}
-div#address{
- display: none;
-}
-</style>
-
-<form name="zonedata" action="" method="post">
- <fieldset class="module aligned ()">
-<label for="id_zone">zone:</label></td> <td>{{ form.zone }}<br>
-<label for="id_admin">admin:</label></td> <td>{{ form.admin }}<br>
-<label for="id_primary_master">primary_master:</label></td> <td>{{ form.primary_master }}<br>
-<label for="id_expire">expire:</label></td> <td>{{ form.expire }}<br>
-<label for="id_retry">retry:</label></td> <td>{{ form.retry }}<br>
-<label for="id_refresh">refresh:</label></td> <td>{{ form.refresh }}<br>
-<label for="id_ttl">ttl:</label></td> <td>{{ form.ttl }}<br>
-{% for ns in nsforms %}
-<label for="id_name">nameserver:</label></td> <td>{{ ns.name }}<br>
-{% endfor %}
-</table>
-<div id=nameserver>
- <label for="id_name">nameserver:</label></td> <td>{{ nsadd.name }}<br>
- <label for="id_name">nameserver:</label></td> <td>{{ nsadd.name }}<br>
-</div>
-<a style="font-size:75%" href=# onclick="toggleField('nameserver')">Add NS records</a><br>
-{% for mx in mxforms %}
-<label for="id_mx">mx:</label></td> <td>{{ mx.priority }} {{ mx.mx }}<br>
-{% endfor %}
-<div id=mx>
- <label for="id_mx">mx:</label></td> <td>{{ mxadd.priority }} {{ mxadd.mx }}<br>
- <label for="id_mx">mx:</label></td> <td>{{ mxadd.priority }} {{ mxadd.mx }}<br>
-</div>
-<a style="font-size:75%" href=# onclick="toggleField('mx')">Add MX records</a><br>
-{% for a in aforms %}
-<label for="id_address">ip address:</label></td> <td>{{ a.ip_addr }}<br>
-{% endfor %}
-<div id=address>
- <label for="id_address">ip address:</label></td> <td>{{ addadd.ip_addr }}<br>
- <label for="id_address">ip address:</label></td> <td>{{ addadd.ip_addr }}<br>
-</div>
-<a style="font-size:75%" href=# onclick="toggleField('address')">Add A records</a><br>
-<label for="id_aux">aux:</label></td> <td>{{ form.aux }}<br>
-<p><input type="submit" value="Submit">
-</form>
-
-{% endblock %}
diff --git a/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/zonenew.html b/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/zonenew.html
deleted file mode 100644
index b59fa9e3c..000000000
--- a/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/zonenew.html
+++ /dev/null
@@ -1,43 +0,0 @@
-{% extends "base.html" %}
-
-{% block pagebanner %}
- <div class="header">
- <h2>Zones</h2>
- <p>Enter information for a new zone to be generated by Hostbase
- </div>
- <br/>
-{% endblock %}
-
-{% block sidebar %}
-{% include "navbar.tmpl" %}
-{% include "logout.tmpl" %}
-{% endblock %}
-
-{% block content %}
-<form name="zonedata" action="" method="post">
- <fieldset class="module aligned ()">
- {{ form.as_p}}
-<!--
- <label for="id_zone">zone:</label>{{ form.zone }}<br>
- <label for="id_admin">admin:</label>{{ form.admin }}<br>
- <label for="id_primary_master">primary_master:</label>{{ form.primary_master }}<br>
- <label for="id_expire">expire:</label>{{ form.expire }}<br>
- <label for="id_retry">retry:</label>{{ form.retry }}<br>
- <label for="id_refresh">refresh:</label>{{ form.refresh }}<br>
- <label for="id_ttl">ttl:</label>{{ form.ttl }}<br>
- <label for="id_name">nameserver:</label>{{ nsform.name }}<br>
- <label for="id_name">nameserver:</label>{{ nsform.name }}<br>
- <label for="id_name">nameserver:</label>{{ nsform.name }}<br>
- <label for="id_name">nameserver:</label>{{ nsform.name }}<br>
- <label for="id_mx">mx:</label>{{ mxform.priority }} {{ mxform.mx }}<br>
- <label for="id_mx">mx:</label>{{ mxform.priority }} {{ mxform.mx }}<br>
- <label for="id_mx">ip address:</label>{{ aform.ip_addr }}<br>
- <label for="id_mx">ip address:</label>{{ aform.ip_addr }}<br>
- <label for="id_aux">aux:
-(information not generated from Hostbase)</label>{{ form.aux }}<br>
---!>
- <p><input type="submit" value="Submit">
- </fieldset>
-</form>
-{% endblock %}
-
diff --git a/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/zones.html b/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/zones.html
deleted file mode 100644
index c773e7922..000000000
--- a/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/zones.html
+++ /dev/null
@@ -1,37 +0,0 @@
-{% extends "base.html" %}
-
-{% block pagebanner %}
- <div class="header">
- <h2>Zones</h2>
- <p>Hostbase generates DNS zone files for the following zones.
- </div>
- <br/>
-{% endblock %}
-
-{% block sidebar %}
-{% include "navbar.tmpl" %}
-{% include "logout.tmpl" %}
-{% endblock %}
-
-{% block content %}
-{% if zone_list %}
-<table border="0" width="100%">
- <colgroup>
- <col width="200">
- <col width="75">
- <col width="50">
- <col width="*">
- <tr> <td><b>zone</b></td>
- </tr>
- {% for zone in zone_list|dictsort:"zone" %}
- <tr> <td> {{ zone.zone }}</td>
- <td> <a href="{{ zone.id }}">view</a> </td>
- <td> <a href="{{ zone.id }}/edit">edit</a> </td>
- </tr>
- {% endfor %}
-</table>
-{% else %}
-There is no zone data currently in the database<br>
-{% endif %}
-{% endblock %}
-
diff --git a/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/zoneview.html b/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/zoneview.html
deleted file mode 100644
index fa12e3ec5..000000000
--- a/src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/zoneview.html
+++ /dev/null
@@ -1,71 +0,0 @@
-{% extends "base.html" %}
-
-{% block pagebanner %}
- <div class="header">
- <h2>Zones</h2>
- <p>Hostbase generates DNS zone files for the following zones.
- </div>
- <br/>
-{% endblock %}
-
-{% block sidebar %}
-{% include "navbar.tmpl" %}
-<ul class="sidebar">
-<li><a href="/hostbase/zones/{{ zone.id }}/edit/" class="sidebar">edit zone</a><br>
-</li>
-</ul>
-{% include "logout.tmpl" %}
-{% endblock %}
-
-{% block content %}
-<table border="0" width="100%">
- <colgroup>
- <col width="200">
- <col width="*">
- <tr> <td> <b>zone</b></td>
- <td> {{ zone.zone }}</td></tr>
- <tr> <td> <b>serial</b></td>
- <td> {{ zone.serial }}</td></tr>
- <tr> <td> <b>admin</b></td>
- <td> {{ zone.admin }}</td></tr>
- <tr> <td> <b>primary_master</b></td>
- <td> {{ zone.primary_master }}</td></tr>
- <tr> <td> <b>expire</b></td>
- <td> {{ zone.expire }}</td></tr>
- <tr> <td> <b>retry</b></td>
- <td> {{ zone.retry }}</td></tr>
- <tr> <td> <b>refresh</b></td>
- <td> {{ zone.refresh }}</td></tr>
- <tr> <td> <b>ttl</b></td>
- <td> {{ zone.ttl }}</td></tr>
-
- <tr><td valign="top"> <b>nameservers</b></td>
- <td>
- {% for nameserver in zone.nameservers.all %}
- {{ nameserver.name }}<br>
- {% endfor %}
- </td></tr>
- <tr><td valign="top"> <b>mxs</b></td>
- <td>
- {% for mx in zone.mxs.all %}
- {{ mx.priority }} {{ mx.mx }}<br>
- {% endfor %}
- </td></tr>
- {% if addresses %}
- <tr><td valign="top"> <b>A records</b></td>
- <td>
- {% for address in sof.addresses.all %}
- {{ address.ip_addr }}<br>
- {% endfor %}
- </td></tr>
- {% endif %}
-
- <tr> <td valign="top"> <b>aux</b></td>
- <td>
- {{ zone.aux|linebreaksbr }}
- </td></tr>
-
-</table>
-<br><br>
-{% endblock %}
-
diff --git a/src/lib/Bcfg2/Server/Hostbase/ldapauth.py b/src/lib/Bcfg2/Server/Hostbase/ldapauth.py
deleted file mode 100644
index fc2ca1bf1..000000000
--- a/src/lib/Bcfg2/Server/Hostbase/ldapauth.py
+++ /dev/null
@@ -1,179 +0,0 @@
-"""
-Checks with LDAP (ActiveDirectory) to see if the current user is an LDAP(AD)
-user, and returns a subset of the user's profile that is needed by Argonne/CIS
-to set user level privleges in Django
-"""
-
-import os
-import ldap
-
-
-class LDAPAUTHError(Exception):
- """LDAPAUTHError is raised when somehting goes boom."""
- pass
-
-
-class ldapauth(object):
- group_test = False
- check_member_of = os.environ['LDAP_CHECK_MBR_OF_GRP']
- securitylevel = 0
- distinguishedName = None
- sAMAccountName = None
- telephoneNumber = None
- title = None
- memberOf = None
- department = None # this will be a list
- mail = None
- extensionAttribute1 = None # badgenumber
- badge_no = None
-
- def __init__(self, login, passwd):
- """get username (if using ldap as auth the
- apache env var REMOTE_USER should be used)
- from username get user profile from AD/LDAP
- """
- #p = self.user_profile(login,passwd)
- d = self.user_dn(login) # success, distname
- print(d[1])
- if d[0] == 'success':
- pass
- p = self.user_bind(d[1], passwd)
- if p[0] == 'success':
- #parse results
- parsed = self.parse_results(p[2])
- print(self.department)
- self.group_test = self.member_of()
- securitylevel = self.security_level()
- print("ACCESS LEVEL: " + str(securitylevel))
- else:
- raise LDAPAUTHError(p[2])
- else:
- raise LDAPAUTHError(p[2])
-
- def user_profile(self, login, passwd=None):
- """NOT USED RIGHT NOW"""
- ldap_login = "CN=%s" % login
- svc_acct = os.environ['LDAP_SVC_ACCT_NAME']
- svc_pass = os.environ['LDAP_SVC_ACCT_PASS']
- #svc_acct = 'CN=%s,DC=anl,DC=gov' % login
- #svc_pass = passwd
-
- search_pth = os.environ['LDAP_SEARCH_PTH']
-
- try:
- conn = ldap.initialize(os.environ['LDAP_URI'])
- conn.bind(svc_acct, svc_pass, ldap.AUTH_SIMPLE)
- result_id = conn.search(search_pth,
- ldap.SCOPE_SUBTREE,
- ldap_login,
- None)
- result_type, result_data = conn.result(result_id, 0)
- return ('success', 'User profile found', result_data,)
- except ldap.LDAPError:
- e = sys.exc_info()[1]
- #connection failed
- return ('error', 'LDAP connect failed', e,)
-
- def user_bind(self, distinguishedName, passwd):
- """Binds to LDAP Server"""
- search_pth = os.environ['LDAP_SEARCH_PTH']
- try:
- conn = ldap.initialize(os.environ['LDAP_URI'])
- conn.bind(distinguishedName, passwd, ldap.AUTH_SIMPLE)
- cn = distinguishedName.split(",")
- result_id = conn.search(search_pth,
- ldap.SCOPE_SUBTREE,
- cn[0],
- None)
- result_type, result_data = conn.result(result_id, 0)
- return ('success', 'User profile found', result_data,)
- except ldap.LDAPError:
- e = sys.exc_info()[1]
- #connection failed
- return ('error', 'LDAP connect failed', e,)
-
- def user_dn(self, cn):
- """Uses Service Account to get distinguishedName"""
- ldap_login = "CN=%s" % cn
- svc_acct = os.environ['LDAP_SVC_ACCT_NAME']
- svc_pass = os.environ['LDAP_SVC_ACCT_PASS']
- search_pth = os.environ['LDAP_SEARCH_PTH']
-
- try:
- conn = ldap.initialize(os.environ['LDAP_URI'])
- conn.bind(svc_acct, svc_pass, ldap.AUTH_SIMPLE)
- result_id = conn.search(search_pth,
- ldap.SCOPE_SUBTREE,
- ldap_login,
- None)
- result_type, result_data = conn.result(result_id, 0)
- raw_obj = result_data[0][1]
- distinguishedName = raw_obj['distinguishedName']
- return ('success', distinguishedName[0],)
- except ldap.LDAPError:
- e = sys.exc_info()[1]
- #connection failed
- return ('error', 'LDAP connect failed', e,)
-
- def parse_results(self, user_obj):
- """Clean up the huge ugly object handed to us in the LDAP query"""
- #user_obj is a list formatted like this:
- #[('LDAP_DN',{user_dict},),]
- try:
- raw_obj = user_obj[0][1]
- self.memberOf = raw_obj['memberOf']
- self.sAMAccountName = raw_obj['sAMAccountName'][0]
- self.distinguishedName = raw_obj['distinguishedName'][0]
- self.telephoneNumber = raw_obj['telephoneNumber'][0]
- self.title = raw_obj['title'][0]
- self.department = raw_obj['department'][0]
- self.mail = raw_obj['mail'][0]
- self.badge_no = raw_obj['extensionAttribute1'][0]
- self.email = raw_obj['extensionAttribute2'][0]
- display_name = raw_obj['displayName'][0].split(",")
- self.name_f = raw_obj['givenName'][0]
- self.name_l = display_name[0]
- self.is_staff = False
- self.is_superuser = False
-
- return
- except KeyError:
- e = sys.exc_info()[1]
- raise LDAPAUTHError("Portions of the LDAP User profile not present")
-
- def member_of(self):
- """See if this user is in our group that is allowed to login"""
- m = [g for g in self.memberOf if g == self.check_member_of]
- if len(m) == 1:
- return True
- else:
- return False
-
- def security_level(self):
- level = self.securitylevel
-
- user = os.environ['LDAP_GROUP_USER']
- m = [g for g in self.memberOf if g == user]
- if len(m) == 1:
- if level < 1:
- level = 1
-
- cspr = os.environ['LDAP_GROUP_SECURITY_LOW']
- m = [g for g in self.memberOf if g == cspr]
- if len(m) == 1:
- if level < 2:
- level = 2
-
- cspo = os.environ['LDAP_GROUP_SECURITY_HIGH']
- m = [g for g in self.memberOf if g == cspo]
- if len(m) == 1:
- if level < 3:
- level = 3
-
- admin = os.environ['LDAP_GROUP_ADMIN']
- m = [g for g in self.memberOf if g == admin]
- if len(m) == 1:
- if level < 4:
- level = 4
-
- return level
diff --git a/src/lib/Bcfg2/Server/Hostbase/manage.py b/src/lib/Bcfg2/Server/Hostbase/manage.py
deleted file mode 100755
index 5e78ea979..000000000
--- a/src/lib/Bcfg2/Server/Hostbase/manage.py
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/usr/bin/env python
-from django.core.management import execute_manager
-try:
- import settings # Assumed to be in the same directory.
-except ImportError:
- import sys
- sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
- sys.exit(1)
-
-if __name__ == "__main__":
- execute_manager(settings)
diff --git a/src/lib/Bcfg2/Server/Hostbase/media/base.css b/src/lib/Bcfg2/Server/Hostbase/media/base.css
deleted file mode 100644
index ddbf02165..000000000
--- a/src/lib/Bcfg2/Server/Hostbase/media/base.css
+++ /dev/null
@@ -1,5 +0,0 @@
-
-/* Import other styles */
-@import url('global.css');
-@import url('layout.css');
-@import url('boxypastel.css');
diff --git a/src/lib/Bcfg2/Server/Hostbase/media/boxypastel.css b/src/lib/Bcfg2/Server/Hostbase/media/boxypastel.css
deleted file mode 100644
index 7ae0684ef..000000000
--- a/src/lib/Bcfg2/Server/Hostbase/media/boxypastel.css
+++ /dev/null
@@ -1,179 +0,0 @@
-body {
- background-color: #fff;
- color: #000;
- font: 12px 'Lucida Grande', Arial, Helvetica, sans-serif;
- margin-left:0px;
- margin-right:100px;
-}
-/* links */
-a:link {
- color: #00f;
- text-decoration: none;
-}
-a:visited {
- color: #00a;
- text-decoration: none;
-}
-a:hover {
- color: #00a;
- text-decoration: underline;
-}
-a:active {
- color: #00a;
- text-decoration: underline;
-}
-/* divs*/
-div.bad {
- border: 1px solid #660000;
- background: #FF6A6A;
- margin: 10px 0;
- padding: 8px;
- text-align: left;
- margin-left:50px;
- margin-right:50px;
-}
-div.modified {
- border: 1px solid #CC9900;
- background: #FFEC8B;
- margin: 10px 0;
- padding: 8px;
- text-align: left;
- margin-left:50px;
- margin-right:50px;
-}
-div.clean {
- border: 1px solid #006600;
- background: #9AFF9A;
- margin: 10px 0;
- padding: 8px;
- text-align: left;
- margin-left:50px;
- margin-right:50px;
-}
-div.extra {
- border: 1px solid #006600;
- background: #6699CC;
- margin: 10px 0;
- padding: 8px;
- text-align: left;
- margin-left:50px;
- margin-right:50px;
-}
-div.warning {
- border: 1px
- solid #CC3300;
- background: #FF9933;
- margin: 10px 0;
- padding: 8px;
- text-align: left;
- margin-left:50px;
- margin-right:50px;
-}
-div.all-warning {
- border: 1px solid #DD5544;
- background: #FFD9A2;
- margin: 10px 0;
- padding: 8px;
- text-align: left;
- margin-left:50px;
- margin-right:50px;
-}
-div.down {
- border: 1px
- solid #999;
- background-color: #DDD;
- margin: 10px 0;
- padding: 8px;
- text-align: left;
- margin-left:50px;
- margin-right:50px;
-}
-div.items{
- display: none;
-}
-div.nodebox {
- border: 1px solid #c7cfd5;
- background: #f1f5f9;
- margin: 20px 0;
- padding: 8px 8px 16px 8px;
- text-align: left;
- position:relative;
-}
-div.header {
- background-color: #DDD;
- padding: 8px;
- text-indent:50px;
- position:relative;
-}
-
-/*Spans*/
-.nodename {
- font-style: italic;
-}
-.nodelisttitle {
- font-size: 14px;
-}
-
-h2{
- font-size: 16px;
- color: #000;
-}
-
-ul.plain {
- list-style-type:none;
- text-align: left;
-}
-
-.notebox {
- position: absolute;
- top: 0px;
- right: 0px;
- padding: 1px;
- text-indent:0px;
- border: 1px solid #FFF;
- background: #999;
- color: #FFF;
-}
-
-.configbox {
- position: absolute;
- bottom: 0px;
- right: 0px;
- padding: 1px;
- text-indent:0px;
- border: 1px solid #999;
- background: #FFF;
- color: #999;
-}
-
-p.indented{
- text-indent: 50px
-}
-
-/*
- Sortable tables */
-table.sortable a.sortheader {
- background-color:#dfd;
- font-weight: bold;
- text-decoration: none;
- display: block;
-}
-table.sortable {
- padding: 2px 4px 2px 4px;
- border: 1px solid #000000;
- border-spacing: 0px
-}
-td.sortable{
- padding: 2px 8px 2px 8px;
-}
-
-th.sortable{
- background-color:#F3DD91;
- border: 1px solid #FFFFFF;
-}
-tr.tablelist {
- background-color:#EDF3FE;
-}
-tr.tablelist-alt{
- background-color:#FFFFFF;
-}
diff --git a/src/lib/Bcfg2/Server/Hostbase/media/global.css b/src/lib/Bcfg2/Server/Hostbase/media/global.css
deleted file mode 100644
index 73451e1bc..000000000
--- a/src/lib/Bcfg2/Server/Hostbase/media/global.css
+++ /dev/null
@@ -1,8 +0,0 @@
-body {
- margin:0;
- padding:0;
- font-size:12px;
- font-family:"Lucida Grande","Bitstream Vera Sans",Verdana,Arial,sans-serif;
- color:#000;
- background:#fff;
- }
diff --git a/src/lib/Bcfg2/Server/Hostbase/media/layout.css b/src/lib/Bcfg2/Server/Hostbase/media/layout.css
deleted file mode 100644
index 9085cc220..000000000
--- a/src/lib/Bcfg2/Server/Hostbase/media/layout.css
+++ /dev/null
@@ -1,62 +0,0 @@
-/* Page Structure */
-#container { position:absolute; top: 3em; margin-left:1em; margin-right:2em; padding:0; margin-top:1.5em; min-width:
- 650px; }
-#header { width:100%; }
-#content-main { float:left; }
-
-/* HEADER */
-#header {
-background:#000;
-color:#ffc;
-position:absolute;
-}
-#header a:link, #header a:visited { color:white; }
-#header a:hover { text-decoration:underline; }
-#branding h1 { padding:0 10px; font-size:18px; margin:8px 0; font-weight:normal; color:#f4f379; }
-#branding h2 { padding:0 10px; font-size:14px; margin:-8px 0 8px 0; font-weight:normal; color:#ffc; }
-#user-tools { position:absolute; top:0; right:0; padding:1.2em 10px; font-size:11px; text-align:right; }
-
-/*SIDEBAR*/
-#sidebar {
- float:left;
- position: relative;
- width: auto;
- height: 100%;
- margin-top: 3em;
- padding-right: 1.5em;
- padding-left: 1.5em;
- padding-top: 1em;
- padding-bottom:3em;
- background: #000;
- color:ffc;
-}
-
-a.sidebar:link {color: #fff;}
-a.sidebar:active {color: #fff;}
-a.sidebar:visited {color: #fff;}
-a.sidebar:hover {color: #fff;}
-
-ul.sidebar {
- color: #ffc;
- text-decoration: none;
- list-style-type: none;
- text-indent: -1em;
-}
-ul.sidebar-level2 {
- text-indent: -2em;
- list-style-type: none;
- font-size: 11px;
-}
-
-/* ALIGNED FIELDSETS */
-.aligned label { display:block; padding:0 1em 3px 0; float:left; width:8em; }
-.aligned label.inline { display:inline; float:none; }
-.colMS .aligned .vLargeTextField, .colMS .aligned .vXMLLargeTextField { width:350px; }
-form .aligned p, form .aligned ul { margin-left:7em; padding-left:30px; }
-form .aligned table p { margin-left:0; padding-left:0; }
-form .aligned p.help { padding-left:38px; }
-.aligned .vCheckboxLabel { float:none !important; display:inline; padding-left:4px; }
-.colM .aligned .vLargeTextField, colM .aligned .vXMLLargeTextField { width:610px; }
-.checkbox-row p.help { margin-left:0; padding-left:0 !important; }
-
-
diff --git a/src/lib/Bcfg2/Server/Hostbase/nisauth.py b/src/lib/Bcfg2/Server/Hostbase/nisauth.py
deleted file mode 100644
index ae4c6c021..000000000
--- a/src/lib/Bcfg2/Server/Hostbase/nisauth.py
+++ /dev/null
@@ -1,40 +0,0 @@
-"""Checks with NIS to see if the current user is in the support group"""
-import os
-import crypt, nis
-from Bcfg2.Server.Hostbase.settings import AUTHORIZED_GROUP
-
-
-class NISAUTHError(Exception):
- """NISAUTHError is raised when somehting goes boom."""
- pass
-
-class nisauth(object):
- group_test = False
-# check_member_of = os.environ['LDAP_CHECK_MBR_OF_GRP']
- samAcctName = None
- distinguishedName = None
- sAMAccountName = None
- telephoneNumber = None
- title = None
- memberOf = None
- department = None #this will be a list
- mail = None
- extensionAttribute1 = None #badgenumber
- badge_no = None
- uid = None
-
- def __init__(self,login,passwd=None):
- """get user profile from NIS"""
- try:
- p = nis.match(login, 'passwd.byname').split(":")
- except:
- raise NISAUTHError('username')
- # check user password using crypt and 2 character salt from passwd file
- if p[1] == crypt.crypt(passwd, p[1][:2]):
- # check to see if user is in valid support groups
- # will have to include these groups in a settings file eventually
- if not login in nis.match(AUTHORIZED_GROUP, 'group.byname').split(':')[-1].split(',') and p[3] != nis.match(AUTHORIZED_GROUP, 'group.byname').split(':')[2]:
- raise NISAUTHError('group')
- self.uid = p[2]
- else:
- raise NISAUTHError('password')
diff --git a/src/lib/Bcfg2/Server/Hostbase/regex.py b/src/lib/Bcfg2/Server/Hostbase/regex.py
deleted file mode 100644
index 41cc0f6f0..000000000
--- a/src/lib/Bcfg2/Server/Hostbase/regex.py
+++ /dev/null
@@ -1,6 +0,0 @@
-import re
-
-date = re.compile('^[0-9]{4}-[0-9]{2}-[0-9]{2}$')
-host = re.compile('^[a-z0-9-_]+(\.[a-z0-9-_]+)+$')
-macaddr = re.compile('^[0-9abcdefABCDEF]{2}(:[0-9abcdefABCDEF]{2}){5}$|virtual')
-ipaddr = re.compile('^[0-9]{1,3}(\.[0-9]{1,3}){3}$')
diff --git a/src/lib/Bcfg2/Server/Hostbase/settings.py b/src/lib/Bcfg2/Server/Hostbase/settings.py
deleted file mode 100644
index 7660e1bdc..000000000
--- a/src/lib/Bcfg2/Server/Hostbase/settings.py
+++ /dev/null
@@ -1,143 +0,0 @@
-import os.path
-# Compatibility import
-from Bcfg2.Compat import ConfigParser
-
-PROJECT_ROOT = os.path.abspath(os.path.dirname(__file__))
-
-c = ConfigParser.ConfigParser()
-#This needs to be configurable one day somehow
-c.read(['./bcfg2.conf'])
-
-defaults = {'database_engine':'sqlite3',
- 'database_name':'./dev.db',
- 'database_user':'',
- 'database_password':'',
- 'database_host':'',
- 'database_port':3306,
- 'default_mx':'localhost',
- 'priority':10,
- 'authorized_group':'admins',
- }
-
-if c.has_section('hostbase'):
- options = dict(c.items('hostbase'))
-else:
- options = defaults
-
-# Django settings for Hostbase project.
-DEBUG = True
-TEMPLATE_DEBUG = DEBUG
-ADMINS = (
- ('Root', 'root'),
-)
-MANAGERS = ADMINS
-
-# 'postgresql', 'mysql', 'sqlite3' or 'ado_mssql'.
-DATABASE_ENGINE = options['database_engine']
-# Or path to database file if using sqlite3.
-DATABASE_NAME = options['database_name']
-# Not used with sqlite3.
-DATABASE_USER = options['database_user']
-# Not used with sqlite3.
-DATABASE_PASSWORD = options['database_password']
-# Set to empty string for localhost. Not used with sqlite3.
-DATABASE_HOST = options['database_host']
-# Set to empty string for default. Not used with sqlite3.
-DATABASE_PORT = int(options['database_port'])
-# Local time zone for this installation. All choices can be found here:
-# http://docs.djangoproject.com/en/dev/ref/settings/#time-zone
-try:
- TIME_ZONE = c.get('statistics', 'time_zone')
-except:
- TIME_ZONE = None
-
-# enter the defauly MX record machines will get in Hostbase
-# this setting may move elsewhere eventually
-DEFAULT_MX = options['default_mx']
-PRIORITY = int(options['priority'])
-
-SESSION_EXPIRE_AT_BROWSER_CLOSE = True
-
-# Uncomment a backend below if you would like to use it for authentication
-AUTHENTICATION_BACKENDS = ('django.contrib.auth.backends.ModelBackend',
- 'Bcfg2.Server.Hostbase.backends.NISBackend',
- #'Bcfg2.Server.Hostbase.backends.LDAPBacken',
- )
-# enter an NIS group name you'd like to give access to edit hostbase records
-AUTHORIZED_GROUP = options['authorized_group']
-
-#create login url area:
-import django.contrib.auth
-django.contrib.auth.LOGIN_URL = '/login'
-# Absolute path to the directory that holds media.
-# Example: "/home/media/media.lawrence.com/"
-MEDIA_ROOT = os.path.join(PROJECT_ROOT, 'media')
-# Just for development
-SERVE_MEDIA = DEBUG
-
-# Language code for this installation. All choices can be found here:
-# http://www.w3.org/TR/REC-html40/struct/dirlang.html#langcodes
-# http://blogs.law.harvard.edu/tech/stories/storyReader$15
-LANGUAGE_CODE = 'en-us'
-SITE_ID = 1
-# URL that handles the media served from MEDIA_ROOT.
-# Example: "http://media.lawrence.com"
-MEDIA_URL = '/site_media/'
-# URL prefix for admin media -- CSS, JavaScript and images. Make sure to use a
-# trailing slash.
-# Examples: "http://foo.com/media/", "/media/".
-ADMIN_MEDIA_PREFIX = '/media/'
-# Make this unique, and don't share it with anybody.
-SECRET_KEY = '*%=fv=yh9zur&gvt4&*d#84o(cy^-*$ox-v1e9%32pzf2*qu#s'
-# List of callables that know how to import templates from various sources.
-TEMPLATE_LOADERS = (
- 'django.template.loaders.filesystem.load_template_source',
- 'django.template.loaders.app_directories.load_template_source',
-# 'django.template.loaders.eggs.load_template_source',
-)
-
-TEMPLATE_CONTEXT_PROCESSORS = (
- "django.core.context_processors.auth",
- "django.core.context_processors.debug",
- "django.core.context_processors.i18n",
- "django.core.context_processors.request",
- "django.core.context_processors.media",
-# Django development version.
-# "django.core.context_processors.csrf",
-)
-
-
-MIDDLEWARE_CLASSES = (
- 'django.middleware.common.CommonMiddleware',
- 'django.contrib.sessions.middleware.SessionMiddleware',
- 'django.middleware.locale.LocaleMiddleware',
- 'django.contrib.auth.middleware.AuthenticationMiddleware',
- 'django.middleware.doc.XViewMiddleware',
-)
-
-ROOT_URLCONF = 'Bcfg2.Server.Hostbase.urls'
-
-TEMPLATE_DIRS = (
- # Put strings here, like "/home/html/django_templates".
- # Always use forward slashes, even on Windows.
- '/usr/lib/python2.3/site-packages/Bcfg2/Server/Hostbase/hostbase/webtemplates',
- '/usr/lib/python2.4/site-packages/Bcfg2/Server/Hostbase/hostbase/webtemplates',
- '/usr/lib/python2.3/site-packages/Bcfg2/Server/Hostbase/templates',
- '/usr/lib/python2.4/site-packages/Bcfg2/Server/Hostbase/templates',
- '/usr/share/bcfg2/Hostbase/templates',
- os.path.join(PROJECT_ROOT, 'templates'),
- os.path.join(PROJECT_ROOT, 'hostbase/webtemplates'),
-)
-
-INSTALLED_APPS = (
- 'django.contrib.admin',
- 'django.contrib.admindocs',
- 'django.contrib.auth',
- 'django.contrib.contenttypes',
- 'django.contrib.sessions',
- 'django.contrib.sites',
- 'django.contrib.humanize',
- 'Bcfg2.Server.Hostbase.hostbase',
-)
-
-LOGIN_URL = '/login/'
diff --git a/src/lib/Bcfg2/Server/Hostbase/templates/batchadd.tmpl b/src/lib/Bcfg2/Server/Hostbase/templates/batchadd.tmpl
deleted file mode 100644
index 74ea3c047..000000000
--- a/src/lib/Bcfg2/Server/Hostbase/templates/batchadd.tmpl
+++ /dev/null
@@ -1,29 +0,0 @@
-#mx ->
-#priority ->
-
-hostname ->
-whatami ->
-netgroup ->
-security_class ->
-support ->
-csi ->
-printq ->
-dhcp ->
-outbound_smtp ->
-primary_user ->
-administrator ->
-location ->
-expiration_date -> YYYY-MM-DD
-comments ->
-
-mac_addr ->
-hdwr_type ->
-ip_addr ->
-#ip_addr ->
-cname ->
-#cname ->
-
-#mac_addr ->
-#hdwr_type ->
-#ip_addr ->
-#cname ->
diff --git a/src/lib/Bcfg2/Server/Hostbase/templates/dhcpd.conf.head b/src/lib/Bcfg2/Server/Hostbase/templates/dhcpd.conf.head
deleted file mode 100644
index a3d19547e..000000000
--- a/src/lib/Bcfg2/Server/Hostbase/templates/dhcpd.conf.head
+++ /dev/null
@@ -1,5 +0,0 @@
-#
-# dhcpd.conf
-#
-# Configuration file for ISC dhcpd
-#
diff --git a/src/lib/Bcfg2/Server/Hostbase/templates/dhcpd.tmpl b/src/lib/Bcfg2/Server/Hostbase/templates/dhcpd.tmpl
deleted file mode 100644
index 757b263cd..000000000
--- a/src/lib/Bcfg2/Server/Hostbase/templates/dhcpd.tmpl
+++ /dev/null
@@ -1,17 +0,0 @@
-#
-# This file is automatically generated.
-# DO NOT EDIT IT BY HAND!
-#
-# This file contains {{ numips }} IP addresses
-# Generated on: {% now "r" %}
-#
-
-{% include "dhcpd.conf.head" %}
-
-# Hosts which require special configuration options can be listed in
-# host statements. If no address is specified, the address will be
-# allocated dynamically (if possible), but the host-specific information
-# will still come from the host declaration.
-
-{% for host in hosts %}host {{ host.0 }} {hardware ethernet {{ host.1 }};fixed-address {{ host.2 }};}
-{% endfor %}
diff --git a/src/lib/Bcfg2/Server/Hostbase/templates/hosts.tmpl b/src/lib/Bcfg2/Server/Hostbase/templates/hosts.tmpl
deleted file mode 100644
index 251cb5a79..000000000
--- a/src/lib/Bcfg2/Server/Hostbase/templates/hosts.tmpl
+++ /dev/null
@@ -1,26 +0,0 @@
-##############################################################################
-# MCS hosts file
-#
-# This file is generated automatically - DO NOT EDIT IT.
-#
-# Generated on: {% now "r" %}
-#
-
-127.0.0.1 localhost.mcs.anl.gov localhost
-
-# This file lists hosts in these domains:
-{% for domain in domain_data %}# {{ domain.0 }}: {{ domain.1 }}
-{% endfor %}
-#
-# This file lists hosts on these networks:
-#
-# Network Hosts
-# ---------------------------------------------------------------------
-{% for octet in two_octets_data %}# {{ octet.0 }} {{octet.1 }}
-{% endfor %}
-#
-{% for octet in three_octets_data %}# {{ octet.0 }} {{ octet.1 }}
-{% endfor %}
-#
-# Total host interfaces (ip addresses) in this file: {{ num_ips }}
-
diff --git a/src/lib/Bcfg2/Server/Hostbase/templates/hostsappend.tmpl b/src/lib/Bcfg2/Server/Hostbase/templates/hostsappend.tmpl
deleted file mode 100644
index 00e0d5d04..000000000
--- a/src/lib/Bcfg2/Server/Hostbase/templates/hostsappend.tmpl
+++ /dev/null
@@ -1,5 +0,0 @@
-##########################################################################
-# Hosts on subnet: {{ subnet.0 }}
-# total hosts: {{ subnet.1 }}
-{% for ip in ips %}{{ ip.0 }} {{ ip.1 }}{% if ip.4 and not ip.3 %} # {{ ip.5 }}{% else %}{% for name in ip.2 %} {{ name }}{% endfor %}{% for cname in ip.3 %} {{ cname }}{% endfor %} # {{ ip.5 }}{% endif %}
-{% endfor %}
diff --git a/src/lib/Bcfg2/Server/Hostbase/templates/named.tmpl b/src/lib/Bcfg2/Server/Hostbase/templates/named.tmpl
deleted file mode 100644
index 03e054198..000000000
--- a/src/lib/Bcfg2/Server/Hostbase/templates/named.tmpl
+++ /dev/null
@@ -1,69 +0,0 @@
-// This is the primary configuration file for the BIND DNS server named.
-//
-// Please read /usr/share/doc/bind9/README.Debian.gz for information on the
-// structure of BIND configuration files in Debian, *BEFORE* you customize
-// this configuration file.
-//
-
-include "/etc/bind/named.conf.options";
-
-include "/etc/bind/rndc.key";
-
-// prime the server with knowledge of the root servers
-zone "." {
- type hint;
- file "/etc/bind/db.root";
-};
-
-// be authoritative for the localhost forward and reverse zones, and for
-// broadcast zones as per RFC 1912
-{% for zone in zones %}
-zone "{{ zone.1 }}" {
- type master;
- file "/etc/bind/hostbase/{{ zone.1 }}";
- notify no;
- also-notify { 140.221.9.6;140.221.8.10; };
-};{% endfor %}
-
-zone "localhost" {
- type master;
- file "/etc/bind/db.local";
-};
-
-zone "127.in-addr.arpa" {
- type master;
- file "/etc/bind/db.127";
-};
-
-zone "0.in-addr.arpa" {
- type master;
- file "/etc/bind/db.0";
-};
-
-zone "255.in-addr.arpa" {
- type master;
- file "/etc/bind/db.255";
-};
-{% for reverse in reverses %}
-zone "{{ reverse.0 }}.in-addr.arpa" {
- type master;
- file "/etc/bind/hostbase/{{ reverse.0 }}.rev";
- notify no;
- also-notify { 140.221.9.6;140.221.8.10; };
-};{% endfor %}
-
-// zone "com" { type delegation-only; };
-// zone "net" { type delegation-only; };
-
-// From the release notes:
-// Because many of our users are uncomfortable receiving undelegated answers
-// from root or top level domains, other than a few for whom that behaviour
-// has been trusted and expected for quite some length of time, we have now
-// introduced the "root-delegations-only" feature which applies delegation-only
-// logic to all top level domains, and to the root domain. An exception list
-// should be specified, including "MUSEUM" and "DE", and any other top level
-// domains from whom undelegated responses are expected and trusted.
-// root-delegation-only exclude { "DE"; "MUSEUM"; };
-
-include "/etc/bind/named.conf.local";
-include "/etc/bind/named.conf.static";
diff --git a/src/lib/Bcfg2/Server/Hostbase/templates/namedviews.tmpl b/src/lib/Bcfg2/Server/Hostbase/templates/namedviews.tmpl
deleted file mode 100644
index 52021620e..000000000
--- a/src/lib/Bcfg2/Server/Hostbase/templates/namedviews.tmpl
+++ /dev/null
@@ -1,92 +0,0 @@
-// This is the primary configuration file for the BIND DNS server named.
-//
-// Please read /usr/share/doc/bind9/README.Debian.gz for information on the
-// structure of BIND configuration files in Debian, *BEFORE* you customize
-// this configuration file.
-//
-
-include "/etc/bind/named.conf.options";
-
-include "/etc/bind/rndc.key";
-
-view "internal" {
- match-clients { 140.221.9.6;140.221.8.10;140.221.8.88;140.221.8.15; };
- recursion yes;
- // prime the server with knowledge of the root servers
- zone "." {
- type hint;
- file "/etc/bind/db.root";
- };
- {% for zone in zones %}
- zone "{{ zone.1 }}" {
- type master;
- file "/etc/bind/hostbase/{{ zone.1 }}";
- notify no;
- also-notify { 140.221.9.6;140.221.8.10;140.221.8.88;140.221.8.15; };
- };{% endfor %}
- // be authoritative for the localhost forward and reverse zones, and for
- // broadcast zones as per RFC 1912
-
- zone "localhost" {
- type master;
- file "/etc/bind/db.local";
- };
-
- zone "127.in-addr.arpa" {
- type master;
- file "/etc/bind/db.127";
- };
-
- zone "0.in-addr.arpa" {
- type master;
- file "/etc/bind/db.0";
- };
-
- zone "255.in-addr.arpa" {
- type master;
- file "/etc/bind/db.255";
- };
- {% for reverse in reverses %}
- zone "{{ reverse.0 }}.in-addr.arpa" {
- type master;
- file "/etc/bind/hostbase/{{ reverse.0 }}.rev";
- notify no;
- also-notify { 140.221.9.6;140.221.8.10;140.221.8.88; };
- };{% endfor %}
- include "/etc/bind/named.conf.static";
-};
-
-view "external" {
- match-clients { any; };
- recursion no;
- {% for zone in zones %}
- zone "{{ zone.1 }}" {
- type master;
- file "/etc/bind/hostbase/{{ zone.1 }}.external";
- notify no;
- };{% endfor %}
-
- {% for reverse in reverses %}
- zone "{{ reverse.0 }}.in-addr.arpa" {
- type master;
- file "/etc/bind/hostbase/{{ reverse.0 }}.rev.external";
- notify no;
- };{% endfor %}
- include "/etc/bind/named.conf.static";
-};
-
-
-// zone "com" { type delegation-only; };
-// zone "net" { type delegation-only; };
-
-// From the release notes:
-// Because many of our users are uncomfortable receiving undelegated answers
-// from root or top level domains, other than a few for whom that behaviour
-// has been trusted and expected for quite some length of time, we have now
-// introduced the "root-delegations-only" feature which applies delegation-only
-// logic to all top level domains, and to the root domain. An exception list
-// should be specified, including "MUSEUM" and "DE", and any other top level
-// domains from whom undelegated responses are expected and trusted.
-// root-delegation-only exclude { "DE"; "MUSEUM"; };
-
-include "/etc/bind/named.conf.local";
diff --git a/src/lib/Bcfg2/Server/Hostbase/templates/reverseappend.tmpl b/src/lib/Bcfg2/Server/Hostbase/templates/reverseappend.tmpl
deleted file mode 100644
index 6ed520c98..000000000
--- a/src/lib/Bcfg2/Server/Hostbase/templates/reverseappend.tmpl
+++ /dev/null
@@ -1,4 +0,0 @@
-{% if fileorigin %}$ORIGIN {{ fileorigin }}.in-addr.arpa.{% endif %}
-$ORIGIN {{ inaddr }}.in-addr.arpa.
-{% for host in hosts %}{{ host.0.3 }} PTR {{ host.1 }}.
-{% endfor %}
diff --git a/src/lib/Bcfg2/Server/Hostbase/templates/reversesoa.tmpl b/src/lib/Bcfg2/Server/Hostbase/templates/reversesoa.tmpl
deleted file mode 100644
index d142eaf7f..000000000
--- a/src/lib/Bcfg2/Server/Hostbase/templates/reversesoa.tmpl
+++ /dev/null
@@ -1,13 +0,0 @@
-$ORIGIN .
-$TTL {{ zone.8 }}
-{{ inaddr }}.in-addr.arpa IN SOA {{ zone.4 }}. {{ zone.3 }} (
- {{ zone.2 }} ; serial
- {{ zone.7 }} ; refresh interval
- {{ zone.6 }} ; retry interval
- {{ zone.5 }} ; expire interval
- {{ zone.8 }} ; min ttl
- )
-
- {% for ns in nameservers %}NS {{ ns.0 }}
- {% endfor %}
-
diff --git a/src/lib/Bcfg2/Server/Hostbase/templates/zone.tmpl b/src/lib/Bcfg2/Server/Hostbase/templates/zone.tmpl
deleted file mode 100644
index aad48d179..000000000
--- a/src/lib/Bcfg2/Server/Hostbase/templates/zone.tmpl
+++ /dev/null
@@ -1,18 +0,0 @@
-$ORIGIN .
-$TTL {{ zone.8 }}
-{{ zone.1 }}. IN SOA {{ zone.4 }}. {{ zone.3 }}. (
- {{ zone.2 }} ; serial
- {{ zone.7 }} ; refresh interval
- {{ zone.6 }} ; retry interval
- {{ zone.5 }} ; expire interval
- {{ zone.8 }} ; min ttl
- )
-
- {% for ns in nameservers %}NS {{ ns.0 }}
- {% endfor %}
- {% for a in addresses %}A {{ a.0 }}
- {% endfor %}
- {% for mx in mxs %}MX {{ mx.0 }} {{ mx.1 }}
- {% endfor %}
-$ORIGIN {{ zone.1 }}.
-localhost A 127.0.0.1
diff --git a/src/lib/Bcfg2/Server/Hostbase/urls.py b/src/lib/Bcfg2/Server/Hostbase/urls.py
deleted file mode 100644
index 01fe97d4f..000000000
--- a/src/lib/Bcfg2/Server/Hostbase/urls.py
+++ /dev/null
@@ -1,27 +0,0 @@
-from django.conf.urls.defaults import *
-from django.conf import settings
-from django.views.generic.simple import direct_to_template
-from django.contrib import admin
-
-
-admin.autodiscover()
-
-
-urlpatterns = patterns('',
- # Uncomment the admin/doc line below and add 'django.contrib.admindocs'
- # to INSTALLED_APPS to enable admin documentation:
- (r'^admin/doc/', include('django.contrib.admindocs.urls')),
-
- # Uncomment the next line to enable the admin:
- (r'^admin/', include(admin.site.urls)),
-
- (r'^$',direct_to_template, {'template':'index.html'}, 'index'),
- (r'^hostbase/', include('hostbase.urls')),
- (r'^login/$', 'django.contrib.auth.views.login', {'template_name': 'login.html'}),
- (r'^logout/$', 'django.contrib.auth.views.logout', {'template_name': 'logout.html'})
-)
-
-if settings.SERVE_MEDIA:
- urlpatterns += patterns('',
- (r'^site_media/(?P<path>.*)$', 'django.views.static.serve',
- dict(document_root=settings.MEDIA_ROOT)),)
diff --git a/src/lib/Bcfg2/Server/Lint/Genshi.py b/src/lib/Bcfg2/Server/Lint/Genshi.py
index 18b4ae28a..437e69d82 100755
--- a/src/lib/Bcfg2/Server/Lint/Genshi.py
+++ b/src/lib/Bcfg2/Server/Lint/Genshi.py
@@ -11,10 +11,9 @@ class Genshi(Bcfg2.Server.Lint.ServerPlugin):
def Run(self):
""" run plugin """
loader = genshi.template.TemplateLoader()
- for plugin in ['Cfg', 'TGenshi']:
- if plugin in self.core.plugins:
- self.check_files(self.core.plugins[plugin].entries,
- loader=loader)
+ if 'Cfg' in self.core.plugins:
+ self.check_files(self.core.plugins['Cfg'].entries,
+ loader=loader)
@classmethod
def Errors(cls):
diff --git a/src/lib/Bcfg2/Server/Lint/InfoXML.py b/src/lib/Bcfg2/Server/Lint/InfoXML.py
index e34f387ff..f2349f861 100644
--- a/src/lib/Bcfg2/Server/Lint/InfoXML.py
+++ b/src/lib/Bcfg2/Server/Lint/InfoXML.py
@@ -4,7 +4,6 @@ import os
import Bcfg2.Options
import Bcfg2.Server.Lint
from Bcfg2.Server.Plugins.Cfg.CfgInfoXML import CfgInfoXML
-from Bcfg2.Server.Plugins.Cfg.CfgLegacyInfo import CfgLegacyInfo
class InfoXML(Bcfg2.Server.Lint.ServerPlugin):
@@ -26,19 +25,9 @@ class InfoXML(Bcfg2.Server.Lint.ServerPlugin):
self.LintError("no-infoxml",
"No info.xml found for %s" % filename)
- for entry in entryset.entries.values():
- if isinstance(entry, CfgLegacyInfo):
- if not self.HandlesFile(entry.path):
- continue
- self.LintError("deprecated-info-file",
- "Deprecated %s file found at %s" %
- (os.path.basename(entry.name),
- entry.path))
-
@classmethod
def Errors(cls):
return {"no-infoxml": "warning",
- "deprecated-info-file": "warning",
"paranoid-false": "warning",
"broken-xinclude-chain": "warning",
"required-infoxml-attrs-missing": "error"}
diff --git a/src/lib/Bcfg2/Server/Plugin/helpers.py b/src/lib/Bcfg2/Server/Plugin/helpers.py
index b036fc31d..59796a556 100644
--- a/src/lib/Bcfg2/Server/Plugin/helpers.py
+++ b/src/lib/Bcfg2/Server/Plugin/helpers.py
@@ -11,6 +11,7 @@ import lxml.etree
import Bcfg2.Server
import Bcfg2.Options
import Bcfg2.Statistics
+import Bcfg2.Server.FileMonitor
from Bcfg2.Compat import CmpMixin, wraps
from Bcfg2.Server.Plugin.base import Debuggable, Plugin
from Bcfg2.Server.Plugin.interfaces import Generator
@@ -31,17 +32,6 @@ except ImportError:
LOGGER = logging.getLogger(__name__)
-#: a compiled regular expression for parsing info and :info files
-INFO_REGEX = re.compile('owner:(\s)*(?P<owner>\S+)|' +
- 'group:(\s)*(?P<group>\S+)|' +
- 'mode:(\s)*(?P<mode>\w+)|' +
- 'secontext:(\s)*(?P<secontext>\S+)|' +
- 'paranoid:(\s)*(?P<paranoid>\S+)|' +
- 'sensitive:(\s)*(?P<sensitive>\S+)|' +
- 'encoding:(\s)*(?P<encoding>\S+)|' +
- 'important:(\s)*(?P<important>\S+)|' +
- 'mtime:(\s)*(?P<mtime>\w+)|')
-
def default_path_metadata():
""" Get the default Path entry metadata from the config.
@@ -204,13 +194,10 @@ class FileBacked(object):
principally meant to be used as a part of
:class:`Bcfg2.Server.Plugin.helpers.DirectoryBacked`. """
- def __init__(self, name, fam=None):
+ def __init__(self, name):
"""
:param name: The full path to the file to cache and monitor
:type name: string
- :param fam: The FAM object used to receive notifications of
- changes
- :type fam: Bcfg2.Server.FileMonitor.FileMonitor
"""
object.__init__(self)
@@ -221,7 +208,7 @@ class FileBacked(object):
self.name = name
#: The FAM object used to receive notifications of changes
- self.fam = fam
+ self.fam = Bcfg2.Server.FileMonitor.get_fam()
def HandleEvent(self, event=None):
""" HandleEvent is called whenever the FAM registers an event.
@@ -274,14 +261,11 @@ class DirectoryBacked(object):
#: :attr:`patterns` or ``ignore``, then a warning will be produced.
ignore = None
- def __init__(self, data, fam):
+ def __init__(self, data):
"""
:param data: The path to the data directory that will be
monitored
:type data: string
- :param fam: The FAM object used to receive notifications of
- changes
- :type fam: Bcfg2.Server.FileMonitor.FileMonitor
.. -----
.. autoattribute:: __child__
@@ -289,7 +273,7 @@ class DirectoryBacked(object):
object.__init__(self)
self.data = os.path.normpath(data)
- self.fam = fam
+ self.fam = Bcfg2.Server.FileMonitor.get_fam()
#: self.entries contains information about the files monitored
#: by this object. The keys of the dict are the relative
@@ -343,8 +327,7 @@ class DirectoryBacked(object):
:returns: None
"""
self.entries[relative] = self.__child__(os.path.join(self.data,
- relative),
- self.fam)
+ relative))
self.entries[relative].HandleEvent(event)
def HandleEvent(self, event): # pylint: disable=R0912
@@ -465,13 +448,10 @@ class XMLFileBacked(FileBacked):
#: behavior, set ``__identifier__`` to ``None``.
__identifier__ = 'name'
- def __init__(self, filename, fam=None, should_monitor=False):
+ def __init__(self, filename, should_monitor=False):
"""
:param filename: The full path to the file to cache and monitor
:type filename: string
- :param fam: The FAM object used to receive notifications of
- changes
- :type fam: Bcfg2.Server.FileMonitor.FileMonitor
:param should_monitor: Whether or not to monitor this file for
changes. It may be useful to disable
monitoring when, for instance, the file
@@ -484,7 +464,7 @@ class XMLFileBacked(FileBacked):
.. -----
.. autoattribute:: __identifier__
"""
- FileBacked.__init__(self, filename, fam=fam)
+ FileBacked.__init__(self, filename)
#: The raw XML data contained in the file as an
#: :class:`lxml.etree.ElementTree` object, with XIncludes
@@ -505,7 +485,7 @@ class XMLFileBacked(FileBacked):
#: Whether or not to monitor this file for changes.
self.should_monitor = should_monitor
- if fam and should_monitor:
+ if should_monitor:
self.fam.AddMonitor(filename, self)
def _follow_xincludes(self, fname=None, xdata=None):
@@ -564,7 +544,7 @@ class XMLFileBacked(FileBacked):
:returns: None
"""
self.extras.append(fpath)
- if self.fam and self.should_monitor:
+ if self.should_monitor:
self.fam.AddMonitor(fpath, self)
def __iter__(self):
@@ -591,9 +571,8 @@ class StructFile(XMLFileBacked):
#: Whether or not encryption support is enabled in this file
encryption = True
- def __init__(self, filename, fam=None, should_monitor=False):
- XMLFileBacked.__init__(self, filename, fam=fam,
- should_monitor=should_monitor)
+ def __init__(self, filename, should_monitor=False):
+ XMLFileBacked.__init__(self, filename, should_monitor=should_monitor)
self.setup = Bcfg2.Options.get_option_parser()
def Index(self):
@@ -826,8 +805,8 @@ class XMLSrc(XMLFileBacked):
__cacheobj__ = dict
__priority_required__ = True
- def __init__(self, filename, fam=None, should_monitor=False):
- XMLFileBacked.__init__(self, filename, fam, should_monitor)
+ def __init__(self, filename, should_monitor=False):
+ XMLFileBacked.__init__(self, filename, should_monitor)
self.items = {}
self.cache = None
self.pnode = None
@@ -916,7 +895,7 @@ class PrioDir(Plugin, Generator, XMLDirectoryBacked):
def __init__(self, core, datastore):
Plugin.__init__(self, core, datastore)
Generator.__init__(self)
- XMLDirectoryBacked.__init__(self, self.data, self.core.fam)
+ XMLDirectoryBacked.__init__(self, self.data)
__init__.__doc__ = Plugin.__init__.__doc__
def HandleEvent(self, event):
@@ -1293,7 +1272,7 @@ class EntrySet(Debuggable):
"""
action = event.code2str()
- if event.filename in ['info', 'info.xml', ':info']:
+ if event.filename == 'info.xml':
if action in ['exists', 'created', 'changed']:
self.update_metadata(event)
elif action == 'deleted':
@@ -1398,8 +1377,8 @@ class EntrySet(Debuggable):
return Specificity(**kwargs)
def update_metadata(self, event):
- """ Process changes to or creation of info, :info, and
- info.xml files for the EntrySet.
+ """ Process changes to or creation of info.xml files for the
+ EntrySet.
:param event: An event that applies to an info handled by this
EntrySet
@@ -1411,24 +1390,9 @@ class EntrySet(Debuggable):
if not self.infoxml:
self.infoxml = InfoXML(fpath)
self.infoxml.HandleEvent(event)
- elif event.filename in [':info', 'info']:
- for line in open(fpath).readlines():
- match = INFO_REGEX.match(line)
- if not match:
- LOGGER.warning("Failed to match line in %s: %s" % (fpath,
- line))
- continue
- else:
- mgd = match.groupdict()
- for key, value in list(mgd.items()):
- if value:
- self.metadata[key] = value
- if len(self.metadata['mode']) == 3:
- self.metadata['mode'] = "0%s" % self.metadata['mode']
def reset_metadata(self, event):
- """ Reset metadata to defaults if info. :info, or info.xml are
- removed.
+ """ Reset metadata to defaults if info.xml is removed.
:param event: An event that applies to an info handled by this
EntrySet
@@ -1437,8 +1401,6 @@ class EntrySet(Debuggable):
"""
if event.filename == 'info.xml':
self.infoxml = None
- elif event.filename in [':info', 'info']:
- self.metadata = default_path_metadata()
def bind_info_to_entry(self, entry, metadata):
""" Shortcut to call :func:`bind_info` with the base
@@ -1503,6 +1465,8 @@ class GroupSpool(Plugin, Generator):
if self.data[-1] == '/':
self.data = self.data[:-1]
+ self.fam = Bcfg2.Server.FileMonitor.get_fam()
+
#: See :class:`Bcfg2.Server.Plugins.interfaces.Generator` for
#: details on the Entries attribute.
self.Entries[self.entry_type] = {}
@@ -1649,5 +1613,5 @@ class GroupSpool(Plugin, Generator):
if not os.path.isdir(name):
self.logger.error("Failed to open directory %s" % name)
return
- reqid = self.core.fam.AddMonitor(name, self)
+ reqid = self.fam.AddMonitor(name, self)
self.handles[reqid] = relative
diff --git a/src/lib/Bcfg2/Server/Plugins/Account.py b/src/lib/Bcfg2/Server/Plugins/Account.py
deleted file mode 100644
index fd49d3655..000000000
--- a/src/lib/Bcfg2/Server/Plugins/Account.py
+++ /dev/null
@@ -1,102 +0,0 @@
-"""This handles authentication setup."""
-
-import Bcfg2.Server.Plugin
-
-
-class Account(Bcfg2.Server.Plugin.Plugin,
- Bcfg2.Server.Plugin.Generator):
- """This module generates account config files,
- based on an internal data repo:
- static.(passwd|group|limits.conf) -> static entries
- dyn.(passwd|group) -> dynamic entries (usually acquired from yp or somesuch)
- useraccess -> users to be granted login access on some hosts
- superusers -> users to be granted root privs on all hosts
- rootlike -> users to be granted root privs on some hosts
-
- """
- name = 'Account'
- __author__ = 'bcfg-dev@mcs.anl.gov'
- deprecated = True
-
- def __init__(self, core, datastore):
- Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore)
- Bcfg2.Server.Plugin.Generator.__init__(self)
- self.Entries = {'ConfigFile': {'/etc/passwd': self.from_yp_cb,
- '/etc/group': self.from_yp_cb,
- '/etc/security/limits.conf': self.gen_limits_cb,
- '/root/.ssh/authorized_keys': self.gen_root_keys_cb,
- '/etc/sudoers': self.gen_sudoers}}
- try:
- self.repository = Bcfg2.Server.Plugin.DirectoryBacked(self.data,
- self.core.fam)
- except:
- self.logger.error("Failed to load repos: %s, %s" % \
- (self.data, "%s/ssh" % (self.data)))
- raise Bcfg2.Server.Plugin.PluginInitError
-
- def from_yp_cb(self, entry, metadata):
- """Build password file from cached yp data."""
- fname = entry.attrib['name'].split('/')[-1]
- entry.text = self.repository.entries["static.%s" % (fname)].data
- entry.text += self.repository.entries["dyn.%s" % (fname)].data
- perms = {'owner': 'root',
- 'group': 'root',
- 'mode': '0644'}
- [entry.attrib.__setitem__(key, value) for (key, value) in \
- list(perms.items())]
-
- def gen_limits_cb(self, entry, metadata):
- """Build limits entries based on current ACLs."""
- entry.text = self.repository.entries["static.limits.conf"].data
- superusers = self.repository.entries["superusers"].data.split()
- useraccess = [line.split(':') for line in \
- self.repository.entries["useraccess"].data.split()]
- users = [user for (user, host) in \
- useraccess if host == metadata.hostname.split('.')[0]]
- perms = {'owner': 'root',
- 'group': 'root',
- 'mode': '0600'}
- [entry.attrib.__setitem__(key, value) for (key, value) in \
- list(perms.items())]
- entry.text += "".join(["%s hard maxlogins 1024\n" % uname for uname in superusers + users])
- if "*" not in users:
- entry.text += "* hard maxlogins 0\n"
-
- def gen_root_keys_cb(self, entry, metadata):
- """Build root authorized keys file based on current ACLs."""
- superusers = self.repository.entries['superusers'].data.split()
- try:
- rootlike = [line.split(':', 1) for line in \
- self.repository.entries['rootlike'].data.split()]
- superusers += [user for (user, host) in rootlike \
- if host == metadata.hostname.split('.')[0]]
- except:
- pass
- rdata = self.repository.entries
- entry.text = "".join([rdata["%s.key" % user].data for user \
- in superusers if \
- ("%s.key" % user) in rdata])
- perms = {'owner': 'root',
- 'group': 'root',
- 'mode': '0600'}
- [entry.attrib.__setitem__(key, value) for (key, value) \
- in list(perms.items())]
-
- def gen_sudoers(self, entry, metadata):
- """Build root authorized keys file based on current ACLs."""
- superusers = self.repository.entries['superusers'].data.split()
- try:
- rootlike = [line.split(':', 1) for line in \
- self.repository.entries['rootlike'].data.split()]
- superusers += [user for (user, host) in rootlike \
- if host == metadata.hostname.split('.')[0]]
- except:
- pass
- entry.text = self.repository.entries['static.sudoers'].data
- entry.text += "".join(["%s ALL=(ALL) ALL\n" % uname \
- for uname in superusers])
- perms = {'owner': 'root',
- 'group': 'root',
- 'mode': '0440'}
- [entry.attrib.__setitem__(key, value) for (key, value) \
- in list(perms.items())]
diff --git a/src/lib/Bcfg2/Server/Plugins/Base.py b/src/lib/Bcfg2/Server/Plugins/Base.py
index d662da60a..db003f729 100644
--- a/src/lib/Bcfg2/Server/Plugins/Base.py
+++ b/src/lib/Bcfg2/Server/Plugins/Base.py
@@ -21,9 +21,7 @@ class Base(Bcfg2.Server.Plugin.Plugin,
Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore)
Bcfg2.Server.Plugin.Structure.__init__(self)
try:
- Bcfg2.Server.Plugin.XMLDirectoryBacked.__init__(self,
- self.data,
- self.core.fam)
+ Bcfg2.Server.Plugin.XMLDirectoryBacked.__init__(self, self.data)
except OSError:
self.logger.error("Failed to load Base repository")
raise Bcfg2.Server.Plugin.PluginInitError
diff --git a/src/lib/Bcfg2/Server/Plugins/Bundler.py b/src/lib/Bcfg2/Server/Plugins/Bundler.py
index 6dc3c2b1d..fa993cd85 100644
--- a/src/lib/Bcfg2/Server/Plugins/Bundler.py
+++ b/src/lib/Bcfg2/Server/Plugins/Bundler.py
@@ -12,13 +12,29 @@ import Bcfg2.Server.Lint
from Bcfg2.Options import get_option_parser
try:
- import genshi.template.base
- import Bcfg2.Server.Plugins.TGenshi
+ import genshi.core
+ import genshi.input
+ from genshi.template import TemplateLoader, MarkupTemplate, TemplateError
HAS_GENSHI = True
except ImportError:
HAS_GENSHI = False
+def removecomment(stream):
+ """ A Genshi filter that removes comments from the stream. This
+ function is a generator.
+
+ :param stream: The Genshi stream to remove comments from
+ :type stream: genshi.core.Stream
+ :returns: tuple of ``(kind, data, pos)``, as when iterating
+ through a Genshi stream
+ """
+ for kind, data, pos in stream:
+ if kind is genshi.core.COMMENT:
+ continue
+ yield kind, data, pos
+
+
class BundleFile(Bcfg2.Server.Plugin.StructFile):
""" Representation of a bundle XML file """
def get_xml_value(self, metadata):
@@ -31,16 +47,35 @@ class BundleFile(Bcfg2.Server.Plugin.StructFile):
if HAS_GENSHI:
- class BundleTemplateFile(Bcfg2.Server.Plugins.TGenshi.TemplateFile,
- Bcfg2.Server.Plugin.StructFile):
+ class BundleTemplateFile(Bcfg2.Server.Plugin.StructFile):
""" Representation of a Genshi-templated bundle XML file """
- def __init__(self, name, specific, encoding):
- Bcfg2.Server.Plugins.TGenshi.TemplateFile.__init__(self, name,
- specific,
- encoding)
+ def __init__(self, name, encoding):
Bcfg2.Server.Plugin.StructFile.__init__(self, name)
+ self.encoding = encoding
self.logger = logging.getLogger(name)
+ self.template = None
+
+ def HandleEvent(self, event=None):
+ """Handle all fs events for this template."""
+ if event and event.code2str() == 'deleted':
+ return
+ try:
+ loader = TemplateLoader()
+ self.template = loader.load(self.name, cls=MarkupTemplate,
+ encoding=self.encoding)
+ except LookupError:
+ err = sys.exc_info()[1]
+ self.logger.error('Genshi lookup error in %s: %s' %
+ (self.name, err))
+ except TemplateError:
+ err = sys.exc_info()[1]
+ self.logger.error('Genshi template error in %s: %s' %
+ (self.name, err))
+ except genshi.input.ParseError:
+ err = sys.exc_info()[1]
+ self.logger.error('Genshi parse error in %s: %s' %
+ (self.name, err))
def get_xml_value(self, metadata):
""" get the rendered XML data that applies to the given
@@ -51,8 +86,7 @@ if HAS_GENSHI:
raise Bcfg2.Server.Plugin.PluginExecutionError(msg)
stream = self.template.generate(
metadata=metadata,
- repo=get_option_parser()['repo']).filter(
- Bcfg2.Server.Plugins.TGenshi.removecomment)
+ repo=get_option_parser()['repo']).filter(removecomment)
data = lxml.etree.XML(stream.render('xml',
strip_whitespace=False),
parser=Bcfg2.Server.XMLParser)
@@ -71,11 +105,6 @@ if HAS_GENSHI:
len(rv)))
return rv
- class SGenshiTemplateFile(BundleTemplateFile):
- """ provided for backwards compat with the deprecated SGenshi
- plugin """
- pass
-
class Bundler(Bcfg2.Server.Plugin.Plugin,
Bcfg2.Server.Plugin.Structure,
@@ -91,9 +120,7 @@ class Bundler(Bcfg2.Server.Plugin.Plugin,
self.encoding = core.setup['encoding']
self.__child__ = self.template_dispatch
try:
- Bcfg2.Server.Plugin.XMLDirectoryBacked.__init__(self,
- self.data,
- self.core.fam)
+ Bcfg2.Server.Plugin.XMLDirectoryBacked.__init__(self, self.data)
except OSError:
err = sys.exc_info()[1]
msg = "Failed to load Bundle repository %s: %s" % (self.data, err)
@@ -111,14 +138,13 @@ class Bundler(Bcfg2.Server.Plugin.Plugin,
('py' in nsmap and
nsmap['py'] == 'http://genshi.edgewall.org/')):
if HAS_GENSHI:
- spec = Bcfg2.Server.Plugin.Specificity()
- return BundleTemplateFile(name, spec, self.encoding)
+ return BundleTemplateFile(name, self.encoding)
else:
raise Bcfg2.Server.Plugin.PluginExecutionError("Genshi not "
"available: %s"
% name)
else:
- return BundleFile(name, self.fam)
+ return BundleFile(name)
def BuildStructures(self, metadata):
"""Build all structures for client (metadata)."""
@@ -139,7 +165,7 @@ class Bundler(Bcfg2.Server.Plugin.Plugin,
continue
try:
bundleset.append(entries[0].get_xml_value(metadata))
- except genshi.template.base.TemplateError:
+ except TemplateError:
err = sys.exc_info()[1]
self.logger.error("Bundler: Failed to render templated bundle "
"%s: %s" % (bundlename, err))
diff --git a/src/lib/Bcfg2/Server/Plugins/Cfg/CfgCatFilter.py b/src/lib/Bcfg2/Server/Plugins/Cfg/CfgCatFilter.py
deleted file mode 100644
index 49a5a85b3..000000000
--- a/src/lib/Bcfg2/Server/Plugins/Cfg/CfgCatFilter.py
+++ /dev/null
@@ -1,28 +0,0 @@
-""" Handle .cat files, which append lines to and remove lines from
-plaintext files """
-
-from Bcfg2.Server.Plugins.Cfg import CfgFilter
-
-
-class CfgCatFilter(CfgFilter):
- """ CfgCatFilter appends lines to and remove lines from plaintext
- :ref:`server-plugins-generators-Cfg` files"""
-
- #: Handle .cat files
- __extensions__ = ['cat']
-
- #: .cat files are deprecated
- deprecated = True
-
- def modify_data(self, entry, metadata, data):
- datalines = data.strip().split('\n')
- for line in self.data.split('\n'):
- if not line:
- continue
- if line.startswith('+'):
- datalines.append(line[1:])
- elif line.startswith('-'):
- if line[1:] in datalines:
- datalines.remove(line[1:])
- return "\n".join(datalines) + "\n"
- modify_data.__doc__ = CfgFilter.modify_data.__doc__
diff --git a/src/lib/Bcfg2/Server/Plugins/Cfg/CfgDiffFilter.py b/src/lib/Bcfg2/Server/Plugins/Cfg/CfgDiffFilter.py
deleted file mode 100644
index da506a195..000000000
--- a/src/lib/Bcfg2/Server/Plugins/Cfg/CfgDiffFilter.py
+++ /dev/null
@@ -1,35 +0,0 @@
-""" Handle .diff files, which apply diffs to plaintext files """
-
-import os
-import tempfile
-from Bcfg2.Server.Plugin import PluginExecutionError
-from subprocess import Popen, PIPE
-from Bcfg2.Server.Plugins.Cfg import CfgFilter
-
-
-class CfgDiffFilter(CfgFilter):
- """ CfgDiffFilter applies diffs to plaintext
- :ref:`server-plugins-generators-Cfg` files """
-
- #: Handle .diff files
- __extensions__ = ['diff']
-
- #: .diff files are deprecated
- deprecated = True
-
- def modify_data(self, entry, metadata, data):
- basehandle, basename = tempfile.mkstemp()
- open(basename, 'w').write(data)
- os.close(basehandle)
-
- cmd = ["patch", "-u", "-f", basename]
- patch = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE)
- stderr = patch.communicate(input=self.data)[1]
- ret = patch.wait()
- output = open(basename, 'r').read()
- os.unlink(basename)
- if ret != 0:
- raise PluginExecutionError("Error applying diff %s: %s" %
- (self.name, stderr))
- return output
- modify_data.__doc__ = CfgFilter.modify_data.__doc__
diff --git a/src/lib/Bcfg2/Server/Plugins/Cfg/CfgLegacyInfo.py b/src/lib/Bcfg2/Server/Plugins/Cfg/CfgLegacyInfo.py
deleted file mode 100644
index 5122d9aa1..000000000
--- a/src/lib/Bcfg2/Server/Plugins/Cfg/CfgLegacyInfo.py
+++ /dev/null
@@ -1,46 +0,0 @@
-""" Handle info and :info files """
-
-import Bcfg2.Server.Plugin
-from Bcfg2.Server.Plugins.Cfg import CfgInfo
-
-
-class CfgLegacyInfo(CfgInfo):
- """ CfgLegacyInfo handles :file:`info` and :file:`:info` files for
- :ref:`server-plugins-generators-cfg` """
-
- #: Handle :file:`info` and :file:`:info`
- __basenames__ = ['info', ':info']
-
- #: CfgLegacyInfo is deprecated. Use
- #: :class:`Bcfg2.Server.Plugins.Cfg.CfgInfoXML.CfgInfoXML` instead.
- deprecated = True
-
- def __init__(self, path):
- CfgInfo.__init__(self, path)
- self.path = path
-
- #: The set of info metadata stored in the file
- self.metadata = None
- __init__.__doc__ = CfgInfo.__init__.__doc__
-
- def bind_info_to_entry(self, entry, metadata):
- self._set_info(entry, self.metadata)
- bind_info_to_entry.__doc__ = CfgInfo.bind_info_to_entry.__doc__
-
- def handle_event(self, event):
- if event.code2str() == 'deleted':
- return
- self.metadata = dict()
- for line in open(self.path).readlines():
- match = Bcfg2.Server.Plugin.INFO_REGEX.match(line)
- if not match:
- self.logger.warning("Failed to parse line in %s: %s" %
- (event.filename, line))
- continue
- else:
- for key, value in list(match.groupdict().items()):
- if value:
- self.metadata[key] = value
- if ('mode' in self.metadata and len(self.metadata['mode']) == 3):
- self.metadata['mode'] = "0%s" % self.metadata['mode']
- handle_event.__doc__ = CfgInfo.handle_event.__doc__
diff --git a/src/lib/Bcfg2/Server/Plugins/Cfg/__init__.py b/src/lib/Bcfg2/Server/Plugins/Cfg/__init__.py
index 53cc90094..0d8116c23 100644
--- a/src/lib/Bcfg2/Server/Plugins/Cfg/__init__.py
+++ b/src/lib/Bcfg2/Server/Plugins/Cfg/__init__.py
@@ -693,13 +693,6 @@ class CfgEntrySet(Bcfg2.Server.Plugin.EntrySet,
# raises an appropriate exception
return self._create_data(entry, metadata)
- if entry.get('mode').lower() == 'inherit':
- # use on-disk permissions
- self.logger.warning("Cfg: %s: Use of mode='inherit' is deprecated"
- % entry.get("name"))
- fname = os.path.join(self.path, generator.name)
- entry.set('mode',
- oct_mode(stat.S_IMODE(os.stat(fname).st_mode)))
try:
return generator.get_data(entry, metadata)
except:
@@ -788,13 +781,6 @@ class CfgEntrySet(Bcfg2.Server.Plugin.EntrySet,
badattr = [attr for attr in ['owner', 'group', 'mode']
if attr in new_entry]
if badattr:
- # check for info files and inform user of their removal
- for ifile in ['info', ':info']:
- info = os.path.join(self.path, ifile)
- if os.path.exists(info):
- self.logger.info("Removing %s and replacing with info.xml"
- % info)
- os.remove(info)
metadata_updates = {}
metadata_updates.update(self.metadata)
for attr in badattr:
@@ -874,26 +860,11 @@ class CfgLint(Bcfg2.Server.Lint.ServerPlugin):
def Run(self):
for basename, entry in list(self.core.plugins['Cfg'].entries.items()):
- self.check_delta(basename, entry)
self.check_pubkey(basename, entry)
@classmethod
def Errors(cls):
- return {"cat-file-used": "warning",
- "diff-file-used": "warning",
- "no-pubkey-xml": "warning"}
-
- def check_delta(self, basename, entry):
- """ check that no .cat or .diff files are in use """
- for fname, handler in entry.entries.items():
- path = handler.name
- if self.HandlesFile(path) and isinstance(handler, CfgFilter):
- extension = fname.split(".")[-1]
- if extension in ["cat", "diff"]:
- self.LintError("%s-file-used" % extension,
- "%s file used on %s: %s" % (extension,
- basename,
- fname))
+ return {"no-pubkey-xml": "warning"}
def check_pubkey(self, basename, entry):
""" check that privkey.xml files have corresponding pubkey.xml
diff --git a/src/lib/Bcfg2/Server/Plugins/Decisions.py b/src/lib/Bcfg2/Server/Plugins/Decisions.py
index 5521ea045..a7ef25a84 100644
--- a/src/lib/Bcfg2/Server/Plugins/Decisions.py
+++ b/src/lib/Bcfg2/Server/Plugins/Decisions.py
@@ -5,6 +5,7 @@ import os
import sys
import lxml.etree
import Bcfg2.Server.Plugin
+import Bcfg2.Server.FileMonitor
class DecisionFile(Bcfg2.Server.Plugin.SpecificData):
@@ -46,7 +47,7 @@ class Decisions(Bcfg2.Server.Plugin.EntrySet,
DecisionFile,
core.setup['encoding'])
try:
- core.fam.AddMonitor(self.data, self)
+ Bcfg2.Server.FileMonitor.get_fam().AddMonitor(self.data, self)
except OSError:
err = sys.exc_info()[1]
msg = 'Adding filemonitor for %s failed: %s' % (self.data, err)
diff --git a/src/lib/Bcfg2/Server/Plugins/Editor.py b/src/lib/Bcfg2/Server/Plugins/Editor.py
deleted file mode 100644
index f82e0f1dd..000000000
--- a/src/lib/Bcfg2/Server/Plugins/Editor.py
+++ /dev/null
@@ -1,80 +0,0 @@
-import Bcfg2.Server.Plugin
-import re
-import lxml.etree
-
-
-def linesub(pattern, repl, filestring):
- """Substitutes instances of pattern with repl in filestring."""
- if filestring == None:
- filestring = ''
- output = list()
- fileread = filestring.split('\n')
- for line in fileread:
- output.append(re.sub(pattern, repl, filestring))
- return '\n'.join(output)
-
-
-class EditDirectives(Bcfg2.Server.Plugin.SpecificData):
- """This object handles the editing directives."""
- def ProcessDirectives(self, input):
- """Processes a list of edit directives on input."""
- temp = input
- for directive in self.data.split('\n'):
- directive = directive.split(',')
- temp = linesub(directive[0], directive[1], temp)
- return temp
-
-
-class EditEntrySet(Bcfg2.Server.Plugin.EntrySet):
- def __init__(self, basename, path, entry_type, encoding):
- self.ignore = re.compile("^(\.#.*|.*~|\\..*\\.(tmp|sw[px])|%s\.H_.*)$" % path.split('/')[-1])
- Bcfg2.Server.Plugin.EntrySet.__init__(self,
- basename,
- path,
- entry_type,
- encoding)
- self.inputs = dict()
-
- def bind_entry(self, entry, metadata):
- client = metadata.hostname
- filename = entry.get('name')
- permdata = {'owner': 'root',
- 'group': 'root',
- 'mode': '0644'}
- [entry.attrib.__setitem__(key, permdata[key]) for key in permdata]
- entry.text = self.entries['edits'].ProcessDirectives(self.get_client_data(client))
- if not entry.text:
- entry.set('empty', 'true')
- try:
- f = open('%s/%s.H_%s' % (self.path, filename.split('/')[-1], client), 'w')
- f.write(entry.text)
- f.close()
- except:
- pass
-
- def get_client_data(self, client):
- return self.inputs[client]
-
-
-class Editor(Bcfg2.Server.Plugin.GroupSpool,
- Bcfg2.Server.Plugin.Probing):
- name = 'Editor'
- __author__ = 'bcfg2-dev@mcs.anl.gov'
- filename_pattern = 'edits'
- es_child_cls = EditDirectives
- es_cls = EditEntrySet
-
- def GetProbes(self, _):
- '''Return a set of probes for execution on client'''
- probelist = list()
- for name in list(self.entries.keys()):
- probe = lxml.etree.Element('probe')
- probe.set('name', name)
- probe.set('source', "Editor")
- probe.text = "cat %s" % name
- probelist.append(probe)
- return probelist
-
- def ReceiveData(self, client, datalist):
- for data in datalist:
- self.entries[data.get('name')].inputs[client.hostname] = data.text
diff --git a/src/lib/Bcfg2/Server/Plugins/FileProbes.py b/src/lib/Bcfg2/Server/Plugins/FileProbes.py
index 365549e85..461b718e2 100644
--- a/src/lib/Bcfg2/Server/Plugins/FileProbes.py
+++ b/src/lib/Bcfg2/Server/Plugins/FileProbes.py
@@ -11,6 +11,7 @@ import lxml.etree
import Bcfg2.Options
import Bcfg2.Server
import Bcfg2.Server.Plugin
+import Bcfg2.Server.FileMonitor
from Bcfg2.Compat import b64decode
#: The probe we send to clients to get the file data. Returns an XML
@@ -69,7 +70,6 @@ class FileProbes(Bcfg2.Server.Plugin.Plugin,
Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore)
Bcfg2.Server.Plugin.Probing.__init__(self)
self.config = FileProbesConfig(os.path.join(self.data, 'config.xml'),
- fam=core.fam,
should_monitor=True)
self.entries = dict()
self.probes = dict()
@@ -196,7 +196,7 @@ class FileProbes(Bcfg2.Server.Plugin.Plugin,
if tries >= 10:
self.logger.error("%s still not registered" % filename)
return
- self.core.fam.handle_events_in_interval(1)
+ Bcfg2.Server.FileMonitor.get_fam().handle_events_in_interval(1)
try:
cfg.entries[filename].bind_entry(entry, metadata)
except Bcfg2.Server.Plugin.PluginExecutionError:
diff --git a/src/lib/Bcfg2/Server/Plugins/GroupPatterns.py b/src/lib/Bcfg2/Server/Plugins/GroupPatterns.py
index 1b12e590a..42d860b89 100644
--- a/src/lib/Bcfg2/Server/Plugins/GroupPatterns.py
+++ b/src/lib/Bcfg2/Server/Plugins/GroupPatterns.py
@@ -90,11 +90,7 @@ class PatternFile(Bcfg2.Server.Plugin.XMLFileBacked):
__identifier__ = None
def __init__(self, filename, core=None):
- try:
- fam = core.fam
- except AttributeError:
- fam = None
- Bcfg2.Server.Plugin.XMLFileBacked.__init__(self, filename, fam=fam,
+ Bcfg2.Server.Plugin.XMLFileBacked.__init__(self, filename,
should_monitor=True)
self.core = core
self.patterns = []
diff --git a/src/lib/Bcfg2/Server/Plugins/Hostbase.py b/src/lib/Bcfg2/Server/Plugins/Hostbase.py
deleted file mode 100644
index 55757e0b4..000000000
--- a/src/lib/Bcfg2/Server/Plugins/Hostbase.py
+++ /dev/null
@@ -1,599 +0,0 @@
-"""
-This file provides the Hostbase plugin.
-It manages dns/dhcp/nis host information
-"""
-
-from lxml.etree import Element, SubElement
-import os
-import re
-from time import strftime
-os.environ['DJANGO_SETTINGS_MODULE'] = 'Bcfg2.Server.Hostbase.settings'
-import Bcfg2.Server.Plugin
-from Bcfg2.Server.Plugin import PluginExecutionError, PluginInitError
-from django.template import Context, loader
-from django.db import connection
-# Compatibility imports
-from Bcfg2.Compat import StringIO
-
-try:
- set
-except NameError:
- # deprecated since python 2.6
- from sets import Set as set
-
-
-class Hostbase(Bcfg2.Server.Plugin.Plugin,
- Bcfg2.Server.Plugin.Structure,
- Bcfg2.Server.Plugin.Generator):
- """The Hostbase plugin handles host/network info."""
- name = 'Hostbase'
- __author__ = 'bcfg-dev@mcs.anl.gov'
- filepath = '/my/adm/hostbase/files/bind'
- deprecated = True
-
- def __init__(self, core, datastore):
-
- self.ready = False
- Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore)
- Bcfg2.Server.Plugin.Structure.__init__(self)
- Bcfg2.Server.Plugin.Generator.__init__(self)
- files = ['zone.tmpl',
- 'reversesoa.tmpl',
- 'named.tmpl',
- 'reverseappend.tmpl',
- 'dhcpd.tmpl',
- 'hosts.tmpl',
- 'hostsappend.tmpl']
- self.filedata = {}
- self.dnsservers = []
- self.dhcpservers = []
- self.templates = {'zone': loader.get_template('zone.tmpl'),
- 'reversesoa': loader.get_template('reversesoa.tmpl'),
- 'named': loader.get_template('named.tmpl'),
- 'namedviews': loader.get_template('namedviews.tmpl'),
- 'reverseapp': loader.get_template('reverseappend.tmpl'),
- 'dhcp': loader.get_template('dhcpd.tmpl'),
- 'hosts': loader.get_template('hosts.tmpl'),
- 'hostsapp': loader.get_template('hostsappend.tmpl'),
- }
- self.Entries['ConfigFile'] = {}
- self.__rmi__ = ['rebuildState']
- try:
- self.rebuildState(None)
- except:
- raise PluginInitError
-
- def FetchFile(self, entry, metadata):
- """Return prebuilt file data."""
- fname = entry.get('name').split('/')[-1]
- if not fname in self.filedata:
- raise PluginExecutionError
- perms = {'owner': 'root',
- 'group': 'root',
- 'mode': '644'}
- [entry.attrib.__setitem__(key, value)
- for (key, value) in list(perms.items())]
- entry.text = self.filedata[fname]
-
- def BuildStructures(self, metadata):
- """Build hostbase bundle."""
- if metadata.hostname not in self.dnsservers or metadata.hostname not in self.dhcpservers:
- return []
- output = Element("Bundle", name='hostbase')
- if metadata.hostname in self.dnsservers:
- for configfile in self.Entries['ConfigFile']:
- if re.search('/etc/bind/', configfile):
- SubElement(output, "ConfigFile", name=configfile)
- if metadata.hostname in self.dhcpservers:
- SubElement(output, "ConfigFile", name="/etc/dhcp3/dhcpd.conf")
- return [output]
-
- def rebuildState(self, _):
- """Pre-cache all state information for hostbase config files
- callable as an XMLRPC function.
-
- """
- self.buildZones()
- self.buildDHCP()
- self.buildHosts()
- self.buildHostsLPD()
- self.buildPrinters()
- self.buildNetgroups()
- return True
-
- def buildZones(self):
- """Pre-build and stash zone files."""
- cursor = connection.cursor()
-
- cursor.execute("SELECT id, serial FROM hostbase_zone")
- zones = cursor.fetchall()
-
- for zone in zones:
- # update the serial number for all zone files
- todaydate = (strftime('%Y%m%d'))
- try:
- if todaydate == str(zone[1])[:8]:
- serial = zone[1] + 1
- else:
- serial = int(todaydate) * 100
- except (KeyError):
- serial = int(todaydate) * 100
- cursor.execute("""UPDATE hostbase_zone SET serial = \'%s\' WHERE id = \'%s\'""" % (str(serial), zone[0]))
-
- cursor.execute("SELECT * FROM hostbase_zone WHERE zone NOT LIKE \'%%.rev\'")
- zones = cursor.fetchall()
-
- iplist = []
- hosts = {}
-
- for zone in zones:
- zonefile = StringIO()
- externalzonefile = StringIO()
- cursor.execute("""SELECT n.name FROM hostbase_zone_nameservers z
- INNER JOIN hostbase_nameserver n ON z.nameserver_id = n.id
- WHERE z.zone_id = \'%s\'""" % zone[0])
- nameservers = cursor.fetchall()
- cursor.execute("""SELECT i.ip_addr FROM hostbase_zone_addresses z
- INNER JOIN hostbase_zoneaddress i ON z.zoneaddress_id = i.id
- WHERE z.zone_id = \'%s\'""" % zone[0])
- addresses = cursor.fetchall()
- cursor.execute("""SELECT m.priority, m.mx FROM hostbase_zone_mxs z
- INNER JOIN hostbase_mx m ON z.mx_id = m.id
- WHERE z.zone_id = \'%s\'""" % zone[0])
- mxs = cursor.fetchall()
- context = Context({
- 'zone': zone,
- 'nameservers': nameservers,
- 'addresses': addresses,
- 'mxs': mxs
- })
- zonefile.write(self.templates['zone'].render(context))
- externalzonefile.write(self.templates['zone'].render(context))
-
- querystring = """SELECT h.hostname, p.ip_addr,
- n.name, c.cname, m.priority, m.mx, n.dns_view
- 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 n.id = x.name_id)
- INNER JOIN hostbase_mx m ON m.id = x.mx_id)
- LEFT JOIN hostbase_cname c ON n.id = c.name_id
- WHERE n.name LIKE '%%%%%s'
- AND h.status = 'active'
- ORDER BY h.hostname, n.name, p.ip_addr
- """ % zone[1]
- cursor.execute(querystring)
- zonehosts = cursor.fetchall()
- prevhost = (None, None, None, None)
- cnames = StringIO()
- cnamesexternal = StringIO()
- for host in zonehosts:
- if not host[2].split(".", 1)[1] == zone[1]:
- zonefile.write(cnames.getvalue())
- externalzonefile.write(cnamesexternal.getvalue())
- cnames = StringIO()
- cnamesexternal = StringIO()
- continue
- if not prevhost[1] == host[1] or not prevhost[2] == host[2]:
- zonefile.write(cnames.getvalue())
- externalzonefile.write(cnamesexternal.getvalue())
- cnames = StringIO()
- cnamesexternal = StringIO()
- zonefile.write("%-32s%-10s%-32s\n" %
- (host[2].split(".", 1)[0], 'A', host[1]))
- zonefile.write("%-32s%-10s%-3s%s.\n" %
- ('', 'MX', host[4], host[5]))
- if host[6] == 'global':
- externalzonefile.write("%-32s%-10s%-32s\n" %
- (host[2].split(".", 1)[0], 'A', host[1]))
- externalzonefile.write("%-32s%-10s%-3s%s.\n" %
- ('', 'MX', host[4], host[5]))
- elif not prevhost[5] == host[5]:
- zonefile.write("%-32s%-10s%-3s%s.\n" %
- ('', 'MX', host[4], host[5]))
- if host[6] == 'global':
- externalzonefile.write("%-32s%-10s%-3s%s.\n" %
- ('', 'MX', host[4], host[5]))
-
- if host[3]:
- try:
- if host[3].split(".", 1)[1] == zone[1]:
- cnames.write("%-32s%-10s%-32s\n" %
- (host[3].split(".", 1)[0],
- 'CNAME', host[2].split(".", 1)[0]))
- if host[6] == 'global':
- cnamesexternal.write("%-32s%-10s%-32s\n" %
- (host[3].split(".", 1)[0],
- 'CNAME', host[2].split(".", 1)[0]))
- else:
- cnames.write("%-32s%-10s%-32s\n" %
- (host[3] + ".",
- 'CNAME',
- host[2].split(".", 1)[0]))
- if host[6] == 'global':
- cnamesexternal.write("%-32s%-10s%-32s\n" %
- (host[3] + ".",
- 'CNAME',
- host[2].split(".", 1)[0]))
-
- except:
- pass
- prevhost = host
- zonefile.write(cnames.getvalue())
- externalzonefile.write(cnamesexternal.getvalue())
- zonefile.write("\n\n%s" % zone[9])
- externalzonefile.write("\n\n%s" % zone[9])
- self.filedata[zone[1]] = zonefile.getvalue()
- self.filedata[zone[1] + ".external"] = externalzonefile.getvalue()
- zonefile.close()
- externalzonefile.close()
- self.Entries['ConfigFile']["%s/%s" % (self.filepath, zone[1])] = self.FetchFile
- self.Entries['ConfigFile']["%s/%s.external" % (self.filepath, zone[1])] = self.FetchFile
-
- cursor.execute("SELECT * FROM hostbase_zone WHERE zone LIKE \'%%.rev\' AND zone <> \'.rev\'")
- reversezones = cursor.fetchall()
-
- reversenames = []
- for reversezone in reversezones:
- cursor.execute("""SELECT n.name FROM hostbase_zone_nameservers z
- INNER JOIN hostbase_nameserver n ON z.nameserver_id = n.id
- WHERE z.zone_id = \'%s\'""" % reversezone[0])
- reverse_nameservers = cursor.fetchall()
-
- context = Context({
- 'inaddr': reversezone[1].rstrip('.rev'),
- 'zone': reversezone,
- 'nameservers': reverse_nameservers,
- })
-
- self.filedata[reversezone[1]] = self.templates['reversesoa'].render(context)
- self.filedata[reversezone[1] + '.external'] = self.templates['reversesoa'].render(context)
- self.filedata[reversezone[1]] += reversezone[9]
- self.filedata[reversezone[1] + '.external'] += reversezone[9]
-
- subnet = reversezone[1].split(".")
- subnet.reverse()
- reversenames.append((reversezone[1].rstrip('.rev'), ".".join(subnet[1:])))
-
- for filename in reversenames:
- cursor.execute("""
- SELECT DISTINCT h.hostname, p.ip_addr, n.dns_view 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 n.ip_id = p.id
- WHERE p.ip_addr LIKE '%s%%%%' AND h.status = 'active' ORDER BY p.ip_addr
- """ % filename[1])
- reversehosts = cursor.fetchall()
- zonefile = StringIO()
- externalzonefile = StringIO()
- if len(filename[0].split(".")) == 2:
- originlist = []
- [originlist.append((".".join([ip[1].split(".")[2], filename[0]]),
- ".".join([filename[1], ip[1].split(".")[2]])))
- for ip in reversehosts
- if (".".join([ip[1].split(".")[2], filename[0]]),
- ".".join([filename[1], ip[1].split(".")[2]])) not in originlist]
- for origin in originlist:
- hosts = [(host[1].split("."), host[0])
- for host in reversehosts
- if host[1].rstrip('0123456789').rstrip('.') == origin[1]]
- hosts_external = [(host[1].split("."), host[0])
- for host in reversehosts
- if (host[1].rstrip('0123456789').rstrip('.') == origin[1]
- and host[2] == 'global')]
- context = Context({
- 'hosts': hosts,
- 'inaddr': origin[0],
- 'fileorigin': filename[0],
- })
- zonefile.write(self.templates['reverseapp'].render(context))
- context = Context({
- 'hosts': hosts_external,
- 'inaddr': origin[0],
- 'fileorigin': filename[0],
- })
- externalzonefile.write(self.templates['reverseapp'].render(context))
- else:
- originlist = [filename[0]]
- hosts = [(host[1].split("."), host[0])
- for host in reversehosts
- if (host[1].split("."), host[0]) not in hosts]
- hosts_external = [(host[1].split("."), host[0])
- for host in reversehosts
- if ((host[1].split("."), host[0]) not in hosts_external
- and host[2] == 'global')]
- context = Context({
- 'hosts': hosts,
- 'inaddr': filename[0],
- 'fileorigin': None,
- })
- zonefile.write(self.templates['reverseapp'].render(context))
- context = Context({
- 'hosts': hosts_external,
- 'inaddr': filename[0],
- 'fileorigin': None,
- })
- externalzonefile.write(self.templates['reverseapp'].render(context))
- self.filedata['%s.rev' % filename[0]] += zonefile.getvalue()
- self.filedata['%s.rev.external' % filename[0]] += externalzonefile.getvalue()
- zonefile.close()
- externalzonefile.close()
- self.Entries['ConfigFile']['%s/%s.rev' % (self.filepath, filename[0])] = self.FetchFile
- self.Entries['ConfigFile']['%s/%s.rev.external' % (self.filepath, filename[0])] = self.FetchFile
-
- ## here's where the named.conf file gets written
- context = Context({
- 'zones': zones,
- 'reverses': reversenames,
- })
- self.filedata['named.conf'] = self.templates['named'].render(context)
- self.Entries['ConfigFile']['/my/adm/hostbase/files/named.conf'] = self.FetchFile
- self.filedata['named.conf.views'] = self.templates['namedviews'].render(context)
- self.Entries['ConfigFile']['/my/adm/hostbase/files/named.conf.views'] = self.FetchFile
-
- def buildDHCP(self):
- """Pre-build dhcpd.conf and stash in the filedata table."""
-
- # fetches all the hosts with DHCP == True
- cursor = connection.cursor()
- cursor.execute("""
- SELECT hostname, mac_addr, ip_addr
- FROM (hostbase_host h INNER JOIN hostbase_interface i ON h.id = i.host_id)
- INNER JOIN hostbase_ip ip ON i.id = ip.interface_id
- WHERE i.dhcp=1 AND h.status='active' AND i.mac_addr <> ''
- AND i.mac_addr <> 'float' AND i.mac_addr <> 'unknown'
- ORDER BY h.hostname, i.mac_addr
- """)
-
- dhcphosts = cursor.fetchall()
- count = 0
- hosts = []
- hostdata = [dhcphosts[0][0], dhcphosts[0][1], dhcphosts[0][2]]
- if len(dhcphosts) > 1:
- for x in range(1, len(dhcphosts)):
- # if an interface has 2 or more ip addresses
- # adds the ip to the current interface
- if hostdata[0].split(".")[0] == dhcphosts[x][0].split(".")[0] and hostdata[1] == dhcphosts[x][1]:
- hostdata[2] = ", ".join([hostdata[2], dhcphosts[x][2]])
- # if a host has 2 or more interfaces
- # writes the current one and grabs the next
- elif hostdata[0].split(".")[0] == dhcphosts[x][0].split(".")[0]:
- hosts.append(hostdata)
- count += 1
- hostdata = ["-".join([dhcphosts[x][0], str(count)]), dhcphosts[x][1], dhcphosts[x][2]]
- # new host found, writes current data to the template
- else:
- hosts.append(hostdata)
- count = 0
- hostdata = [dhcphosts[x][0], dhcphosts[x][1], dhcphosts[x][2]]
- #makes sure the last of the data gets written out
- if hostdata not in hosts:
- hosts.append(hostdata)
-
- context = Context({
- 'hosts': hosts,
- 'numips': len(hosts),
- })
-
- self.filedata['dhcpd.conf'] = self.templates['dhcp'].render(context)
- self.Entries['ConfigFile']['/my/adm/hostbase/files/dhcpd.conf'] = self.FetchFile
-
- def buildHosts(self):
- """Pre-build and stash /etc/hosts file."""
-
- append_data = []
-
- cursor = connection.cursor()
- cursor.execute("""
- SELECT hostname FROM hostbase_host ORDER BY hostname
- """)
- hostbase = cursor.fetchall()
- domains = [host[0].split(".", 1)[1] for host in hostbase]
- domains_set = set(domains)
- domain_data = [(domain, domains.count(domain)) for domain in domains_set]
- domain_data.sort()
-
- cursor.execute("""
- SELECT ip_addr FROM hostbase_ip ORDER BY ip_addr
- """)
- ips = cursor.fetchall()
- three_octets = [ip[0].rstrip('0123456789').rstrip('.') \
- for ip in ips]
- three_octets_set = set(three_octets)
- three_octets_data = [(octet, three_octets.count(octet)) \
- for octet in three_octets_set]
- three_octets_data.sort()
-
- for three_octet in three_octets_data:
- querystring = """SELECT h.hostname, h.primary_user,
- p.ip_addr, n.name, c.cname
- 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)
- LEFT JOIN hostbase_cname c ON n.id = c.name_id
- WHERE p.ip_addr LIKE \'%s.%%%%\' AND h.status = 'active'""" % three_octet[0]
- cursor.execute(querystring)
- tosort = list(cursor.fetchall())
- tosort.sort(lambda x, y: cmp(int(x[2].split(".")[-1]), int(y[2].split(".")[-1])))
- append_data.append((three_octet, tuple(tosort)))
-
- two_octets = [ip.rstrip('0123456789').rstrip('.') for ip in three_octets]
- two_octets_set = set(two_octets)
- two_octets_data = [(octet, two_octets.count(octet))
- for octet in two_octets_set]
- two_octets_data.sort()
-
- context = Context({
- 'domain_data': domain_data,
- 'three_octets_data': three_octets_data,
- 'two_octets_data': two_octets_data,
- 'three_octets': three_octets,
- 'num_ips': len(three_octets),
- })
-
- self.filedata['hosts'] = self.templates['hosts'].render(context)
-
- for subnet in append_data:
- ips = []
- simple = True
- namelist = [name.split('.', 1)[0] for name in [subnet[1][0][3]]]
- cnamelist = []
- if subnet[1][0][4]:
- cnamelist.append(subnet[1][0][4].split('.', 1)[0])
- simple = False
- appenddata = subnet[1][0]
- for ip in subnet[1][1:]:
- if appenddata[2] == ip[2]:
- namelist.append(ip[3].split('.', 1)[0])
- if ip[4]:
- cnamelist.append(ip[4].split('.', 1)[0])
- simple = False
- appenddata = ip
- else:
- if appenddata[0] == ip[0]:
- simple = False
- ips.append((appenddata[2], appenddata[0], set(namelist),
- cnamelist, simple, appenddata[1]))
- appenddata = ip
- simple = True
- namelist = [ip[3].split('.', 1)[0]]
- cnamelist = []
- if ip[4]:
- cnamelist.append(ip[4].split('.', 1)[0])
- simple = False
- ips.append((appenddata[2], appenddata[0], set(namelist),
- cnamelist, simple, appenddata[1]))
- context = Context({
- 'subnet': subnet[0],
- 'ips': ips,
- })
- self.filedata['hosts'] += self.templates['hostsapp'].render(context)
- self.Entries['ConfigFile']['/mcs/etc/hosts'] = self.FetchFile
-
- def buildPrinters(self):
- """The /mcs/etc/printers.data file"""
- header = """# This file is automatically generated. DO NOT EDIT IT!
-#
-Name Room User Type Notes
-============== ========== ============================== ======================== ====================
-"""
-
- cursor = connection.cursor()
- # fetches all the printers from the database
- cursor.execute("""
- SELECT printq, location, primary_user, comments
- FROM hostbase_host
- WHERE whatami='printer' AND printq <> '' AND status = 'active'
- ORDER BY printq
- """)
- printers = cursor.fetchall()
-
- printersfile = header
- for printer in printers:
- # splits up the printq line and gets the
- # correct description out of the comments section
- temp = printer[3].split('\n')
- for printq in re.split(',[ ]*', printer[0]):
- if len(temp) > 1:
- printersfile += ("%-16s%-12s%-32s%-26s%s\n" %
- (printq, printer[1], printer[2], temp[1], temp[0]))
- else:
- printersfile += ("%-16s%-12s%-32s%-26s%s\n" %
- (printq, printer[1], printer[2], '', printer[3]))
- self.filedata['printers.data'] = printersfile
- self.Entries['ConfigFile']['/mcs/etc/printers.data'] = self.FetchFile
-
- def buildHostsLPD(self):
- """Creates the /mcs/etc/hosts.lpd file"""
-
- # this header needs to be changed to be more generic
- header = """+@machines
-+@all-machines
-achilles.ctd.anl.gov
-raven.ops.anl.gov
-seagull.hr.anl.gov
-parrot.ops.anl.gov
-condor.ops.anl.gov
-delphi.esh.anl.gov
-anlcv1.ctd.anl.gov
-anlvms.ctd.anl.gov
-olivia.ctd.anl.gov\n\n"""
-
- cursor = connection.cursor()
- cursor.execute("""
- SELECT hostname FROM hostbase_host WHERE netgroup=\"red\" AND status = 'active'
- ORDER BY hostname""")
- redmachines = list(cursor.fetchall())
- cursor.execute("""
- SELECT n.name 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
- WHERE netgroup=\"red\" AND n.only=1 AND h.status = 'active'
- """)
- redmachines.extend(list(cursor.fetchall()))
- cursor.execute("""
- SELECT hostname FROM hostbase_host WHERE netgroup=\"win\" AND status = 'active'
- ORDER BY hostname""")
- winmachines = list(cursor.fetchall())
- cursor.execute("""
- SELECT n.name 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
- WHERE netgroup=\"win\" AND n.only=1 AND h.status = 'active'
- """)
- winmachines.__add__(list(cursor.fetchall()))
- hostslpdfile = header
- for machine in redmachines:
- hostslpdfile += machine[0] + "\n"
- hostslpdfile += "\n"
- for machine in winmachines:
- hostslpdfile += machine[0] + "\n"
- self.filedata['hosts.lpd'] = hostslpdfile
- self.Entries['ConfigFile']['/mcs/etc/hosts.lpd'] = self.FetchFile
-
- def buildNetgroups(self):
- """Makes the *-machine files"""
- header = """###################################################################
-# This file lists hosts in the '%s' machine netgroup, it is
-# automatically generated. DO NOT EDIT THIS FILE!
-#
-# Number of hosts in '%s' machine netgroup: %i
-#\n\n"""
-
- cursor = connection.cursor()
- # fetches all the hosts that with valid netgroup entries
- cursor.execute("""
- SELECT h.hostname, n.name, h.netgroup, n.only 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
- WHERE h.netgroup <> '' AND h.netgroup <> 'none' AND h.status = 'active'
- ORDER BY h.netgroup, h.hostname
- """)
- nameslist = cursor.fetchall()
- # gets the first host and initializes the hash
- hostdata = nameslist[0]
- netgroups = {hostdata[2]: [hostdata[0]]}
- for row in nameslist:
- # if new netgroup, create it
- if row[2] not in netgroups:
- netgroups.update({row[2]: []})
- # if it belongs in the netgroup and has multiple interfaces, put them in
- if hostdata[0] == row[0] and row[3]:
- netgroups[row[2]].append(row[1])
- hostdata = row
- # if its a new host, write the old one to the hash
- elif hostdata[0] != row[0]:
- netgroups[row[2]].append(row[0])
- hostdata = row
-
- for netgroup in netgroups:
- fileoutput = StringIO()
- fileoutput.write(header % (netgroup, netgroup, len(netgroups[netgroup])))
- for each in netgroups[netgroup]:
- fileoutput.write(each + "\n")
- self.filedata['%s-machines' % netgroup] = fileoutput.getvalue()
- fileoutput.close()
- self.Entries['ConfigFile']['/my/adm/hostbase/makenets/machines/%s-machines' % netgroup] = self.FetchFile
-
- cursor.execute("""
- UPDATE hostbase_host SET dirty=0
- """)
diff --git a/src/lib/Bcfg2/Server/Plugins/Ldap.py b/src/lib/Bcfg2/Server/Plugins/Ldap.py
index f724402d0..8e8b078d9 100644
--- a/src/lib/Bcfg2/Server/Plugins/Ldap.py
+++ b/src/lib/Bcfg2/Server/Plugins/Ldap.py
@@ -44,10 +44,10 @@ class ConfigFile(Bcfg2.Server.Plugin.FileBacked):
The approach implemented here is having the user call a registering
decorator that updates a global variable in this module.
"""
- def __init__(self, filename, fam):
+ def __init__(self, filename):
self.filename = filename
Bcfg2.Server.Plugin.FileBacked.__init__(self, self.filename)
- fam.AddMonitor(self.filename, self)
+ self.fam.AddMonitor(self.filename, self)
def Index(self):
"""
@@ -72,7 +72,7 @@ class Ldap(Bcfg2.Server.Plugin.Plugin, Bcfg2.Server.Plugin.Connector):
def __init__(self, core, datastore):
Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore)
Bcfg2.Server.Plugin.Connector.__init__(self)
- self.config = ConfigFile(self.data + "/config.py", core.fam)
+ self.config = ConfigFile(self.data + "/config.py")
def debug_log(self, message, flag = None):
if (flag is None) and self.debug_flag or flag:
diff --git a/src/lib/Bcfg2/Server/Plugins/Metadata.py b/src/lib/Bcfg2/Server/Plugins/Metadata.py
index 5519d42b5..b64f91ccf 100644
--- a/src/lib/Bcfg2/Server/Plugins/Metadata.py
+++ b/src/lib/Bcfg2/Server/Plugins/Metadata.py
@@ -103,7 +103,6 @@ class XMLMetadataConfig(Bcfg2.Server.Plugin.XMLFileBacked):
# so that XInclude'd files get properly watched
fpath = os.path.join(metadata.data, basefile)
Bcfg2.Server.Plugin.XMLFileBacked.__init__(self, fpath,
- fam=metadata.core.fam,
should_monitor=False)
self.should_monitor = watch_clients
self.metadata = metadata
@@ -112,7 +111,7 @@ class XMLMetadataConfig(Bcfg2.Server.Plugin.XMLFileBacked):
self.basedata = None
self.basedir = metadata.data
self.logger = metadata.logger
- self.pseudo_monitor = isinstance(metadata.core.fam,
+ self.pseudo_monitor = isinstance(Bcfg2.Server.FileMonitor.get_fam(),
Bcfg2.Server.FileMonitor.Pseudo)
def _get_xdata(self):
@@ -250,7 +249,7 @@ class XMLMetadataConfig(Bcfg2.Server.Plugin.XMLFileBacked):
def add_monitor(self, fpath):
self.extras.append(fpath)
- if self.fam and self.should_monitor:
+ if self.should_monitor:
self.fam.AddMonitor(fpath, self.metadata)
def HandleEvent(self, event=None):
@@ -469,7 +468,8 @@ class Metadata(Bcfg2.Server.Plugin.Metadata,
(clients.xml or groups.xml, e.g.) """
if self.watch_clients:
try:
- self.core.fam.AddMonitor(os.path.join(self.data, fname), self)
+ Bcfg2.Server.FileMonitor.get_fam().AddMonitor(
+ os.path.join(self.data, fname), self)
except:
err = sys.exc_info()[1]
msg = "Unable to add file monitor for %s: %s" % (fname, err)
diff --git a/src/lib/Bcfg2/Server/Plugins/NagiosGen.py b/src/lib/Bcfg2/Server/Plugins/NagiosGen.py
index baea5fe23..fc06be455 100644
--- a/src/lib/Bcfg2/Server/Plugins/NagiosGen.py
+++ b/src/lib/Bcfg2/Server/Plugins/NagiosGen.py
@@ -17,14 +17,14 @@ class NagiosGenConfig(Bcfg2.Server.Plugin.StructFile):
encryption = False
- def __init__(self, filename, fam):
+ def __init__(self, filename):
# create config.xml if missing
if not os.path.exists(filename):
LOGGER.warning("NagiosGen: %s missing. "
"Creating empty one for you." % filename)
open(filename, "w").write("<NagiosGen/>")
- Bcfg2.Server.Plugin.StructFile.__init__(self, filename, fam=fam,
+ Bcfg2.Server.Plugin.StructFile.__init__(self, filename,
should_monitor=True)
@@ -38,8 +38,7 @@ class NagiosGen(Bcfg2.Server.Plugin.Plugin,
def __init__(self, core, datastore):
Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore)
Bcfg2.Server.Plugin.Generator.__init__(self)
- self.config = NagiosGenConfig(os.path.join(self.data, 'config.xml'),
- core.fam)
+ self.config = NagiosGenConfig(os.path.join(self.data, 'config.xml'))
self.Entries = {'Path':
{'/etc/nagiosgen.status': self.createhostconfig,
'/etc/nagios/nagiosgen.cfg': self.createserverconfig}}
diff --git a/src/lib/Bcfg2/Server/Plugins/Packages/Apt.py b/src/lib/Bcfg2/Server/Plugins/Packages/Apt.py
index 27f493677..57f802bb5 100644
--- a/src/lib/Bcfg2/Server/Plugins/Packages/Apt.py
+++ b/src/lib/Bcfg2/Server/Plugins/Packages/Apt.py
@@ -13,8 +13,7 @@ class AptCollection(Collection):
overrides nothing, and defers all operations to :class:`PacSource`
"""
- def __init__(self, metadata, sources, cachepath, basepath, fam,
- debug=False):
+ def __init__(self, metadata, sources, cachepath, basepath, debug=False):
# we define an __init__ that just calls the parent __init__,
# so that we can set the docstring on __init__ to something
# different from the parent __init__ -- namely, the parent
@@ -22,7 +21,7 @@ class AptCollection(Collection):
# which we use to delineate the actual docs from the
# .. autoattribute hacks we have to do to get private
# attributes included in sphinx 1.0 """
- Collection.__init__(self, metadata, sources, cachepath, basepath, fam,
+ Collection.__init__(self, metadata, sources, cachepath, basepath,
debug=debug)
__init__.__doc__ = Collection.__init__.__doc__.split(".. -----")[0]
@@ -48,10 +47,6 @@ class AptCollection(Collection):
class AptSource(Source):
""" Handle APT sources """
- #: :ref:`server-plugins-generators-packages-magic-groups` for
- #: ``AptSource`` are "apt", "debian", "ubuntu", and "nexenta"
- basegroups = ['apt', 'debian', 'ubuntu', 'nexenta']
-
#: AptSource sets the ``type`` on Package entries to "deb"
ptype = 'deb'
diff --git a/src/lib/Bcfg2/Server/Plugins/Packages/Collection.py b/src/lib/Bcfg2/Server/Plugins/Packages/Collection.py
index 2c59b9a5a..cf4234ed0 100644
--- a/src/lib/Bcfg2/Server/Plugins/Packages/Collection.py
+++ b/src/lib/Bcfg2/Server/Plugins/Packages/Collection.py
@@ -78,6 +78,7 @@ import copy
import logging
import lxml.etree
import Bcfg2.Server.Plugin
+from Bcfg2.Server.FileMonitor import get_fam
from Bcfg2.Options import get_option_parser
from Bcfg2.Compat import any, md5 # pylint: disable=W0622
@@ -94,8 +95,7 @@ class Collection(list, Bcfg2.Server.Plugin.Debuggable):
#: Whether or not this Packages backend supports package groups
__package_groups__ = False
- def __init__(self, metadata, sources, cachepath, basepath, fam,
- debug=False):
+ def __init__(self, metadata, sources, cachepath, basepath, debug=False):
"""
:param metadata: The client metadata for this collection
:type metadata: Bcfg2.Server.Plugins.Metadata.ClientMetadata
@@ -112,9 +112,6 @@ class Collection(list, Bcfg2.Server.Plugin.Debuggable):
directory, where more permanent data can be
stored
:type basepath: string
- :param fam: A file monitor object to use if this Collection
- needs to monitor for file activity
- :type fam: Bcfg2.Server.FileMonitor.FileMonitor
:param debug: Enable debugging output
:type debug: bool
@@ -128,7 +125,7 @@ class Collection(list, Bcfg2.Server.Plugin.Debuggable):
self.basepath = basepath
self.cachepath = cachepath
self.virt_pkgs = dict()
- self.fam = fam
+ self.fam = get_fam()
self.setup = get_option_parser()
try:
@@ -204,19 +201,6 @@ class Collection(list, Bcfg2.Server.Plugin.Debuggable):
return sorted(list(set(groups)))
@property
- def basegroups(self):
- """ Get a list of group names used by this Collection type in
- resolution of
- :ref:`server-plugins-generators-packages-magic-groups`.
-
- The base implementation simply aggregates the results of
- :attr:`Bcfg2.Server.Plugins.Packages.Source.Source.basegroups`."""
- groups = set()
- for source in self:
- groups.update(source.basegroups)
- return list(groups)
-
- @property
def cachefiles(self):
""" A list of the full path to all cachefiles used by this
collection.
@@ -386,20 +370,6 @@ class Collection(list, Bcfg2.Server.Plugin.Debuggable):
for source in self:
source.filter_unknown(unknown)
- def magic_groups_match(self):
- """ Returns True if the client's
- :ref:`server-plugins-generators-packages-magic-groups` match
- the magic groups for any of the sources contained in this
- Collection.
-
- The base implementation returns True if any source
- :func:`Bcfg2.Server.Plugins.Packages.Source.Source.magic_groups_match`
- returns True.
-
- :returns: bool
- """
- return any(s.magic_groups_match(self.metadata) for s in self)
-
def build_extra_structures(self, independent):
""" Add additional entries to the ``<Independent/>`` section
of the final configuration. This can be used to handle, e.g.,
diff --git a/src/lib/Bcfg2/Server/Plugins/Packages/Pac.py b/src/lib/Bcfg2/Server/Plugins/Packages/Pac.py
index 99aed5ce5..5f4d2ea41 100644
--- a/src/lib/Bcfg2/Server/Plugins/Packages/Pac.py
+++ b/src/lib/Bcfg2/Server/Plugins/Packages/Pac.py
@@ -12,8 +12,7 @@ class PacCollection(Collection):
overrides nothing, and defers all operations to :class:`PacSource`
"""
- def __init__(self, metadata, sources, cachepath, basepath, fam,
- debug=False):
+ def __init__(self, metadata, sources, cachepath, basepath, debug=False):
# we define an __init__ that just calls the parent __init__,
# so that we can set the docstring on __init__ to something
# different from the parent __init__ -- namely, the parent
@@ -21,7 +20,7 @@ class PacCollection(Collection):
# which we use to delineate the actual docs from the
# .. autoattribute hacks we have to do to get private
# attributes included in sphinx 1.0 """
- Collection.__init__(self, metadata, sources, cachepath, basepath, fam,
+ Collection.__init__(self, metadata, sources, cachepath, basepath,
debug=debug)
__init__.__doc__ = Collection.__init__.__doc__.split(".. -----")[0]
@@ -29,10 +28,6 @@ class PacCollection(Collection):
class PacSource(Source):
""" Handle Pacman sources """
- #: :ref:`server-plugins-generators-packages-magic-groups` for
- #: ``PacSource`` are "arch" and "parabola"
- basegroups = ['arch', 'parabola']
-
#: PacSource sets the ``type`` on Package entries to "pacman"
ptype = 'pacman'
diff --git a/src/lib/Bcfg2/Server/Plugins/Packages/PackagesSources.py b/src/lib/Bcfg2/Server/Plugins/Packages/PackagesSources.py
index f528076c4..876ee6090 100644
--- a/src/lib/Bcfg2/Server/Plugins/Packages/PackagesSources.py
+++ b/src/lib/Bcfg2/Server/Plugins/Packages/PackagesSources.py
@@ -20,7 +20,7 @@ class PackagesSources(Bcfg2.Server.Plugin.StructFile,
encryption = False
- def __init__(self, filename, cachepath, fam, packages):
+ def __init__(self, filename, cachepath, packages):
"""
:param filename: The full path to ``sources.xml``
:type filename: string
@@ -28,9 +28,6 @@ class PackagesSources(Bcfg2.Server.Plugin.StructFile,
:class:`Bcfg2.Server.Plugins.Packages.Source.Source`
data will be cached
:type cachepath: string
- :param fam: The file access monitor to use to create watches
- on ``sources.xml`` and any XIncluded files.
- :type fam: Bcfg2.Server.FileMonitor.FileMonitor
:param packages: The Packages plugin object ``sources.xml`` is
being parsed on behalf of (i.e., the calling
object)
@@ -41,7 +38,7 @@ class PackagesSources(Bcfg2.Server.Plugin.StructFile,
"""
Bcfg2.Server.Plugin.Debuggable.__init__(self)
try:
- Bcfg2.Server.Plugin.StructFile.__init__(self, filename, fam=fam,
+ Bcfg2.Server.Plugin.StructFile.__init__(self, filename,
should_monitor=True)
except OSError:
err = sys.exc_info()[1]
diff --git a/src/lib/Bcfg2/Server/Plugins/Packages/Source.py b/src/lib/Bcfg2/Server/Plugins/Packages/Source.py
index 33eff60c8..7a8b2827a 100644
--- a/src/lib/Bcfg2/Server/Plugins/Packages/Source.py
+++ b/src/lib/Bcfg2/Server/Plugins/Packages/Source.py
@@ -27,7 +27,6 @@ in your ``Source`` subclass:
* :func:`Source.urls`
* :func:`Source.read_files`
-* :attr:`Source.basegroups`
Additionally, you may want to consider overriding the following
methods and attributes:
@@ -107,11 +106,6 @@ class Source(Bcfg2.Server.Plugin.Debuggable): # pylint: disable=R0902
those features.
"""
- #: The list of
- #: :ref:`server-plugins-generators-packages-magic-groups` that
- #: make sources of this type available to clients.
- basegroups = []
-
#: The Package type handled by this Source class. The ``type``
#: attribute of Package entries will be set to the value ``ptype``
#: when they are handled by :mod:`Bcfg2.Server.Plugins.Packages`.
@@ -303,8 +297,7 @@ class Source(Bcfg2.Server.Plugin.Debuggable): # pylint: disable=R0902
:return: list of strings - group names
"""
return sorted(list(set([g for g in metadata.groups
- if (g in self.basegroups or
- g in self.groups or
+ if (g in self.groups or
g in self.arches)])))
def load_state(self):
@@ -631,16 +624,15 @@ class Source(Bcfg2.Server.Plugin.Debuggable): # pylint: disable=R0902
def applies(self, metadata):
""" Return true if this source applies to the given client,
- i.e., the client is in all necessary groups and
- :ref:`server-plugins-generators-packages-magic-groups`.
+ i.e., the client is in all necessary groups.
:param metadata: The client metadata to check to see if this
source applies
:type metadata: Bcfg2.Server.Plugins.Metadata.ClientMetadata
:returns: bool
"""
- # check base groups
- if not self.magic_groups_match(metadata):
+ # check arch groups
+ if not self.arch_groups_match(metadata):
return False
# check Group/Client tags from sources.xml
@@ -711,29 +703,13 @@ class Source(Bcfg2.Server.Plugin.Debuggable): # pylint: disable=R0902
"""
return []
- def magic_groups_match(self, metadata):
- """ Returns True if the client's
- :ref:`server-plugins-generators-packages-magic-groups` match
- the magic groups this source. Also returns True if magic
- groups are off in the configuration and the client's
- architecture matches (i.e., architecture groups are *always*
- checked).
+ def arch_groups_match(self, metadata):
+ """ Returns True if the client is in an arch group that
+ matches the arch of this source.
:returns: bool
"""
- found_arch = False
for arch in self.arches:
if arch in metadata.groups:
- found_arch = True
- break
- if not found_arch:
- return False
-
- if not self.setup.cfp.getboolean("packages", "magic_groups",
- default=False):
- return True
- else:
- for group in self.basegroups:
- if group in metadata.groups:
- return True
- return False
+ return True
+ return False
diff --git a/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py b/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py
index 1ad699208..c5d59eb24 100644
--- a/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py
+++ b/src/lib/Bcfg2/Server/Plugins/Packages/Yum.py
@@ -59,6 +59,7 @@ import socket
import logging
import lxml.etree
from subprocess import Popen, PIPE
+import Bcfg2.Server.FileMonitor
import Bcfg2.Server.Plugin
from Bcfg2.Options import get_option_parser
# pylint: disable=W0622
@@ -174,7 +175,7 @@ class PulpCertificateSet(Bcfg2.Server.Plugin.EntrySet):
#: The path to certificates on consumer machines
certpath = "/etc/pki/consumer/cert.pem"
- def __init__(self, path, fam):
+ def __init__(self, path):
"""
:param path: The path to the directory where Pulp consumer
certificates will be stored
@@ -192,7 +193,7 @@ class PulpCertificateSet(Bcfg2.Server.Plugin.EntrySet):
important='true',
sensitive='true',
paranoid=self.metadata['paranoid'])
- self.fam = fam
+ self.fam = Bcfg2.Server.FileMonitor.get_fam()
self.fam.AddMonitor(path, self)
def HandleEvent(self, event):
@@ -271,9 +272,8 @@ class YumCollection(Collection):
#: :class:`PulpCertificateSet` object used to handle Pulp certs
pulp_cert_set = None
- def __init__(self, metadata, sources, cachepath, basepath, fam,
- debug=False):
- Collection.__init__(self, metadata, sources, cachepath, basepath, fam,
+ def __init__(self, metadata, sources, cachepath, basepath, debug=False):
+ Collection.__init__(self, metadata, sources, cachepath, basepath,
debug=debug)
self.keypath = os.path.join(self.cachepath, "keys")
@@ -309,7 +309,7 @@ class YumCollection(Collection):
self.logger.error("Could not create Pulp consumer "
"cert directory at %s: %s" %
(certdir, err))
- self.pulp_cert_set = PulpCertificateSet(certdir, self.fam)
+ self.pulp_cert_set = PulpCertificateSet(certdir)
@property
def __package_groups__(self):
@@ -933,10 +933,6 @@ class YumCollection(Collection):
class YumSource(Source):
""" Handle yum sources """
- #: :ref:`server-plugins-generators-packages-magic-groups` for
- #: ``YumSource`` are "yum", "redhat", "centos", and "fedora"
- basegroups = ['yum', 'redhat', 'centos', 'fedora']
-
#: YumSource sets the ``type`` on Package entries to "yum"
ptype = 'yum'
diff --git a/src/lib/Bcfg2/Server/Plugins/Packages/__init__.py b/src/lib/Bcfg2/Server/Plugins/Packages/__init__.py
index db64cf309..169dcd588 100644
--- a/src/lib/Bcfg2/Server/Plugins/Packages/__init__.py
+++ b/src/lib/Bcfg2/Server/Plugins/Packages/__init__.py
@@ -64,14 +64,6 @@ class Packages(Bcfg2.Server.Plugin.Plugin,
# create key directory if needed
os.makedirs(self.keypath)
- # warn about deprecated magic groups
- if self.core.setup.cfp.getboolean("packages", "magic_groups",
- default=False):
- self.logger.warning("Packages: Magic groups are deprecated and "
- "will be removed in a future release")
- self.logger.warning("You can disable magic groups by setting "
- "magic_groups=0 in [packages] in bcfg2.conf")
-
# pylint: disable=C0301
#: The
#: :class:`Bcfg2.Server.Plugins.Packages.PackagesSources.PackagesSources`
@@ -79,7 +71,7 @@ class Packages(Bcfg2.Server.Plugin.Plugin,
#: :class:`Bcfg2.Server.Plugins.Packages.Source.Source` objects for
#: this plugin.
self.sources = PackagesSources(os.path.join(self.data, "sources.xml"),
- self.cachepath, core.fam, self)
+ self.cachepath, self)
#: We cache
#: :class:`Bcfg2.Server.Plugins.Packages.Collection.Collection`
@@ -229,13 +221,7 @@ class Packages(Bcfg2.Server.Plugin.Plugin,
:raises: :class:`Bcfg2.Server.Plugin.exceptions.PluginExecutionError`
"""
if entry.tag == 'Package':
- if self.core.setup.cfp.getboolean("packages", "magic_groups",
- default=False):
- collection = self.get_collection(metadata)
- if collection.magic_groups_match():
- return True
- else:
- return True
+ return True
elif entry.tag == 'Path':
# managed entries for yum/apt configs
if (entry.get("name") == \
@@ -476,8 +462,7 @@ class Packages(Bcfg2.Server.Plugin.Plugin,
if not self.sources.loaded:
# if sources.xml has not received a FAM event yet, defer;
# instantiate a dummy Collection object
- return Collection(metadata, [], self.cachepath, self.data,
- self.core.fam)
+ return Collection(metadata, [], self.cachepath, self.data)
if metadata.hostname in self.clients:
return self.collections[self.clients[metadata.hostname]]
@@ -508,7 +493,7 @@ class Packages(Bcfg2.Server.Plugin.Plugin,
"for %s" % (cclass.__name__, metadata.hostname))
collection = cclass(metadata, relevant, self.cachepath, self.data,
- self.core.fam, debug=self.debug_flag)
+ debug=self.debug_flag)
ckey = collection.cachekey
self.clients[metadata.hostname] = ckey
self.collections[ckey] = collection
diff --git a/src/lib/Bcfg2/Server/Plugins/Probes.py b/src/lib/Bcfg2/Server/Plugins/Probes.py
index f106b75a4..7b8ef2209 100644
--- a/src/lib/Bcfg2/Server/Plugins/Probes.py
+++ b/src/lib/Bcfg2/Server/Plugins/Probes.py
@@ -9,6 +9,7 @@ import operator
import lxml.etree
import Bcfg2.Server
import Bcfg2.Server.Plugin
+import Bcfg2.Server.FileMonitor
try:
from django.db import models
@@ -117,12 +118,12 @@ class ProbeSet(Bcfg2.Server.Plugin.EntrySet):
bangline = re.compile('^#!\s*(?P<interpreter>.*)$')
basename_is_regex = True
- def __init__(self, path, fam, encoding, plugin_name):
+ def __init__(self, path, encoding, plugin_name):
self.plugin_name = plugin_name
Bcfg2.Server.Plugin.EntrySet.__init__(self, '[0-9A-Za-z_\-]+', path,
Bcfg2.Server.Plugin.SpecificData,
encoding)
- fam.AddMonitor(path, self)
+ Bcfg2.Server.FileMonitor.get_fam().AddMonitor(path, self)
def HandleEvent(self, event):
""" handle events on everything but probed.xml """
@@ -178,7 +179,7 @@ class Probes(Bcfg2.Server.Plugin.Probing,
Bcfg2.Server.Plugin.DatabaseBacked.__init__(self, core, datastore)
try:
- self.probes = ProbeSet(self.data, core.fam, core.setup['encoding'],
+ self.probes = ProbeSet(self.data, core.setup['encoding'],
self.name)
except:
err = sys.exc_info()[1]
diff --git a/src/lib/Bcfg2/Server/Plugins/Properties.py b/src/lib/Bcfg2/Server/Plugins/Properties.py
index 24daa2107..b7ede594c 100644
--- a/src/lib/Bcfg2/Server/Plugins/Properties.py
+++ b/src/lib/Bcfg2/Server/Plugins/Properties.py
@@ -88,8 +88,8 @@ class PropertyFile(object):
class JSONPropertyFile(Bcfg2.Server.Plugin.FileBacked, PropertyFile):
""" Handle JSON Properties files. """
- def __init__(self, name, fam=None):
- Bcfg2.Server.Plugin.FileBacked.__init__(self, name, fam=fam)
+ def __init__(self, name):
+ Bcfg2.Server.Plugin.FileBacked.__init__(self, name)
PropertyFile.__init__(self, name)
self.json = None
__init__.__doc__ = Bcfg2.Server.Plugin.FileBacked.__init__.__doc__
@@ -127,8 +127,8 @@ class JSONPropertyFile(Bcfg2.Server.Plugin.FileBacked, PropertyFile):
class YAMLPropertyFile(Bcfg2.Server.Plugin.FileBacked, PropertyFile):
""" Handle YAML Properties files. """
- def __init__(self, name, fam=None):
- Bcfg2.Server.Plugin.FileBacked.__init__(self, name, fam=fam)
+ def __init__(self, name):
+ Bcfg2.Server.Plugin.FileBacked.__init__(self, name)
PropertyFile.__init__(self, name)
self.yaml = None
__init__.__doc__ = Bcfg2.Server.Plugin.FileBacked.__init__.__doc__
@@ -166,8 +166,8 @@ class YAMLPropertyFile(Bcfg2.Server.Plugin.FileBacked, PropertyFile):
class XMLPropertyFile(Bcfg2.Server.Plugin.StructFile, PropertyFile):
""" Handle XML Properties files. """
- def __init__(self, name, fam=None, should_monitor=False):
- Bcfg2.Server.Plugin.StructFile.__init__(self, name, fam=fam,
+ def __init__(self, name, should_monitor=False):
+ Bcfg2.Server.Plugin.StructFile.__init__(self, name,
should_monitor=should_monitor)
PropertyFile.__init__(self, name)
__init__.__doc__ = Bcfg2.Server.Plugin.StructFile.__init__.__doc__
@@ -239,8 +239,8 @@ class PropDirectoryBacked(Bcfg2.Server.Plugin.DirectoryBacked):
#: Ignore XML schema (``.xsd``) files
ignore = re.compile(r'.*\.xsd$')
- def __init__(self, data, fam):
- Bcfg2.Server.Plugin.DirectoryBacked.__init__(self, data, fam)
+ def __init__(self, data):
+ Bcfg2.Server.Plugin.DirectoryBacked.__init__(self, data)
#: Instead of creating children of this object with a static
#: object, we use :func:`property_dispatcher` to create a
@@ -248,23 +248,21 @@ class PropDirectoryBacked(Bcfg2.Server.Plugin.DirectoryBacked):
self.__child__ = self.property_dispatcher
__init__.__doc__ = Bcfg2.Server.Plugin.DirectoryBacked.__init__.__doc__
- def property_dispatcher(self, fname, fam):
+ def property_dispatcher(self, fname):
""" Dispatch an event on a Properties file to the
appropriate object.
:param fname: The name of the file that received the event
:type fname: string
- :param fam: The file monitor the event was received by
- :type fam: Bcfg2.Server.FileMonitor.FileMonitor
:returns: An object of the appropriate subclass of
:class:`PropertyFile`
"""
if fname.endswith(".xml"):
- return XMLPropertyFile(fname, fam)
+ return XMLPropertyFile(fname)
elif HAS_JSON and fname.endswith(".json"):
- return JSONPropertyFile(fname, fam)
+ return JSONPropertyFile(fname)
elif HAS_YAML and (fname.endswith(".yaml") or fname.endswith(".yml")):
- return YAMLPropertyFile(fname, fam)
+ return YAMLPropertyFile(fname)
else:
raise Bcfg2.Server.Plugin.PluginExecutionError(
"Properties: Unknown extension %s" % fname)
@@ -279,7 +277,7 @@ class Properties(Bcfg2.Server.Plugin.Plugin,
Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore)
Bcfg2.Server.Plugin.Connector.__init__(self)
try:
- self.store = PropDirectoryBacked(self.data, core.fam)
+ self.store = PropDirectoryBacked(self.data)
except OSError:
err = sys.exc_info()[1]
self.logger.error("Error while creating Properties store: %s" %
diff --git a/src/lib/Bcfg2/Server/Plugins/PuppetENC.py b/src/lib/Bcfg2/Server/Plugins/PuppetENC.py
index 801e7006d..221f49e3c 100644
--- a/src/lib/Bcfg2/Server/Plugins/PuppetENC.py
+++ b/src/lib/Bcfg2/Server/Plugins/PuppetENC.py
@@ -35,8 +35,7 @@ class PuppetENC(Bcfg2.Server.Plugin.Plugin,
Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore)
Bcfg2.Server.Plugin.Connector.__init__(self)
Bcfg2.Server.Plugin.ClientRunHooks.__init__(self)
- Bcfg2.Server.Plugin.DirectoryBacked.__init__(self, self.data,
- self.core.fam)
+ Bcfg2.Server.Plugin.DirectoryBacked.__init__(self, self.data)
self.cache = dict()
def _run_encs(self, metadata):
diff --git a/src/lib/Bcfg2/Server/Plugins/SSHbase.py b/src/lib/Bcfg2/Server/Plugins/SSHbase.py
index c7db67301..7b6c9c418 100644
--- a/src/lib/Bcfg2/Server/Plugins/SSHbase.py
+++ b/src/lib/Bcfg2/Server/Plugins/SSHbase.py
@@ -135,7 +135,8 @@ class SSHbase(Bcfg2.Server.Plugin.Plugin,
# do so once
self.badnames = dict()
- core.fam.AddMonitor(self.data, self)
+ self.fam = Bcfg2.Server.FileMonitor.get_fam()
+ self.fam.AddMonitor(self.data, self)
self.static = dict()
self.entries = dict()
@@ -256,7 +257,7 @@ class SSHbase(Bcfg2.Server.Plugin.Plugin,
self.skn = False
return
- if event.filename in ['info', 'info.xml', ':info']:
+ if event.filename == 'info.xml':
for entry in list(self.entries.values()):
entry.handle_event(event)
return
@@ -368,7 +369,7 @@ class SSHbase(Bcfg2.Server.Plugin.Plugin,
msg = "%s still not registered" % filename
self.logger.error(msg)
raise Bcfg2.Server.Plugin.PluginExecutionError(msg)
- self.core.fam.handle_events_in_interval(1)
+ self.fam.handle_events_in_interval(1)
tries += 1
try:
self.entries[entry.get('name')].bind_entry(entry, metadata)
diff --git a/src/lib/Bcfg2/Server/Plugins/Snapshots.py b/src/lib/Bcfg2/Server/Plugins/Snapshots.py
deleted file mode 100644
index cc5946bb2..000000000
--- a/src/lib/Bcfg2/Server/Plugins/Snapshots.py
+++ /dev/null
@@ -1,129 +0,0 @@
-import logging
-import difflib
-import Bcfg2.Server.Plugin
-import Bcfg2.Server.Snapshots
-import Bcfg2.Logger
-from Bcfg2.Server.Snapshots.model import Snapshot
-import sys
-import time
-import threading
-
-# Compatibility import
-from Bcfg2.Compat import Queue, u_str, b64decode
-
-logger = logging.getLogger('Snapshots')
-
-ftypes = ['ConfigFile', 'SymLink', 'Directory']
-datafields = {
- 'Package': ['version'],
- 'Path': ['type'],
- 'Service': ['status'],
- 'ConfigFile': ['owner', 'group', 'mode'],
- 'Directory': ['owner', 'group', 'mode'],
- 'SymLink': ['to'],
- }
-
-
-def build_snap_ent(entry):
- basefields = []
- if entry.tag in ['Package', 'Service']:
- basefields += ['type']
- desired = dict([(key, u_str(entry.get(key))) for key in basefields])
- state = dict([(key, u_str(entry.get(key))) for key in basefields])
- desired.update([(key, u_str(entry.get(key))) for key in \
- datafields[entry.tag]])
- if entry.tag == 'ConfigFile' or \
- ((entry.tag == 'Path') and (entry.get('type') == 'file')):
- if entry.text == None:
- desired['contents'] = None
- else:
- if entry.get('encoding', 'ascii') == 'ascii':
- desired['contents'] = u_str(entry.text)
- else:
- desired['contents'] = u_str(b64decode(entry.text))
-
- if 'current_bfile' in entry.attrib:
- state['contents'] = u_str(b64decode(entry.get('current_bfile')))
- elif 'current_bdiff' in entry.attrib:
- diff = b64decode(entry.get('current_bdiff'))
- state['contents'] = u_str( \
- '\n'.join(difflib.restore(diff.split('\n'), 1)))
-
- state.update([(key, u_str(entry.get('current_' + key, entry.get(key)))) \
- for key in datafields[entry.tag]])
- if entry.tag in ['ConfigFile', 'Path'] and entry.get('exists', 'true') == 'false':
- state = None
- return [desired, state]
-
-
-class Snapshots(Bcfg2.Server.Plugin.Statistics):
- name = 'Snapshots'
- deprecated = True
-
- def __init__(self, core, datastore):
- Bcfg2.Server.Plugin.Statistics.__init__(self, core, datastore)
- self.session = Bcfg2.Server.Snapshots.setup_session(core.cfile)
- self.work_queue = Queue()
- self.loader = threading.Thread(target=self.load_snapshot)
-
- def start_threads(self):
- self.loader.start()
-
- def load_snapshot(self):
- while self.running:
- try:
- (metadata, data) = self.work_queue.get(block=True, timeout=5)
- except:
- continue
- self.statistics_from_old_stats(metadata, data)
-
- def process_statistics(self, metadata, data):
- return self.work_queue.put((metadata, data))
-
- def statistics_from_old_stats(self, metadata, xdata):
- # entries are name -> (modified, correct, start, desired, end)
- # not sure we can get all of this from old format stats
- t1 = time.time()
- entries = dict([('Package', dict()),
- ('Service', dict()), ('Path', dict())])
- extra = dict([('Package', dict()), ('Service', dict()),
- ('Path', dict())])
- bad = []
- state = xdata.find('.//Statistics')
- correct = state.get('state') == 'clean'
- revision = u_str(state.get('revision', '-1'))
- for entry in state.find('.//Bad'):
- data = [False, False, u_str(entry.get('name'))] \
- + build_snap_ent(entry)
- if entry.tag in ftypes:
- etag = 'Path'
- else:
- etag = entry.tag
- entries[etag][entry.get('name')] = data
- for entry in state.find('.//Modified'):
- if entry.tag in ftypes:
- etag = 'Path'
- else:
- etag = entry.tag
- if entry.get('name') in entries[etag]:
- data = [True, False, u_str(entry.get('name'))] + \
- build_snap_ent(entry)
- else:
- data = [True, False, u_str(entry.get('name'))] + \
- build_snap_ent(entry)
- for entry in state.find('.//Extra'):
- if entry.tag in datafields:
- data = build_snap_ent(entry)[1]
- ename = u_str(entry.get('name'))
- data['name'] = ename
- extra[entry.tag][ename] = data
- else:
- print("extra", entry.tag, entry.get('name'))
- t2 = time.time()
- snap = Snapshot.from_data(self.session, correct, revision,
- metadata, entries, extra)
- self.session.add(snap)
- self.session.commit()
- t3 = time.time()
- logger.info("Snapshot storage took %fs" % (t3 - t2))
- return True
diff --git a/src/lib/Bcfg2/Server/Plugins/Statistics.py b/src/lib/Bcfg2/Server/Plugins/Statistics.py
deleted file mode 100644
index 7fae445d0..000000000
--- a/src/lib/Bcfg2/Server/Plugins/Statistics.py
+++ /dev/null
@@ -1,160 +0,0 @@
-'''This file manages the statistics collected by the BCFG2 Server'''
-
-import copy
-import difflib
-import logging
-import lxml.etree
-import os
-import sys
-from time import asctime, localtime, time, strptime, mktime
-import threading
-from Bcfg2.Compat import b64decode
-import Bcfg2.Server.Plugin
-
-
-class StatisticsStore(object):
- """Manages the memory and file copy of statistics collected about client runs."""
- __min_write_delay__ = 0
-
- def __init__(self, filename):
- self.filename = filename
- self.element = lxml.etree.Element('Dummy')
- self.dirty = 0
- self.lastwrite = 0
- self.logger = logging.getLogger('Bcfg2.Server.Statistics')
- self.ReadFromFile()
-
- def WriteBack(self, force=0):
- """Write statistics changes back to persistent store."""
- if (self.dirty and (self.lastwrite + self.__min_write_delay__ <= time())) \
- or force:
- try:
- fout = open(self.filename + '.new', 'w')
- except IOError:
- ioerr = sys.exc_info()[1]
- self.logger.error("Failed to open %s for writing: %s" % (self.filename + '.new', ioerr))
- else:
- fout.write(lxml.etree.tostring(self.element,
- xml_declaration=False).decode('UTF-8'))
- fout.close()
- os.rename(self.filename + '.new', self.filename)
- self.dirty = 0
- self.lastwrite = time()
-
- def ReadFromFile(self):
- """Reads current state regarding statistics."""
- try:
- fin = open(self.filename, 'r')
- data = fin.read()
- fin.close()
- self.element = lxml.etree.XML(data)
- self.dirty = 0
- except (IOError, lxml.etree.XMLSyntaxError):
- self.logger.error("Creating new statistics file %s"%(self.filename))
- self.element = lxml.etree.Element('ConfigStatistics')
- self.WriteBack()
- self.dirty = 0
-
- def updateStats(self, xml, client):
- """Updates the statistics of a current node with new data."""
-
- # Current policy:
- # - Keep anything less than 24 hours old
- # - Keep latest clean run for clean nodes
- # - Keep latest clean and dirty run for dirty nodes
- newstat = xml.find('Statistics')
-
- if newstat.get('state') == 'clean':
- node_dirty = 0
- else:
- node_dirty = 1
-
- # Find correct node entry in stats data
- # The following list comprehension should be guarenteed to return at
- # most one result
- nodes = [elem for elem in self.element.findall('Node') \
- if elem.get('name') == client]
- nummatch = len(nodes)
- if nummatch == 0:
- # Create an entry for this node
- node = lxml.etree.SubElement(self.element, 'Node', name=client)
- elif nummatch == 1 and not node_dirty:
- # Delete old instance
- node = nodes[0]
- [node.remove(elem) for elem in node.findall('Statistics') \
- if self.isOlderThan24h(elem.get('time'))]
- elif nummatch == 1 and node_dirty:
- # Delete old dirty statistics entry
- node = nodes[0]
- [node.remove(elem) for elem in node.findall('Statistics') \
- if (elem.get('state') == 'dirty' \
- and self.isOlderThan24h(elem.get('time')))]
- else:
- # Shouldn't be reached
- self.logger.error("Duplicate node entry for %s"%(client))
-
- # Set current time for stats
- newstat.set('time', asctime(localtime()))
-
- # Add statistic
- node.append(copy.copy(newstat))
-
- # Set dirty
- self.dirty = 1
- self.WriteBack(force=1)
-
- def isOlderThan24h(self, testTime):
- """Helper function to determine if <time> string is older than 24 hours."""
- now = time()
- utime = mktime(strptime(testTime))
- secondsPerDay = 60*60*24
-
- return (now-utime) > secondsPerDay
-
-
-class Statistics(Bcfg2.Server.Plugin.ThreadedStatistics,
- Bcfg2.Server.Plugin.PullSource):
- name = 'Statistics'
- deprecated = True
-
- def __init__(self, core, datastore):
- Bcfg2.Server.Plugin.ThreadedStatistics.__init__(self, core, datastore)
- Bcfg2.Server.Plugin.PullSource.__init__(self)
- fpath = "%s/etc/statistics.xml" % datastore
- self.data_file = StatisticsStore(fpath)
-
- def handle_statistic(self, metadata, data):
- self.data_file.updateStats(data, metadata.hostname)
-
- def FindCurrent(self, client):
- rt = self.data_file.element.xpath('//Node[@name="%s"]' % client)[0]
- maxtime = max([strptime(stat.get('time')) for stat \
- in rt.findall('Statistics')])
- return [stat for stat in rt.findall('Statistics') \
- if strptime(stat.get('time')) == maxtime][0]
-
- def GetExtra(self, client):
- return [(entry.tag, entry.get('name')) for entry \
- in self.FindCurrent(client).xpath('.//Extra/*')]
-
- def GetCurrentEntry(self, client, e_type, e_name):
- curr = self.FindCurrent(client)
- entry = curr.xpath('.//Bad/%s[@name="%s"]' % (e_type, e_name))
- if not entry:
- raise Bcfg2.Server.Plugin.PluginExecutionError
- cfentry = entry[-1]
-
- owner = cfentry.get('current_owner', cfentry.get('owner'))
- group = cfentry.get('current_group', cfentry.get('group'))
- mode = cfentry.get('current_mode', cfentry.get('mode'))
- if cfentry.get('sensitive') in ['true', 'True']:
- raise Bcfg2.Server.Plugin.PluginExecutionError
- elif 'current_bfile' in cfentry.attrib:
- contents = b64decode(cfentry.get('current_bfile'))
- elif 'current_bdiff' in cfentry.attrib:
- diff = b64decode(cfentry.get('current_bdiff'))
- contents = '\n'.join(difflib.restore(diff.split('\n'), 1))
- else:
- contents = None
-
- return (owner, group, mode, contents)
diff --git a/src/lib/Bcfg2/Server/Plugins/TCheetah.py b/src/lib/Bcfg2/Server/Plugins/TCheetah.py
deleted file mode 100644
index f2c59ce29..000000000
--- a/src/lib/Bcfg2/Server/Plugins/TCheetah.py
+++ /dev/null
@@ -1,79 +0,0 @@
-'''This module implements a templating generator based on Cheetah'''
-
-import logging
-import sys
-import traceback
-import Bcfg2.Server.Plugin
-
-from Bcfg2.Compat import unicode, b64encode
-
-logger = logging.getLogger('Bcfg2.Plugins.TCheetah')
-
-try:
- import Cheetah.Template
- import Cheetah.Parser
-except:
- logger.error("TCheetah: Failed to import Cheetah. Is it installed?")
- raise
-
-
-class TemplateFile:
- """Template file creates Cheetah template structures for the loaded file."""
-
- def __init__(self, name, specific, encoding):
- self.name = name
- self.specific = specific
- self.encoding = encoding
- self.template = None
- self.searchlist = dict()
-
- def handle_event(self, event):
- """Handle all fs events for this template."""
- if event.code2str() == 'deleted':
- return
- try:
- s = {'useStackFrames': False}
- self.template = Cheetah.Template.Template(open(self.name).read(),
- compilerSettings=s,
- searchList=self.searchlist)
- except Cheetah.Parser.ParseError:
- perror = sys.exc_info()[1]
- logger.error("Cheetah parse error for file %s" % (self.name))
- logger.error(perror.report())
-
- def bind_entry(self, entry, metadata):
- """Build literal file information."""
- self.template.metadata = metadata
- self.searchlist['metadata'] = metadata
- self.template.path = entry.get('realname', entry.get('name'))
- self.searchlist['path'] = entry.get('realname', entry.get('name'))
- self.template.source_path = self.name
- self.searchlist['source_path'] = self.name
-
- if entry.tag == 'Path':
- entry.set('type', 'file')
- try:
- if type(self.template) == unicode:
- entry.text = self.template
- else:
- if entry.get('encoding') == 'base64':
- # take care of case where file needs base64 encoding
- entry.text = b64encode(self.template)
- else:
- entry.text = unicode(str(self.template), self.encoding)
- except:
- (a, b, c) = sys.exc_info()
- msg = traceback.format_exception(a, b, c, limit=2)[-1][:-1]
- logger.error(msg)
- logger.error("TCheetah template error for %s" % self.searchlist['path'])
- del a, b, c
- raise Bcfg2.Server.Plugin.PluginExecutionError
-
-
-class TCheetah(Bcfg2.Server.Plugin.GroupSpool):
- """The TCheetah generator implements a templating mechanism for configuration files."""
- name = 'TCheetah'
- __author__ = 'bcfg-dev@mcs.anl.gov'
- filename_pattern = 'template'
- es_child_cls = TemplateFile
- deprecated = True
diff --git a/src/lib/Bcfg2/Server/Plugins/TGenshi.py b/src/lib/Bcfg2/Server/Plugins/TGenshi.py
deleted file mode 100644
index 809587d91..000000000
--- a/src/lib/Bcfg2/Server/Plugins/TGenshi.py
+++ /dev/null
@@ -1,139 +0,0 @@
-"""This module implements a templating generator based on Genshi."""
-
-import logging
-import sys
-import Bcfg2.Server.Plugin
-
-from Bcfg2.Compat import unicode, b64encode
-
-logger = logging.getLogger('Bcfg2.Plugins.TGenshi')
-
-# try to import genshi stuff
-try:
- import genshi.core
- import genshi.input
- from genshi.template import TemplateLoader, \
- TextTemplate, MarkupTemplate, TemplateError
-except ImportError:
- logger.error("TGenshi: Failed to import Genshi. Is it installed?")
- raise
-try:
- from genshi.template import NewTextTemplate
- have_ntt = True
-except:
- have_ntt = False
-
-def removecomment(stream):
- """A genshi filter that removes comments from the stream."""
- for kind, data, pos in stream:
- if kind is genshi.core.COMMENT:
- continue
- yield kind, data, pos
-
-
-class TemplateFile(object):
- """Template file creates Genshi template structures for the loaded file."""
-
- def __init__(self, name, specific, encoding):
- self.name = name
- self.specific = specific
- self.encoding = encoding
- if self.specific.all:
- matchname = self.name
- elif self.specific.group:
- matchname = self.name[:self.name.find('.G')]
- else:
- matchname = self.name[:self.name.find('.H')]
- if matchname.endswith('.txt'):
- self.template_cls = TextTemplate
- elif matchname.endswith('.newtxt'):
- if not have_ntt:
- logger.error("Genshi NewTextTemplates not supported by this version of Genshi")
- else:
- self.template_cls = NewTextTemplate
- else:
- self.template_cls = MarkupTemplate
- self.HandleEvent = self.handle_event
-
- def handle_event(self, event=None):
- """Handle all fs events for this template."""
- if event and event.code2str() == 'deleted':
- return
- try:
- loader = TemplateLoader()
- try:
- self.template = loader.load(self.name, cls=self.template_cls,
- encoding=self.encoding)
- except LookupError:
- lerror = sys.exc_info()[1]
- logger.error('Genshi lookup error: %s' % lerror)
- except TemplateError:
- terror = sys.exc_info()[1]
- logger.error('Genshi template error: %s' % terror)
- except genshi.input.ParseError:
- perror = sys.exc_info()[1]
- logger.error('Genshi parse error: %s' % perror)
-
- def bind_entry(self, entry, metadata):
- """Build literal file information."""
- fname = entry.get('realname', entry.get('name'))
- if entry.tag == 'Path':
- entry.set('type', 'file')
- try:
- stream = self.template.generate( \
- name=fname, metadata=metadata,
- path=self.name).filter(removecomment)
- if have_ntt:
- ttypes = [TextTemplate, NewTextTemplate]
- else:
- ttypes = [TextTemplate]
- if True in [isinstance(self.template, t) for t in ttypes]:
- try:
- textdata = stream.render('text', strip_whitespace=False)
- except TypeError:
- textdata = stream.render('text')
- if type(textdata) == unicode:
- entry.text = textdata
- else:
- if entry.get('encoding') == 'base64':
- # take care of case where file needs base64 encoding
- entry.text = b64encode(textdata)
- else:
- entry.text = unicode(textdata, self.encoding)
- else:
- try:
- xmldata = stream.render('xml', strip_whitespace=False)
- except TypeError:
- xmldata = stream.render('xml')
- if type(xmldata) == unicode:
- entry.text = xmldata
- else:
- entry.text = unicode(xmldata, self.encoding)
- if entry.text == '':
- entry.set('empty', 'true')
- except TemplateError:
- err = sys.exc_info()[1]
- logger.exception('Genshi template error')
- raise Bcfg2.Server.Plugin.PluginExecutionError('Genshi template error: %s' % err)
- except AttributeError:
- err = sys.exc_info()[1]
- logger.exception('Genshi template loading error')
- raise Bcfg2.Server.Plugin.PluginExecutionError('Genshi template loading error: %s' % err)
-
-
-class TemplateEntrySet(Bcfg2.Server.Plugin.EntrySet):
- basename_is_regex = True
-
-
-class TGenshi(Bcfg2.Server.Plugin.GroupSpool):
- """
- The TGenshi generator implements a templating
- mechanism for configuration files.
-
- """
- name = 'TGenshi'
- __author__ = 'jeff@ocjtech.us'
- filename_pattern = 'template\.(txt|newtxt|xml)'
- es_cls = TemplateEntrySet
- es_child_cls = TemplateFile
- deprecated = True
diff --git a/src/lib/Bcfg2/Server/Plugins/TemplateHelper.py b/src/lib/Bcfg2/Server/Plugins/TemplateHelper.py
index 9c8314f50..e3f8ed749 100644
--- a/src/lib/Bcfg2/Server/Plugins/TemplateHelper.py
+++ b/src/lib/Bcfg2/Server/Plugins/TemplateHelper.py
@@ -15,9 +15,8 @@ MODULE_RE = re.compile(r'(?P<filename>(?P<module>[^\/]+)\.py)$')
class HelperModule(object):
""" Representation of a TemplateHelper module """
- def __init__(self, name, fam=None):
+ def __init__(self, name):
self.name = name
- self.fam = fam
self._module_name = MODULE_RE.search(self.name).group('module')
self._attrs = []
@@ -75,7 +74,7 @@ class TemplateHelper(Bcfg2.Server.Plugin.Plugin,
def __init__(self, core, datastore):
Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore)
Bcfg2.Server.Plugin.Connector.__init__(self)
- Bcfg2.Server.Plugin.DirectoryBacked.__init__(self, self.data, core.fam)
+ Bcfg2.Server.Plugin.DirectoryBacked.__init__(self, self.data)
def get_additional_data(self, _):
return dict([(h._module_name, h) # pylint: disable=W0212
diff --git a/src/lib/Bcfg2/Server/Plugins/Trigger.py b/src/lib/Bcfg2/Server/Plugins/Trigger.py
index f7c82fdb3..878bf9cea 100644
--- a/src/lib/Bcfg2/Server/Plugins/Trigger.py
+++ b/src/lib/Bcfg2/Server/Plugins/Trigger.py
@@ -25,8 +25,7 @@ class Trigger(Bcfg2.Server.Plugin.Plugin,
def __init__(self, core, datastore):
Bcfg2.Server.Plugin.Plugin.__init__(self, core, datastore)
Bcfg2.Server.Plugin.ClientRunHooks.__init__(self)
- Bcfg2.Server.Plugin.DirectoryBacked.__init__(self, self.data,
- self.core.fam)
+ Bcfg2.Server.Plugin.DirectoryBacked.__init__(self, self.data)
def async_run(self, args):
""" Run the trigger script asynchronously in a forked process
diff --git a/src/lib/Bcfg2/Server/Plugins/__init__.py b/src/lib/Bcfg2/Server/Plugins/__init__.py
index b33eeba28..1f85702f0 100644
--- a/src/lib/Bcfg2/Server/Plugins/__init__.py
+++ b/src/lib/Bcfg2/Server/Plugins/__init__.py
@@ -1,32 +1 @@
-"""Imports for Bcfg2.Server.Plugins."""
-
-__all__ = [
- 'Account',
- 'Base',
- 'Bundler',
- 'Bzr',
- 'Cfg',
- 'Cvs',
- 'Darcs',
- 'Decisions',
- 'Fossil',
- 'Git',
- 'GroupPatterns',
- 'Hg',
- 'Hostbase',
- 'Metadata',
- 'NagiosGen',
- 'Ohai',
- 'Packages',
- 'Properties',
- 'Probes',
- 'Pkgmgr',
- 'Rules',
- 'SSHbase',
- 'Snapshots',
- 'Statistics',
- 'Svn',
- 'TCheetah',
- 'Trigger',
- 'TGenshi',
- ]
+""" Bcfg2 Plugins """
diff --git a/src/lib/Bcfg2/Server/Snapshots/__init__.py b/src/lib/Bcfg2/Server/Snapshots/__init__.py
deleted file mode 100644
index d42aa0525..000000000
--- a/src/lib/Bcfg2/Server/Snapshots/__init__.py
+++ /dev/null
@@ -1,31 +0,0 @@
-__all__ = ['models', 'db_from_config', 'setup_session']
-
-import sqlalchemy
-import sqlalchemy.orm
-# Compatibility import
-from Bcfg2.Compat import ConfigParser
-
-
-def db_from_config(cfile):
- cp = ConfigParser.ConfigParser()
- cp.read([cfile])
- driver = cp.get('snapshots', 'driver')
- if driver == 'sqlite':
- path = cp.get('snapshots', 'database')
- return 'sqlite:///%s' % path
- elif driver in ['mysql', 'postgres']:
- user = cp.get('snapshots', 'user')
- password = cp.get('snapshots', 'password')
- host = cp.get('snapshots', 'host')
- db = cp.get('snapshots', 'database')
- return '%s://%s:%s@%s/%s' % (driver, user, password, host, db)
- else:
- raise Exception("unsupported db driver %s" % driver)
-
-
-def setup_session(cfile, debug=False):
- engine = sqlalchemy.create_engine(db_from_config(cfile),
- echo=debug)
- Session = sqlalchemy.orm.sessionmaker()
- Session.configure(bind=engine)
- return Session()
diff --git a/src/lib/Bcfg2/Server/Snapshots/model.py b/src/lib/Bcfg2/Server/Snapshots/model.py
deleted file mode 100644
index d578cd2c0..000000000
--- a/src/lib/Bcfg2/Server/Snapshots/model.py
+++ /dev/null
@@ -1,323 +0,0 @@
-import sys
-from sqlalchemy import Table, Column, Integer, Unicode, ForeignKey, Boolean, \
- DateTime, UnicodeText, desc
-import datetime
-import sqlalchemy.exceptions
-from sqlalchemy.orm import relation, backref
-from sqlalchemy.ext.declarative import declarative_base
-
-from Bcfg2.Compat import u_str
-
-
-class Uniquer(object):
- force_rt = True
-
- @classmethod
- def by_value(cls, session, **kwargs):
- if cls.force_rt:
- try:
- return session.query(cls).filter_by(**kwargs).one()
- except sqlalchemy.exceptions.InvalidRequestError:
- return cls(**kwargs)
- else:
- return cls(**kwargs)
-
- @classmethod
- def from_record(cls, session, data):
- return cls.by_value(session, **data)
-
-Base = declarative_base()
-
-
-class Administrator(Uniquer, Base):
- __tablename__ = 'administrator'
- id = Column(Integer, primary_key=True)
- name = Column(Unicode(20), unique=True)
- email = Column(Unicode(64))
-
-admin_client = Table('admin_client', Base.metadata,
- Column('admin_id',
- Integer,
- ForeignKey('administrator.id')),
- Column('client_id',
- Integer,
- ForeignKey('client.id')))
-
-admin_group = Table('admin_group', Base.metadata,
- Column('admin_id',
- Integer,
- ForeignKey('administrator.id')),
- Column('group_id',
- Integer,
- ForeignKey('group.id')))
-
-
-class Client(Uniquer, Base):
- __tablename__ = 'client'
- id = Column(Integer, primary_key=True)
- name = Column(Unicode(64), unique=True)
- admins = relation("Administrator", secondary=admin_client,
- backref='clients')
- active = Column(Boolean, default=True)
- online = Column(Boolean, default=True)
- online_ts = Column(DateTime)
-
-
-class Group(Uniquer, Base):
- __tablename__ = 'group'
- id = Column(Integer, primary_key=True)
- name = Column(Unicode(32), unique=True)
- admins = relation("Administrator", secondary=admin_group,
- backref='groups')
-
-
-class ConnectorKeyVal(Uniquer, Base):
- __tablename__ = 'connkeyval'
- id = Column(Integer, primary_key=True)
- connector = Column(Unicode(16))
- key = Column(Unicode(32))
- value = Column(UnicodeText)
-
-meta_group = Table('meta_group', Base.metadata,
- Column('metadata_id',
- Integer,
- ForeignKey('metadata.id')),
- Column('group_id',
- Integer,
- ForeignKey('group.id')))
-
-meta_conn = Table('meta_conn', Base.metadata,
- Column('metadata_id',
- Integer,
- ForeignKey('metadata.id')),
- Column('connkeyval_id',
- Integer,
- ForeignKey('connkeyval.id')))
-
-
-class Metadata(Base):
- __tablename__ = 'metadata'
- id = Column(Integer, primary_key=True)
- client_id = Column(Integer, ForeignKey('client.id'))
- client = relation(Client)
- groups = relation("Group", secondary=meta_group)
- keyvals = relation(ConnectorKeyVal, secondary=meta_conn)
- timestamp = Column(DateTime)
-
- @classmethod
- def from_metadata(cls, mysession, mymetadata):
- client = Client.by_value(mysession, name=u_str(mymetadata.hostname))
- m = cls(client=client)
- for group in mymetadata.groups:
- m.groups.append(Group.by_value(mysession, name=u_str(group)))
- for connector in mymetadata.connectors:
- data = getattr(mymetadata, connector)
- if not isinstance(data, dict):
- continue
- for key, value in list(data.items()):
- if not isinstance(value, str):
- continue
- m.keyvals.append(ConnectorKeyVal.by_value(mysession,
- connector=u_str(connector),
- key=u_str(key),
- value=u_str(value)))
- return m
-
-
-class Package(Base, Uniquer):
- __tablename__ = 'package'
- id = Column(Integer, primary_key=True)
- name = Column(Unicode(24))
- type = Column(Unicode(16))
- version = Column(Unicode(16))
- verification_status = Column(Boolean)
-
-
-class CorrespondenceType(object):
- mtype = Package
-
- @classmethod
- def from_record(cls, mysession, record):
- (mod, corr, name, s_dict, e_dict) = record
- if not s_dict:
- start = None
- else:
- start = cls.mtype.by_value(mysession, name=name, **s_dict)
- if s_dict != e_dict:
- end = cls.mtype.by_value(mysession, name=name, **e_dict)
- else:
- end = start
- return cls(start=start, end=end, modified=mod, correct=corr)
-
-
-class PackageCorrespondence(Base, CorrespondenceType):
- mtype = Package
- __tablename__ = 'package_pair'
- id = Column(Integer, primary_key=True)
- start_id = Column(Integer, ForeignKey('package.id'))
- start = relation(Package, primaryjoin=start_id == Package.id)
- end_id = Column(Integer, ForeignKey('package.id'), nullable=True)
- end = relation(Package, primaryjoin=end_id == Package.id)
- modified = Column(Boolean)
- correct = Column(Boolean)
-
-package_snap = Table('package_snap', Base.metadata,
- Column('ppair_id',
- Integer,
- ForeignKey('package_pair.id')),
- Column('snapshot_id',
- Integer,
- ForeignKey('snapshot.id')))
-
-
-class Service(Base, Uniquer):
- __tablename__ = 'service'
- id = Column(Integer, primary_key=True)
- name = Column(Unicode(16))
- type = Column(Unicode(12))
- status = Column(Boolean)
-
-
-class ServiceCorrespondence(Base, CorrespondenceType):
- mtype = Service
- __tablename__ = 'service_pair'
- id = Column(Integer, primary_key=True)
- start_id = Column(Integer, ForeignKey('service.id'))
- start = relation(Service, primaryjoin=start_id == Service.id)
- end_id = Column(Integer, ForeignKey('service.id'), nullable=True)
- end = relation(Service, primaryjoin=end_id == Service.id)
- modified = Column(Boolean)
- correct = Column(Boolean)
-
-service_snap = Table('service_snap', Base.metadata,
- Column('spair_id',
- Integer,
- ForeignKey('service_pair.id')),
- Column('snapshot_id',
- Integer,
- ForeignKey('snapshot.id')))
-
-
-class File(Base, Uniquer):
- __tablename__ = 'file'
- id = Column(Integer, primary_key=True)
- name = Column(UnicodeText)
- type = Column(Unicode(12))
- owner = Column(Unicode(12))
- group = Column(Unicode(16))
- perms = Column(Integer)
- contents = Column(UnicodeText)
-
-
-class FileCorrespondence(Base, CorrespondenceType):
- mtype = File
- __tablename__ = 'file_pair'
- id = Column(Integer, primary_key=True)
- start_id = Column(Integer, ForeignKey('file.id'))
- start = relation(File, primaryjoin=start_id == File.id)
- end_id = Column(Integer, ForeignKey('file.id'), nullable=True)
- end = relation(File, primaryjoin=end_id == File.id)
- modified = Column(Boolean)
- correct = Column(Boolean)
-
-file_snap = Table('file_snap', Base.metadata,
- Column('fpair_id',
- Integer,
- ForeignKey('file_pair.id')),
- Column('snapshot_id',
- Integer,
- ForeignKey('snapshot.id')))
-
-extra_pkg_snap = Table('extra_pkg_snap', Base.metadata,
- Column('package_id',
- Integer,
- ForeignKey('package.id')),
- Column('snapshot_id',
- Integer,
- ForeignKey('snapshot.id')))
-
-extra_file_snap = Table('extra_file_snap', Base.metadata,
- Column('file_id',
- Integer,
- ForeignKey('file.id')),
- Column('snapshot_id',
- Integer,
- ForeignKey('snapshot.id')))
-
-extra_service_snap = Table('extra_service_snap', Base.metadata,
- Column('service_id',
- Integer,
- ForeignKey('service.id')),
- Column('snapshot_id',
- Integer,
- ForeignKey('snapshot.id')))
-
-
-class Action(Base):
- __tablename__ = 'action'
- id = Column(Integer, primary_key=True)
- command = Column(UnicodeText)
- return_code = Column(Integer)
- output = Column(UnicodeText)
-
-action_snap = Table('action_snap', Base.metadata,
- Column('action_id', Integer, ForeignKey('action.id')),
- Column('snapshot_id', Integer, ForeignKey('snapshot.id')))
-
-
-class Snapshot(Base):
- __tablename__ = 'snapshot'
- id = Column(Integer, primary_key=True)
- correct = Column(Boolean)
- revision = Column(Unicode(36))
- metadata_id = Column(Integer, ForeignKey('metadata.id'))
- client_metadata = relation(Metadata, primaryjoin=metadata_id == Metadata.id)
- timestamp = Column(DateTime, default=datetime.datetime.now)
- client_id = Column(Integer, ForeignKey('client.id'))
- client = relation(Client, backref=backref('snapshots'))
- packages = relation(PackageCorrespondence, secondary=package_snap)
- services = relation(ServiceCorrespondence, secondary=service_snap)
- files = relation(FileCorrespondence, secondary=file_snap)
- actions = relation(Action, secondary=action_snap)
- extra_packages = relation(Package, secondary=extra_pkg_snap)
- extra_services = relation(Service, secondary=extra_service_snap)
- extra_files = relation(File, secondary=extra_file_snap)
-
- c_dispatch = dict([('Package', ('packages', PackageCorrespondence)),
- ('Service', ('services', ServiceCorrespondence)),
- ('Path', ('files', FileCorrespondence))])
- e_dispatch = dict([('Package', ('extra_packages', Package)),
- ('Service', ('extra_services', Service)),
- ('Path', ('extra_files', File))])
-
- @classmethod
- def from_data(cls, session, correct, revision, metadata, entries, extra):
- dbm = Metadata.from_metadata(session, metadata)
- snap = cls(correct=correct, client_metadata=dbm, revision=revision,
- timestamp=datetime.datetime.now(), client=dbm.client)
- for (dispatch, data) in [(cls.c_dispatch, entries),
- (cls.e_dispatch, extra)]:
- for key in dispatch:
- dest, ecls = dispatch[key]
- for edata in list(data[key].values()):
- getattr(snap, dest).append(ecls.from_record(session, edata))
- return snap
-
- @classmethod
- def by_client(cls, session, clientname):
- return session.query(cls).join(cls.client_metadata,
- Metadata.client).filter(Client.name == clientname)
-
- @classmethod
- def get_current(cls, session, clientname):
- return session.query(Snapshot).join(Snapshot.client_metadata,
- Metadata.client).filter(Client.name == clientname).order_by(desc(Snapshot.timestamp)).first()
-
- @classmethod
- def get_by_date(cls, session, clientname, timestamp):
- return session.query(Snapshot)\
- .join(Snapshot.client_metadata, Metadata.client)\
- .filter(Snapshot.timestamp < timestamp)\
- .filter(Client.name == clientname)\
- .order_by(desc(Snapshot.timestamp))\
- .first()
diff --git a/src/lib/Bcfg2/Server/__init__.py b/src/lib/Bcfg2/Server/__init__.py
index 3eb300a98..bcf3b4dea 100644
--- a/src/lib/Bcfg2/Server/__init__.py
+++ b/src/lib/Bcfg2/Server/__init__.py
@@ -3,8 +3,7 @@
import lxml.etree
__all__ = ["Admin", "Core", "FileMonitor", "Plugin", "Plugins",
- "Hostbase", "Reports", "Snapshots", "XMLParser",
- "XI", "XI_NAMESPACE"]
+ "Reports", "XMLParser", "XI", "XI_NAMESPACE"]
XI = 'http://www.w3.org/2001/XInclude'
XI_NAMESPACE = '{%s}' % XI
diff --git a/src/lib/Bcfg2/Server/models.py b/src/lib/Bcfg2/Server/models.py
index 4ac2be43b..11d85c248 100644
--- a/src/lib/Bcfg2/Server/models.py
+++ b/src/lib/Bcfg2/Server/models.py
@@ -5,6 +5,7 @@ import copy
import logging
import Bcfg2.Options
import Bcfg2.Server.Plugins
+from Bcfg2.Compat import walk_packages
from django.db import models
LOGGER = logging.getLogger('Bcfg2.Server.models')
@@ -21,7 +22,18 @@ def load_models(plugins=None, cfile='/etc/bcfg2.conf', quiet=True):
# namely, _all_ plugins, so that the database is guaranteed to
# work, even if /etc/bcfg2.conf isn't set up properly
plugin_opt = copy.deepcopy(Bcfg2.Options.SERVER_PLUGINS)
- plugin_opt.default = Bcfg2.Server.Plugins.__all__
+ all_plugins = []
+ for submodule in walk_packages(path=Bcfg2.Server.Plugins.__path__,
+ prefix="Bcfg2.Server.Plugins."):
+ module = submodule[1].rsplit('.', 1)[-1]
+ if submodule[1] == "Bcfg2.Server.Plugins.%s" % module:
+ # we only include direct children of
+ # Bcfg2.Server.Plugins -- e.g., all_plugins should
+ # include Bcfg2.Server.Plugins.Cfg, but not
+ # Bcfg2.Server.Plugins.Cfg.CfgInfoXML
+ all_plugins.append(module)
+ plugin_opt.default = all_plugins
+
setup = Bcfg2.Options.get_option_parser()
setup.add_option("plugins", plugin_opt)
setup.add_option("configfile", Bcfg2.Options.CFILE)