summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--debian/bcfg2-server.install1
-rw-r--r--debian/bcfg2-server.logcheck.ignore.server2
-rw-r--r--doc/appendix/contributors.txt2
-rw-r--r--doc/appendix/files/mysql.txt2
-rw-r--r--doc/appendix/guides/centos.txt67
-rw-r--r--doc/appendix/guides/fedora.txt18
-rw-r--r--doc/appendix/guides/ubuntu.txt18
-rw-r--r--doc/client/tools.txt14
-rw-r--r--doc/client/tools/yum.txt4
-rw-r--r--doc/development/cfg.txt7
-rw-r--r--doc/development/fam.txt5
-rw-r--r--doc/getting_started/index.txt6
-rw-r--r--doc/help/troubleshooting.txt11
-rw-r--r--doc/installation/distributions.txt2
-rw-r--r--doc/installation/prerequisites.txt4
-rw-r--r--doc/reports/static.txt100
-rw-r--r--doc/server/admin/index.txt1
-rw-r--r--doc/server/admin/snapshots.txt8
-rw-r--r--doc/server/configuration.txt4
-rw-r--r--doc/server/index.txt1
-rw-r--r--doc/server/info.txt22
-rw-r--r--doc/server/plugins/generators/account.txt115
-rw-r--r--doc/server/plugins/generators/cfg.txt77
-rw-r--r--doc/server/plugins/generators/hostbase.txt228
-rw-r--r--doc/server/plugins/generators/packages.txt83
-rw-r--r--doc/server/plugins/generators/tcheetah.txt197
-rw-r--r--doc/server/plugins/generators/tgenshi.txt213
-rw-r--r--doc/server/plugins/statistics/statistics.txt7
-rw-r--r--doc/server/plugins/structures/bundler/kernel.txt2
-rw-r--r--doc/server/snapshots/index.txt156
-rw-r--r--doc/unsorted/index.txt1
-rw-r--r--examples/Cfg/etc/dirvish/master.conf/master.conf.genshi (renamed from examples/TGenshi/etc/dirvish/master.conf/template.newtxt)0
-rw-r--r--examples/TGenshi/etc/motd/template.newtxt31
-rw-r--r--examples/TGenshi/tmp/bar/template.txt19
-rw-r--r--examples/TGenshi/tmp/foo/template.xml46
-rw-r--r--examples/bcfg2.confHostbase33
-rw-r--r--misc/bcfg2.spec1
-rw-r--r--osx/Makefile3
-rw-r--r--osx/macports/files/patch-setup.py.diff11
-rw-r--r--schemas/bundle.xsd14
-rw-r--r--schemas/rules.xsd13
-rwxr-xr-xsetup.py9
-rw-r--r--solaris/prototype.bcfg24
-rw-r--r--solaris/prototype.bcfg2-server10
-rw-r--r--src/lib/Bcfg2/Client/Tools/Action.py19
-rw-r--r--src/lib/Bcfg2/Client/Tools/RPM.py2
-rw-r--r--src/lib/Bcfg2/Client/Tools/RPMng.py9
-rw-r--r--src/lib/Bcfg2/Client/Tools/YUM.py2
-rw-r--r--src/lib/Bcfg2/Client/Tools/YUM24.py404
-rw-r--r--src/lib/Bcfg2/Client/Tools/YUMng.py9
-rw-r--r--src/lib/Bcfg2/Options.py102
-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
-rwxr-xr-xsrc/sbin/bcfg2-build-reports306
-rw-r--r--testsuite/Testsrc/Testlib/TestServer/TestPlugin/Testhelpers.py114
-rw-r--r--testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestMetadata.py82
-rw-r--r--testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestProbes.py17
-rw-r--r--testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestTemplateHelper.py2
-rw-r--r--testsuite/Testsrc/test_code_checks.py20
-rw-r--r--tools/README12
-rwxr-xr-xtools/batchadd.py168
-rwxr-xr-xtools/bcfg2-import-config10
-rwxr-xr-xtools/bcfg2-profile-templates.py62
-rwxr-xr-xtools/hostbase.py79
-rwxr-xr-xtools/hostbasepush.py14
-rwxr-xr-xtools/hostinfo.py197
164 files changed, 441 insertions, 9062 deletions
diff --git a/debian/bcfg2-server.install b/debian/bcfg2-server.install
index 91b1b2aef..eab9cd117 100644
--- a/debian/bcfg2-server.install
+++ b/debian/bcfg2-server.install
@@ -1,7 +1,6 @@
debian/bcfg2-server.default usr/share/bcfg2
debian/tmp/usr/bin/bcfg2-* usr/sbin
debian/tmp/usr/lib/python*/*-packages/Bcfg2/Server/*
-debian/tmp/usr/share/bcfg2/Hostbase/*
debian/tmp/usr/share/bcfg2/schemas/*
debian/tmp/usr/share/bcfg2/xsl-transforms/*
debian/tmp/usr/share/man/man8/*
diff --git a/debian/bcfg2-server.logcheck.ignore.server b/debian/bcfg2-server.logcheck.ignore.server
index 136384f00..be4e45de3 100644
--- a/debian/bcfg2-server.logcheck.ignore.server
+++ b/debian/bcfg2-server.logcheck.ignore.server
@@ -1,4 +1,4 @@
-^\w{3} [ :0-9]{11} [._[:alnum:]-]+ bcfg2-server\[[0-9]+\]: Processed [0-9]+ (fam|gamin) events in [0-9.]+ seconds\. [0-9]+ coalesced$
+^\w{3} [ :0-9]{11} [._[:alnum:]-]+ bcfg2-server\[[0-9]+\]: Handled [0-9]+ events in [0-9.]+
^\w{3} [ :0-9]{11} [._[:alnum:]-]+ bcfg2-server\[[0-9]+\]: Generated config for [._[:alnum:]-]+ in [0-9.]+ s$
^\w{3} [ :0-9]{11} [._[:alnum:]-]+ bcfg2-server\[[0-9]+\]: Client [._[:alnum:]-]+ reported state (clean|dirty)$
^\w{3} [ :0-9]{11} [._[:alnum:]-]+ bcfg2-server\[[0-9]+\]: Suppressing event for bogus file .*$
diff --git a/doc/appendix/contributors.txt b/doc/appendix/contributors.txt
index 1afc62706..9f99d25be 100644
--- a/doc/appendix/contributors.txt
+++ b/doc/appendix/contributors.txt
@@ -35,7 +35,7 @@ In alphabetical order of the given name:
Bcfg client and server and implemented a common logging infrastructure.
- Fabian Affolter <mail@fabian-affolter.ch> made some patches, added
some new features and plugins, and restructured the manual for Bcfg2.
-- Jack Neely <jjneely@ncsu.edu> worked on YUMng.
+- Jack Neely <jjneely@ncsu.edu> worked on YUMng (now YUM).
- James Yang <jjyang@mcs.anl.gov> worked on ``bcfg2-admin`` and
``bcfg2-reports``.
- Jason Pepas <cell@ices.utexas.edu> has written a RPM package list creator
diff --git a/doc/appendix/files/mysql.txt b/doc/appendix/files/mysql.txt
index 81104ec17..6c6c83e3e 100644
--- a/doc/appendix/files/mysql.txt
+++ b/doc/appendix/files/mysql.txt
@@ -17,7 +17,7 @@ I added a new bundle:
<Bundle name="mysql-server" version="3.0">
<Path name="/root/bcfg2-install/mysql/users.sh"/>
<Path name="/root/bcfg2-install/mysql/users.sql"/>
- <PostInstall name="/root/bcfg2-install/mysql/users.sh"/>
+ <Action name="mysql_users"/>
<Package name="mysql-server-4.1"/>
<Service name="mysql"/>
</Bundle>
diff --git a/doc/appendix/guides/centos.txt b/doc/appendix/guides/centos.txt
index 5a2d1bed0..afec18ff5 100644
--- a/doc/appendix/guides/centos.txt
+++ b/doc/appendix/guides/centos.txt
@@ -102,7 +102,7 @@ Run bcfg2 to be sure you are able to communicate with the server::
Excluding Packages in global exclude list
Finished
Loaded tool drivers:
- Action Chkconfig POSIX YUMng
+ Action Chkconfig POSIX YUM
Phase: initial
Correct entries: 0
@@ -147,7 +147,7 @@ Now if you run the client, no more warning::
Excluding Packages in global exclude list
Finished
Loaded tool drivers:
- Action Chkconfig POSIX YUMng
+ Action Chkconfig POSIX YUM
Phase: initial
Correct entries: 0
@@ -176,7 +176,7 @@ First, replace **Pkgmgr** with **Packages** in the plugins
line of ``bcfg2.conf``. Then create Packages layout (as per
:ref:`packages-exampleusage`) in ``/var/lib/bcfg2``
-.. note:: I am using the RawURL syntax here since we are using `mrepo`_
+.. note:: I am using the rawurl syntax here since we are using `mrepo`_
to manage our yum mirrors.
.. _mrepo: http://dag.wieers.com/home-made/mrepo/
@@ -184,43 +184,36 @@ line of ``bcfg2.conf``. Then create Packages layout (as per
.. code-block:: xml
<Sources>
- <!-- CentOS (5.4) sources -->
- <YUMSource>
- <Group>centos-5.4</Group>
- <RawURL>http://mrepo/centos5-x86_64/RPMS.os</RawURL>
- <Arch>x86_64</Arch>
- </YUMSource>
- <YUMSource>
- <Group>centos-5.4</Group>
- <RawURL>http://mrepo/centos5-x86_64/RPMS.updates</RawURL>
- <Arch>x86_64</Arch>
- </YUMSource>
- <YUMSource>
- <Group>centos-5.4</Group>
- <RawURL>http://mrepo/centos5-x86_64/RPMS.extras</RawURL>
- <Arch>x86_64</Arch>
- </YUMSource>
+ <Group name="centos5">
+ <!-- CentOS 5 sources -->
+ <Source type="yum"
+ rawurl="http://mrepo/centos5-x86_64/RPMS.os">
+ <Arch>x86_64</Arch>
+ </Source>
+ <Source type="yum"
+ rawurl="http://mrepo/centos5-x86_64/RPMS.updates">
+ <Arch>x86_64</Arch>
+ </Source>
+ <Source type="yum"
+ rawurl="http://mrepo/centos5-x86_64/RPMS.extras">
+ <Arch>x86_64</Arch>
+ </Source>
+ </Group>
</Sources>
-Due to the :ref:`server-plugins-generators-packages-magic-groups`,
-we need to modify our Metadata. Let's add a **centos5.4** group which
-inherits a **centos** group (this should replace the existing **redhat**
-group) present in ``/var/lib/bcfg2/Metadata/groups.xml``. The resulting
-file should look something like this
-
-.. note::
-
- The reason we are creating a release-specific group in this case is
- that the YUMSource above is specific to the 5.4 release of centos.
- That is, it should not apply to other releases (5.1, 5.3, etc).
+To make these sources apply to our centos 5 clients, we need to modify
+our Metadata. Let's add a **centos5** group which inherits a
+**centos** group (this should replace the existing **redhat** group)
+present in ``/var/lib/bcfg2/Metadata/groups.xml``. The resulting file
+should look something like this
.. code-block:: xml
<Groups version='3.0'>
<Group profile='true' public='true' default='true' name='basic'>
- <Group name='centos-5.4'/>
+ <Group name='centos-5'/>
</Group>
- <Group name='centos-5.4'>
+ <Group name='centos-5'>
<Group name='centos'/>
</Group>
<Group name='ubuntu'/>
@@ -277,7 +270,7 @@ profile group might look something like this
<Group profile='true' public='true' default='true' name='basic'>
<Bundle name='base-packages'/>
- <Group name='centos5.4'/>
+ <Group name='centos5'/>
</Group>
Now if we run the client, we can see what this has done for us.::
@@ -291,7 +284,7 @@ Now if we run the client, we can see what this has done for us.::
Excluding Packages in global exclude list
Finished
Loaded tool drivers:
- Action Chkconfig POSIX YUMng
+ Action Chkconfig POSIX YUM
Package pam failed verification.
Phase: initial
@@ -336,7 +329,7 @@ entries?::
Excluding Packages in global exclude list
Finished
Loaded tool drivers:
- Action Chkconfig POSIX YUMng
+ Action Chkconfig POSIX YUM
Extra Package openssh-clients 4.3p2-36.el5_4.4.x86_64.
Extra Package libuser 0.54.7-2.1el5_4.1.x86_64.
...
@@ -394,7 +387,7 @@ package::
Excluding Packages in global exclude list
Finished
Loaded tool drivers:
- Action Chkconfig POSIX YUMng
+ Action Chkconfig POSIX YUM
Extra Package gpg-pubkey e8562897-459f07a4.None.
Extra Package gpg-pubkey 217521f6-45e8a532.None.
@@ -562,7 +555,7 @@ Now we run the client and see there are no more unmanaged entries!::
Excluding Packages in global exclude list
Finished
Loaded tool drivers:
- Action Chkconfig POSIX YUMng
+ Action Chkconfig POSIX YUM
Phase: initial
Correct entries: 205
diff --git a/doc/appendix/guides/fedora.txt b/doc/appendix/guides/fedora.txt
index 1e49084ef..1c2a33f3b 100644
--- a/doc/appendix/guides/fedora.txt
+++ b/doc/appendix/guides/fedora.txt
@@ -106,7 +106,7 @@ Run ``bcfg2`` to be sure you are able to communicate with the server:
import md5
Loaded plugins: presto, refresh-packagekit
Loaded tool drivers:
- Action Chkconfig POSIX YUMng
+ Action Chkconfig POSIX YUM
Extra Package imsettings-libs 0.108.0-2.fc13.i686.
Extra Package PackageKit-device-rebind 0.6.4-1.fc13.i686.
...
@@ -209,8 +209,10 @@ near your location according the `Mirror list`_ .
.. code-block:: xml
<Sources>
- <Group name="fedora-13">
- <Source type="yum" url="ftp://fedora.tu-chemnitz.de/pub/linux/fedora/linux/releases/" version="13">
+ <Group name="fedora13">
+ <Source type="yum"
+ url="ftp://fedora.tu-chemnitz.de/pub/linux/fedora/linux/releases/"
+ version="13">
<Component>Fedora</Component>
<Arch>i386</Arch>
<Arch>x86_64</Arch>
@@ -219,11 +221,11 @@ near your location according the `Mirror list`_ .
</Sources>
-Due to the :ref:`server-plugins-generators-packages-magic-groups`,
-we need to modify our Metadata. Let's add a **fedora13** group which
-inherits a **fedora** group (this should replace the existing **redhat**
-group) present in ``/var/lib/bcfg2/Metadata/groups.xml``. The resulting
-file should look something like this
+In order to make these sources apply to our clients, we need to modify
+our Metadata. Let's add a **fedora13** group which inherits a
+**fedora** group (this should replace the existing **redhat** group)
+present in ``/var/lib/bcfg2/Metadata/groups.xml``. The resulting file
+should look something like this
.. note::
diff --git a/doc/appendix/guides/ubuntu.txt b/doc/appendix/guides/ubuntu.txt
index 5a67d0a37..06813f50b 100644
--- a/doc/appendix/guides/ubuntu.txt
+++ b/doc/appendix/guides/ubuntu.txt
@@ -82,7 +82,7 @@ You are now ready to start your bcfg2 server for the first time.::
root@lucid:~# tail /var/log/syslog
Dec 17 22:07:02 lucid bcfg2-server[17523]: serving bcfg2-server at https://lucid:6789
Dec 17 22:07:02 lucid bcfg2-server[17523]: serve_forever() [start]
- Dec 17 22:07:02 lucid bcfg2-server[17523]: Processed 16 fam events in 0.502 seconds. 0 coalesced
+ Dec 17 22:07:02 lucid bcfg2-server[17523]: Handled 16 events in 0.502 seconds
Run bcfg2 to be sure you are able to communicate with the server::
@@ -181,9 +181,9 @@ Create Packages layout (as per :ref:`packages-exampleusage`) in
</Group>
</Sources>
-Due to the :ref:`server-plugins-generators-packages-magic-groups`,
-we need to modify our Metadata. Let's add an **ubuntu-lucid**
-group which inherits the **ubuntu** group already present in
+To make these sources apply to our clients, we need to modify our
+Metadata. Let's add an **ubuntu-lucid** group which inherits the
+**ubuntu** group already present in
``/var/lib/bcfg2/Metadata/groups.xml``. The resulting file should look
something like this
@@ -256,7 +256,7 @@ Now we restart the bcfg2-server::
Dec 17 22:37:27 lucid bcfg2-server[17937]: service available at https://lucid:6789
Dec 17 22:37:27 lucid bcfg2-server[17937]: serving bcfg2-server at https://lucid:6789
Dec 17 22:37:27 lucid bcfg2-server[17937]: serve_forever() [start]
- Dec 17 22:37:28 lucid bcfg2-server[17937]: Processed 17 fam events in 0.502 seconds. 0 coalesced
+ Dec 17 22:37:28 lucid bcfg2-server[17937]: Handled 17 events in 0.502 seconds
Start managing packages
-----------------------
@@ -364,7 +364,7 @@ while, I ended up with a minimal bundle that looks like this
<Package name='deborphan'/>
<Package name='diffutils'/>
<Package name='e2fsprogs'/>
- <Package name='fam'/>
+ <Package name='gamin'/>
<Package name='grep'/>
<Package name='grub-pc'/>
<Package name='gzip'/>
@@ -379,7 +379,7 @@ while, I ended up with a minimal bundle that looks like this
<Package name='mlocate'/>
<Package name='ncurses-base'/>
<Package name='openssh-server'/>
- <Package name='python-fam'/>
+ <Package name='python-gamin'/>
<Package name='tar'/>
<Package name='ubuntu-minimal'/>
<Package name='ubuntu-standard'/>
@@ -422,7 +422,7 @@ As you can see below, I no longer have any unmanaged packages. ::
Incorrect entries: 0
Total managed entries: 247
Unmanaged entries: 10
- Service:bcfg2 Service:fam Service:killprocs Service:rc.local Service:single
+ Service:bcfg2 Service:killprocs Service:rc.local Service:single
Service:bcfg2-server Service:grub-common Service:ondemand Service:rsync Service:ssh
Manage services
@@ -436,7 +436,6 @@ entries to our bundle...
<!-- basic services -->
<Service name='bcfg2'/>
<Service name='bcfg2-server'/>
- <Service name='fam'/>
<Service name='grub-common'/>
<Service name='killprocs'/>
<Service name='ondemand'/>
@@ -455,7 +454,6 @@ entries to our bundle...
<!-- basic services -->
<Service type='deb' status='on' name='bcfg2'/>
<Service type='deb' status='on' name='bcfg2-server'/>
- <Service type='deb' status='on' name='fam'/>
<Service type='deb' status='on' name='grub-common'/>
<Service type='deb' status='on' name='killprocs'/>
<Service type='deb' status='on' name='ondemand'/>
diff --git a/doc/client/tools.txt b/doc/client/tools.txt
index 1dbb33b1a..09ea76230 100644
--- a/doc/client/tools.txt
+++ b/doc/client/tools.txt
@@ -133,8 +133,6 @@ RPM
Executes RPM to manage packages on Redhat-based and similar systems.
Consider using the :ref:`YUM <client-tools-yum>` tool instead if possible.
-Formerly called ``RPMng``, but was renamed for the 1.3 release.
-
SMF
---
@@ -166,13 +164,5 @@ Upstart service support. Uses `Upstart`_ to configure services.
YUM
---
-Handles RPMs using the YUM package manager. Renamed from ``YUMng`` for
-the 1.3 release. See :ref:`client-tools-yum` for more details.
-
-YUM24
------
-
-.. warning:: Deprecated in favor of :ref:`YUM <client-tools-yum>`
-
-Handles RPMs using older versions of the YUM package manager.
-
+Handles RPMs using the YUM package manager. See
+:ref:`client-tools-yum` for more details.
diff --git a/doc/client/tools/yum.txt b/doc/client/tools/yum.txt
index 47ef3d5e9..ed1a3d5fd 100644
--- a/doc/client/tools/yum.txt
+++ b/doc/client/tools/yum.txt
@@ -7,9 +7,7 @@ Bcfg2 RPM/YUM Client Drivers
============================
The RPM and YUM client drivers provide client support for RPMs
-(installed directly from URLs) and Yum repositories. These drivers
-were formerly called ``RPMng`` and ``YUMng``, respectively, but were
-renamed for Bcfg2 1.3.0.
+(installed directly from URLs) and Yum repositories.
Features
========
diff --git a/doc/development/cfg.txt b/doc/development/cfg.txt
index c3b8d12af..71c455b52 100644
--- a/doc/development/cfg.txt
+++ b/doc/development/cfg.txt
@@ -80,18 +80,11 @@ Creators
.. autoclass:: Bcfg2.Server.Plugins.Cfg.CfgPrivateKeyCreator.CfgPrivateKeyCreator
.. autoclass:: Bcfg2.Server.Plugins.Cfg.CfgPublicKeyCreator.CfgPublicKeyCreator
-Filters
--------
-
-.. autoclass:: Bcfg2.Server.Plugins.Cfg.CfgCatFilter.CfgCatFilter
-.. autoclass:: Bcfg2.Server.Plugins.Cfg.CfgDiffFilter.CfgDiffFilter
-
Info Handlers
-------------
.. autoclass:: Bcfg2.Server.Plugins.Cfg.CfgDefaultInfo
.. autoclass:: Bcfg2.Server.Plugins.Cfg.CfgInfoXML.CfgInfoXML
-.. autoclass:: Bcfg2.Server.Plugins.Cfg.CfgLegacyInfo.CfgLegacyInfo
Verifiers
---------
diff --git a/doc/development/fam.txt b/doc/development/fam.txt
index c2c3b14f5..e967aaf68 100644
--- a/doc/development/fam.txt
+++ b/doc/development/fam.txt
@@ -56,11 +56,6 @@ Pseudo
.. automodule:: Bcfg2.Server.FileMonitor.Pseudo
-Fam
----
-
-.. automodule:: Bcfg2.Server.FileMonitor.Fam
-
Gamin
-----
diff --git a/doc/getting_started/index.txt b/doc/getting_started/index.txt
index a9e91e6b8..5f84117d4 100644
--- a/doc/getting_started/index.txt
+++ b/doc/getting_started/index.txt
@@ -70,7 +70,7 @@ That can be translated as "bcfg2 quick verbose no-op". The output
should be something similar to::
Loaded tool drivers:
- Chkconfig POSIX YUMng
+ Chkconfig POSIX YUM
Phase: initial
Correct entries: 0
@@ -175,7 +175,7 @@ Next, we create a motd.xml file in the Bundler directory:
Now when we run the client, we get slightly different output::
Loaded tool drivers:
- Chkconfig POSIX YUMng
+ Chkconfig POSIX YUM
Incomplete information for entry Path:/etc/motd; cannot verify
Phase: initial
@@ -205,7 +205,7 @@ real ``/etc/motd`` file to that location, run the client again, and
you will find that we now have a correct entry::
Loaded tool drivers:
- Chkconfig POSIX PostInstall RPM
+ Chkconfig POSIX Action RPM
Phase: initial
Correct entries: 1
diff --git a/doc/help/troubleshooting.txt b/doc/help/troubleshooting.txt
index 35c1e93a2..c3abab9e7 100644
--- a/doc/help/troubleshooting.txt
+++ b/doc/help/troubleshooting.txt
@@ -69,13 +69,13 @@ included with the source distribution and all packages.
If the bcfg2 server is not reflecting recent changes, try restarting the bcfg2-server process
=============================================================================================
-If this fixes the problem, it is either a bug in the
-underlying file monitoring system (fam or gamin) or a bug in
-Bcfg2's file monitoring code. In either case, file a `ticket
+If this fixes the problem, it is either a bug in the underlying file
+monitoring system (inotify or gamin) or a bug in Bcfg2's file
+monitoring code. In either case, file a `ticket
<https://trac.mcs.anl.gov/projects/bcfg2/newticket>`_ in the tracking
system. In the ticket, include:
-* filesystem monitoring system (fam or gamin)
+* filesystem monitoring system (inotify or gamin)
* kernel version (if on linux)
* if any messages of the form "Handled N events in M
seconds" appeared between the modification event and the client
@@ -259,8 +259,7 @@ Server Errors
:ref:`server-info` file for this entry.
.. [s11] Verify that you have the proper prefix set in bcfg2.conf.
.. [s12] Ensure that the client is a member of all the appropriate
- :ref:`server-plugins-generators-packages-magic-groups` as
- well as any additional groups you may have defined in your
+ groups you may have defined in your
:ref:`server-plugins-generators-packages` configuration.
FAQs
diff --git a/doc/installation/distributions.txt b/doc/installation/distributions.txt
index 3dcfd7721..eccd6e723 100644
--- a/doc/installation/distributions.txt
+++ b/doc/installation/distributions.txt
@@ -73,7 +73,7 @@ to get it marked as stable.
If you don't use portage to install Bcfg2, you'll want to make sure you
have all the prerequisites installed first. For a server, you'll need:
-* ``app-admin/gamin`` or ``app-admin/fam``
+* ``app-admin/gamin``
* ``dev-python/lxml``
Clients will need at least:
diff --git a/doc/installation/prerequisites.txt b/doc/installation/prerequisites.txt
index 0cb721bb9..eaa2a0393 100644
--- a/doc/installation/prerequisites.txt
+++ b/doc/installation/prerequisites.txt
@@ -50,9 +50,9 @@ Bcfg2 Server
+-------------------------------+----------+--------------------------------+
| lxml | 0.9+ | lxml: libxml2, libxslt, python |
+-------------------------------+----------+--------------------------------+
-| gamin or fam | Any | |
+| gamin or inotify | Any | |
+-------------------------------+----------+--------------------------------+
-| python-gamin or python-fam | Any | gamin or fam, python |
+| python-gamin or pyinotify | Any | gamin or inotify, python |
+-------------------------------+----------+--------------------------------+
| M2crypto or python-ssl (note | Any | python, openssl |
| that the ssl module is | | |
diff --git a/doc/reports/static.txt b/doc/reports/static.txt
deleted file mode 100644
index 00c1867f8..000000000
--- a/doc/reports/static.txt
+++ /dev/null
@@ -1,100 +0,0 @@
-.. -*- mode: rst -*-
-
-.. _reports-static:
-
-=============================
-Bcfg2 Static Reporting System
-=============================
-
-The Bcfg2 reporting system collects and displays information about the
-operation of the Bcfg2 client, and the configuration states of target
-machines.
-
-Goals
-=====
-
-The reporting system provides an interface to administrators describing
-a few important tasks
-
-* Client configuration state, particularly aspects that do not match the configuration specification.
- Information about bad and extra configuration elements is included.
-* Client execution results (a list of configuration elements that were modified)
-* Client execution performance data (including operation retry counts, and timings for several critical execution regions)
-
-This data can be used to understand the current configuration state
-of the entire network, the operations performed by the client, how the
-configuration changes propagate, and any reconfiguration operations that
-have failed.
-
-Retention Model
-===============
-
-The current reporting system stores statistics in an XML data store, by
-default to ``<repo>/etc/statistics.xml``. It retains either one or two
-statistic sets per host. If the client has a clean configuration state,
-the most recent (clean) record is retained. If the client has a dirty
-configuration state, two records are retained. One record is the last
-clean record. The other record is the most recent record collected,
-detailing the incorrect state.
-
-This retention model, while non-optimal, does manage to persistently
-record most of the data that users would like.
-
-Setup
-=====
-
-In order to configure your Bcfg2 server for receiving reports, you
-will need to list the Statistics plugin in the plugins line of your
-``bcfg2.conf``. You will also need a [statistics] section
-in your ``bcfg2.conf``. You can find out more about what goes there in the
-``bcfg2.conf`` manpage.
-
-Output
-======
-
-Several output reports can be generated from the statistics store with
-the command line tool ``bcfg2-build-reports``.
-
-* Nodes Digest
-* Nodes Individual
-* Overview Statistics
-* Performance
-
-The data generated by these reports can be delivered by several
-mechanisms:
-
-* HTML
-* Email
-* RSS
-
-Shortcomings and Planned Enhancements
-=====================================
-
-When designing the current reporting system, we were overly concerned with
-the potential explosion in data size over time. In order to address this,
-we opted to use the retention scheme described above. This approach has
-several shortcomings:
-
-* A comprehensive list of reconfiguration operations (with associated
- timestamps) isn't retained
-* Client results for any given day (except the last one) aren't uniformly
- retained. This means that inter-client analysis is difficult, if
- not impossible
-
-We plan to move to a database backend to address the dataset size
-problem and start retaining all information. The move to a SQL backend
-will allow many more types of queries to be efficiently processed. It
-will also make on-demand reports simpler.
-
-Other sorts of information would also be useful to track. We plan to
-add the ability to tag a particular configuration element as security
-related, and include this in reports. This will aid in the effective
-prioritization of manual and failed reconfiguration tasks.
-
-Capability Goals (posed as questions)
--------------------------------------
-
-* What machines have not yet applied critical updates?
-* How long did critical updates take to be applied?
-* What configuration did machine X have on a particular date?
-* When did machine X perform configuration update Y?
diff --git a/doc/server/admin/index.txt b/doc/server/admin/index.txt
index ee03cedda..8ea765aac 100644
--- a/doc/server/admin/index.txt
+++ b/doc/server/admin/index.txt
@@ -24,7 +24,6 @@ functionality. Available modes are listed below.
perf
pull
query
- snapshots
tidy
viz
xcmd
diff --git a/doc/server/admin/snapshots.txt b/doc/server/admin/snapshots.txt
deleted file mode 100644
index 25a7286c2..000000000
--- a/doc/server/admin/snapshots.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-.. -*- mode: rst -*-
-
-.. _server-admin-snapshots:
-
-snapshots
-=========
-
-Interact with the Snapshots system.
diff --git a/doc/server/configuration.txt b/doc/server/configuration.txt
index 2c5879ff0..be421207c 100644
--- a/doc/server/configuration.txt
+++ b/doc/server/configuration.txt
@@ -52,9 +52,7 @@ itself, which would prevent the ``bcfg2`` user from enabling a new
plugin. If you depend on this capability (e.g., if your specification
is stored in a VCS and checked out onto the Bcfg2 server by a script
running as the ``bcfg2`` user), then you would want to ``chown`` and
-``chmod`` ``/var/lib/bcfg2`` rather than ``/var/lib/bcfg2/*``. Note
-also that the recursive ``chmod`` will change permissions on any files
-that are using ``mode="inherit"`` in :ref:`server-info`.
+``chmod`` ``/var/lib/bcfg2`` rather than ``/var/lib/bcfg2/*``.
The Bcfg2 server also needs to be able to read its SSL certificate,
key and the SSL CA certificate:
diff --git a/doc/server/index.txt b/doc/server/index.txt
index 2ccc9c923..42abb454c 100644
--- a/doc/server/index.txt
+++ b/doc/server/index.txt
@@ -26,7 +26,6 @@ clients.
admin/index
configurationentries
info
- snapshots/index
bcfg2-info
selinux
configuration
diff --git a/doc/server/info.txt b/doc/server/info.txt
index b4d1f7113..2c50f0031 100644
--- a/doc/server/info.txt
+++ b/doc/server/info.txt
@@ -53,25 +53,3 @@ A more complex example for a template that generates both
See :ref:`server-selinux` for more information on the ``secontext``
attribute and managing SELinux in general.
-
-:info and info files
-====================
-
-.. deprecated:: 1.3.0
-
-Historically, Bcfg2 also accepted the use of ``:info`` and ``info``
-files, which function the same as ``info.xml``, but are not XML. They
-lack the ability to specify different permissions based on client,
-group, or path, and cannot be used to specify ACLs, either.
-
-An example ``:info`` or ``info`` file would look like::
-
- owner: www
- group: www
- mode: 0755
-
-All attributes allowed on the ``<Info>`` tag of an ``info.xml`` file
-can be used in an ``:info`` or ``info`` file.
-
-You should not use more than one ``:info``, ``info``, or ``info.xml``
-file for a single entry.
diff --git a/doc/server/plugins/generators/account.txt b/doc/server/plugins/generators/account.txt
deleted file mode 100644
index 99c35c814..000000000
--- a/doc/server/plugins/generators/account.txt
+++ /dev/null
@@ -1,115 +0,0 @@
-.. -*- mode: rst -*-
-
-.. _server-plugins-generators-account:
-
-=======
-Account
-=======
-
-The account plugin manages authentication data, including
-
-* ``/etc/passwd``
-* ``/etc/group``
-* ``/etc/security/limits.conf``
-* ``/etc/sudoers``
-* ``/root/.ssh/authorized_keys``
-
-User access data is stored in three files in the Account directory:
-
-* superusers (a list of users who always have root privs)
-* rootlist (a list of user:host pairs for scoped root privs)
-* useraccess (a list of user:host pairs for login access)
-
-SSH keys are stored in files named $username.key; these are installed
-into root's authorized keys for users in the superusers list as well as
-for the pertitent users in the rootlike file (for the current system).
-
-Authentication data is read in from (static|dyn).(passwd|group) The static
-ones are for system local ones, while the dyn. versions are for external
-synchronization (from ldap/nis/etc). There is also a static.limits.conf
-that provides the limits.conf header and any static entries.
-
-Files in the Account directory:
-
-``<username>.key``
-
- **Format**: The SSH public key for user <username>.
-
- If the user is in the "rootlike" or "superusers" group, these
- keys will be appended to ``/root/.ssh/auth``
-
-``useraccess``
-
- **Format**: "user:hostname" on each line.
-
- Describes who may login where (via PAMs
- ``/etc/security/limits.conf``). Everybody else will be denied
- access.(?)
-
- **Example**:
-
- If Alice should be able to access host "foo", Bob should access
- "foo" and "bar"::
-
- alice:foo.example.com
- bob:foo.example.com
- bob:bar.example.com
-
-``rootlike``
-
- **Format**: "user:hostname" on each line.
-
- Describes who will be allowed root access where. The user may
- login via public key and use sudo.
-
- **Example**:
-
- If Chris should be root only on host "foo"::
-
- chris:foo.example.com
-
-``superusers``
-
- **Format**: usernames, separated by spaces or newlines. (Any whitespace that makes pythons split() happy.)
-
- Describes who will be allowed root access on all hosts. The user
- may login via public key and use sudo.
-
- **Example**:
-
- Daniel, Eve and Faith are global admins::
-
- daniel eve
- faith
-
-``static.passwd``, ``static.group``
-
- **Format**: Lines from ``/etc/passwd`` or ``/etc/group``
-
- These entries are appended to the passwd and group files
- (in addition to the auto-generated entries from "useraccess",
- "rootlike" and "superusers" above) without doing anything else.
-
-``dyn.passwd``, ``dyn.group``
-
- **Format**: Lines from ``/etc/passwd`` or ``/etc/group``
-
- Similar to "static.*" above, but for entries that are managed "on
- the network" (yp, LDAP, ...), so it is most likely periodically
- (re)filled.
-
-``static.limits.conf``
-
- **Format**: Lines from ``/etc/security/limit.conf``
-
- These limits will be appended to limits.conf (in addition to
- the auto-generated entries from "useraccess", "rootlike" and
- "superusers" above).
-
-``static.sudoers``
-
- **Format**: Lines from ``/etc/sudoers``
-
- These lines will be appended to to sudoers file (in addition
- to the auto-generated entries from "useraccess", "rootlike" and
- "superusers" above).
diff --git a/doc/server/plugins/generators/cfg.txt b/doc/server/plugins/generators/cfg.txt
index 1cb4b8727..8339c8080 100644
--- a/doc/server/plugins/generators/cfg.txt
+++ b/doc/server/plugins/generators/cfg.txt
@@ -102,9 +102,8 @@ Genshi Templates
----------------
Genshi templates allow you to use the `Genshi
-<http://genshi.edgewall.org>`_ templating system. This is similar to
-the deprecated :ref:`server-plugins-generators-tgenshi-index` plugin.
-Genshi templates should be named with a ``.genshi`` extension, e.g.::
+<http://genshi.edgewall.org>`_ templating system. Genshi templates
+should be named with a ``.genshi`` extension, e.g.::
% ls Cfg/etc/motd
info.xml motd.genshi
@@ -214,9 +213,8 @@ Cheetah Templates
-----------------
Cheetah templates allow you to use the `cheetah templating system
-<http://www.cheetahtemplate.org/>`_. This is similar to
-the deprecated :ref:`server-plugins-generators-tcheetah` plugin.
-Cheetah templates should be named with a ``.cheetah`` extension, e.g.::
+<http://www.cheetahtemplate.org/>`_. Cheetah templates should be
+named with a ``.cheetah`` extension, e.g.::
% ls Cfg/etc/motd
info.xml motd.cheetah
@@ -586,73 +584,6 @@ influenced by several options in the ``[sshkeys]`` section of
See :ref:`server-encryption` for more details on encryption in Bcfg2
in general.
-Deltas
-======
-
-.. note::
-
- In Bcfg2 1.3 and newer, deltas are deprecated. It is recommended
- that you use templates instead. The
- :ref:`TemplateHelper plugin
- <server-plugins-connectors-templatehelper>` comes with an example
- helper that can be used to include other files easily, a subset of
- cat file functionality. ``bcfg2-lint`` checks for deltas and
- warns about them.
-
-Bcfg2 has finer grained control over how to deliver configuration
-files to a host. Let's say we have a Group named file-server. Members
-of this group need the exact same ``/etc/motd`` as all other hosts except
-they need one line added. We could copy motd to ``motd.G01_file-server``,
-add the one line to the Group specific version and be done with it,
-but we're duplicating data in both files. What happens if we need to
-update the motd? We'll need to remember to update both files then. Here's
-where deltas come in. A delta is a small change to the base file. There
-are two types of deltas: cats and diffs. The cat delta simply adds or
-removes lines from the base file. The diff delta is more powerful since
-it can take a unified diff and apply it to the base configuration file
-to create the specialized file. Diff deltas should be used very sparingly.
-
-Cat Files
----------
-
-Continuing our example for cat files, we would first create a file named
-``motd.G01_file-server.cat``. The .cat suffix designates that the file is
-a diff. We would then edit that file and add the following line::
-
- +This is a file server
-
-The **+** at the begining of the file tells Bcfg2 that the line should be
-appended to end of the file. You can also start a line with **-** to tell
-Bcfg2 to remove that exact line wherever it might be in the file. How do
-we know what base file Bcfg2 will choose to use to apply a delta? The
-same rules apply as before: Bcfg2 will choose the highest priority,
-most specific file as the base and then apply deltas in the order of
-most specific and then increasing in priority. What does this mean in
-real life. Let's say our machine is a web server, mail server, and file
-server and we have the following configuration files::
-
- motd
- motd.G01_web-server
- motd.G01_mail-server.cat
- motd.G02_file-server.cat
- motd.H_foo.example.com.cat
-
-If our machine **isn't** *foo.example.com* then here's what would happen:
-
-Bcfg2 would choose ``motd.G01_web-server`` as the base file. It is
-the most specific base file for this host. Bcfg2 would apply the
-``motd.G01_mail-server.cat`` delta to the ``motd.G01_web-server``
-base file. It is the least specific delta. Bcfg2 would then apply the
-``motd.G02_file-server.cat`` delta to the result of the delta before
-it. If our machine **is** *foo.example.com* then here's what would happen:
-
-Bcfg2 would choose ``motd.G01_web-server`` as the base file. It
-is the most specific base file for this host. Bcfg2 would apply the
-``motd.H_foo.example.com.cat`` delta to the ``motd.G01_web-server`` base
-file. The reason the other deltas aren't applied to *foo.example.com*
-is because a **.H_** delta is more specific than a **.G##_** delta. Bcfg2
-applies all the deltas at the most specific level.
-
.. _server-plugins-generators-cfg-validation:
Content Validation
diff --git a/doc/server/plugins/generators/hostbase.txt b/doc/server/plugins/generators/hostbase.txt
deleted file mode 100644
index c6007f70e..000000000
--- a/doc/server/plugins/generators/hostbase.txt
+++ /dev/null
@@ -1,228 +0,0 @@
-.. -*- mode: rst -*-
-
-.. _server-plugins-generators-hostbase:
-
-========
-Hostbase
-========
-
-IP management system built on top of Bcfg2. It has four main parts: a
-django data model, a web frontend, command-line utilities, and a Bcfg2
-plugin that generates dhcp, dns, and yp configuration files.
-
-Installation
-============
-
-Installation of Hostbase requires installation of a python module,
-configuration of database (mysql or postgres), and configuration of an
-Apache webserver with mod_python. Hostbase was developed using MySQL,
-so this document is aimed at MySQL users.
-
-Prerequisites
--------------
-
-* `mysql`_
-* `python-mysqldb`_
-* `Django`_
-
-.. _Django: http://www.djangoproject.com
-.. _python-mysqldb: http://mysql-python.sourceforge.net/MySQLdb.html
-.. _mysql: http://www.mysql.com/
-
-Configure the database
-----------------------
-
-Create the hostbase database and a user. For MySQL users::
-
- mysql> CREATE DATABASE hostbase
- mysql> quit
-
- systemprompt#: mysql -u root hostbase
- mysql> GRANT ALL PRIVILEGES ON *.* TO hostbaseuser@mycomputer.private.net IDENTIFIED
- BY 'password' WITH GRANT OPTION;
- mysql> quit
-
-As of Bcfg2 v0.8.7 configuration options for Hostbase have moved to
-``/etc/bcfg2.conf``. There is an example bcfg2.conf with Hostbase
-options located at ``bcfg2-tarball/examples/bcfg2.confHostbase``.
-Edit the hostbase options to correspond to the database you've
-initialized and copy the configuration to ``/etc/bcfg2.conf``. To
-finish creating the database, from your ``path to
-python/Bcfg2/Server/Hostbase`` directory, run ``python manage.py
-syncdb`` to do all table creation.
-
-Configure the web interface
----------------------------
-
-Now it's possible to explore the Hostbase web interface. For
-curiosity, you can run Django's built-in development server to take a
-peek. Do this by running ``python manage.py runserver
-[servername:port]`` from your Hostbase directory. Django will
-default to ``localhost:8000`` if no server or port is entered. Now
-you can explore the web interface. Try adding a host and a zone.
-You'll see that a ".rev" zone already exists. This is where
-information for reverse files will go.
-
-For production, you'll want to have this configured for Apache with
-mod_python. Here is an example of how to configure Hostbase as a
-virtual host.
-
-.. code-block:: html
-
- <VirtualHost hostbase.mcs.anl.gov:80>
- ServerAdmin systems@mcs.anl.gov
-
- DocumentRoot /var/www/hostbase/
- <Directory />
- AllowOverride None
- </Directory>
-
- # Possible values include: debug, info, notice, warn, error, crit,
- # alert, emerg.
- LogLevel warn
-
- ServerSignature Off
-
- # Stop TRACE/TRACK vulnerability
- <IfModule mod_rewrite.c>
- RewriteEngine on
- RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK)
- RewriteRule .* - [F]
- </IfModule>
-
- Redirect / https://hostbase.mcs.anl.gov/
- </VirtualHost>
-
- <VirtualHost hostbase.mcs.anl.gov:443>
- ServerAdmin systems@mcs.anl.gov
-
- DocumentRoot /var/www/hostbase/
- <Directory />
- AllowOverride None
- </Directory>
-
- # Possible values include: debug, info, notice, warn, error, crit,
- # alert, emerg.
- LogLevel warn
-
- ServerSignature Off
-
- # Stop TRACE/TRACK vulnerability
- <IfModule mod_rewrite.c>
- RewriteEngine on
- RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK)
- RewriteRule .* - [F]
- </IfModule>
-
- SSLEngine On
- SSLCertificateFile /etc/apache2/ssl/hostbase_server.crt
- SSLCertificateKeyfile /etc/apache2/ssl/hostbase_server.key
-
- <Location "/">
- SetHandler python-program
- PythonHandler django.core.handlers.modpython
- SetEnv DJANGO_SETTINGS_MODULE Bcfg2.Server.Hostbase.settings
- PythonDebug On
- </Location>
- <Location "/site_media/">
- SetHandler None
- </Location>
- </VirtualHost>
-
-
-You'll need to copy the contents of ``Hostbase/media`` into
-``/var/www/hostbase/site_media`` in this configuration to serve the
-correct css files.
-
-Enable the Hostbase plugin
---------------------------
-
-Now that the database is accessible and there is some data in it, you can
-enable the Hostbase plugin on your Bcfg2 server to start generating some
-configuration files. All that needs to be done is to add ``Hostbase``
-to the end of the list of generators in your bcfg2.conf file. To see
-what's being generated by Hostbase, fire up a Bcfg2 development server:
-``bcfg2-info``. For more information on how to use the Bcfg2 development
-server, type help at the prompt. For our purposes, type ``debug``.
-This will bring you to an interactive python prompt where you can access
-bcfg's core data.
-
-.. code-block:: python
-
- for each in bcore.plugins['Hostbase'].filedata:
- print each
-
-
-The above loop will print out the name of each file that was generated
-by Hostbase. You can see the contents of any of these by typing ``print
-bcore.plugins['Hostbase'].filedata[filename]``.
-
-Create a bundle
----------------
-
-Bcfg2 needs a way to distribute the files generated by Hostbase.
-We'll do this with a bundle. In bcfg's ``Bundler`` directory, touch
-``hostbase.xml``.
-
-.. code-block:: xml
-
- <Bundle name='hostbase' version='0.1'>
- <Package name='dhcp3-server'/>
- <Package name='bind9'/>
- <Service name='dhcp3-server'/>
- <Service name='bind9'/>
- <Path name='/etc/dhcp3/dhcpd.conf'/>
- <Path name='/etc/bind/[your domain]'/>
- <Path name='/etc/bind/xxx.xxx.xxx.rev'/>
- </Bundle>
-
-The above example is a bundle that will deliver both dhcp and dns files.
-This can be trivially split into separate bundles. It is planned that
-Hostbase will eventually be able to generate the list of ``Paths``
-in its bundles automatically.
-
-Do a Hostbase push
-------------------
-
-You'll want to be able to trigger the Hostbase plugin to rebuild
-it's config files and push them out when data has been modified
-in the database. This can be done through and XMLRPC function
-available from the Bcfg2 server. From a client that is configured
-to receive one or more hostbase bundles, you'll need to first
-edit your ``python/site-packages/Bcfg2/Client/Proxy.py`` file.
-Add ``'Hostbase.rebuildState'`` to the list of methods in the Bcfg2
-client proxy object. The modified list is shown below:
-
-.. code-block:: python
-
- class bcfg2(ComponentProxy):
- '''bcfg2 client code'''
- name = 'bcfg2'
- methods = ['AssertProfile', 'GetConfig', 'GetProbes', 'RecvProbeData', 'RecvStats', 'Hostbase.rebuildState']
-
-Now copy the file ``hostbasepush.py`` from ``bcfg2/tools`` in the Bcfg2
-source to your machine. When this command is run as root, it triggers
-the Hostbase to rebuild it's files, then runs the Bcfg2 client on your
-local machine to grab the new configs.
-
-NIS Authentication
-==================
-
-Django allows for custom authentication backends to its login procedure.
-Hostbase has an NIS authentication backend that verifies a user to be
-in the unix group allowed to modify Hostbase.
-
-To enable this feature:
-
-* first edit your ``Hostbase/settings.py`` file and uncomment
- the line **Hostbase.backends.NISBackend** in the list of
- *AUTHENTICATION_BACKENDS*
-* enter the name of the unix group you want to give access to Hostbase
- in the *AUTHORIZED_GROUP* variable
-* in your ``Hostbase/hostbase/views.py`` file at the very bottom,
- uncomment the block(s) of lines that give you the desired level
- of access
-
-Hostbase will now direct the user to a login page if he or she is not
-authorized to view a certain page. Users should log in with their
-regular Unix username and password.
diff --git a/doc/server/plugins/generators/packages.txt b/doc/server/plugins/generators/packages.txt
index e45864ef9..a7987260a 100644
--- a/doc/server/plugins/generators/packages.txt
+++ b/doc/server/plugins/generators/packages.txt
@@ -18,14 +18,10 @@ through those channels.
Limiting sources to groups
==========================
-`sources.xml`_ processes ``<Group>`` and ``<Client>`` tags just like
-Bundles. In addition to any groups or clients specified that way,
-clients must be a member of the appropriate architecture group as
-specified in a Source stanza. In total, in order for a source to be
-associated with a client, the client must be in any explicit groups or
-clients specified in `sources.xml`_, and any specified architecture
-groups. If `"Magic Groups"`_ are enabled, then the client must be a
-member of a matching magic group as well.
+``Packages/sources.xml`` processes ``<Group>`` and ``<Client>`` tags
+just like Bundles. In addition to any groups or clients specified that
+way, clients must be a member of the appropriate architecture group as
+specified in a Source stanza.
Memberships in architecture groups is needed so that Packages can map
software sources to clients. There is no other way to handle this than
@@ -36,62 +32,6 @@ source to which they apply (based on group memberships, as described
above). Packages and dependencies are resolved from all applicable
sources.
-.. note::
-
- To recap, a client needs to be a member of the **Architecture**
- group and any other groups defined in your
- `sources.xml`_ file in order for the client to be
- associated to the proper sources. If you are using
- :ref:`server-plugins-generators-packages-magic-groups`, then a
- client must also be a member of the appropriate OS group.
-
-.. _server-plugins-generators-packages-magic-groups:
-
-"Magic Groups"
-==============
-
-.. deprecated:: 1.3.0
-
-Packages has the ability to use a feature known as "magic groups"; it
-is the only plugin to use that feature. Most plugins operate based on
-client group memberships, without any concern for the particular names
-chosen for groups by the user. The Packages plugin is the sole
-exception to this rule. Packages needs to "know" two different sorts
-of facts about clients. The first is the basic OS/distro of the
-client, enabling classes of sources. The second is the architecture of
-the client, enabling sources for a given architecture. In addition to
-these magic groups, each source may also specify non-magic groups to
-limit the source's applicability to group member clients.
-
-+--------+----------+--------------+
-| Source | OS Group | Architecture |
-+========+==========+==============+
-| Apt | debian | i386 |
-+--------+----------+--------------+
-| Apt | ubuntu | amd64 |
-+--------+----------+--------------+
-| Apt | nexenta | |
-+--------+----------+--------------+
-| Apt | apt | |
-+--------+----------+--------------+
-| Yum | redhat | i386 |
-+--------+----------+--------------+
-| Yum | centos | x86_64 |
-+--------+----------+--------------+
-| Yum | fedora | |
-+--------+----------+--------------+
-| Yum | yum | |
-+--------+----------+--------------+
-
-Magic OS groups are disabled by default in Bcfg2 1.3 and greater. If
-you require magic groups, you can enable them by setting
-``magic_groups`` to ``1`` in the ``[packages]`` section of
-``bcfg2.conf``.
-
-Magic groups will be removed in a future release.
-
-Magic architecture groups cannot be disabled.
-
Setup
=====
@@ -102,14 +42,13 @@ Three basic steps are required for Packages to work properly.
software repositories should be used, and which clients are
eligible to use each one.
#. Ensure that clients are members of the proper groups. Each client
- should be a member of all of the groups listed in the `sources.xml`
- (like ubuntu-intrepid or centos-5.2 in the following examples), one
- of the architecture groups listed in the source configuration
- (i386, amd64 or x86_64 in the following examples), and one of the
- magic groups listed above, if magic groups are enabled. '''Failure
- to do this will result in the source either not applying to the
- client, or only architecture independent packages being made
- available to the client.'''
+ should be a member of all of the groups listed in the
+ ``sources.xml`` (like ubuntu-intrepid or centos-5.2 in the
+ following examples), and one of the architecture groups listed in
+ the source configuration (i386, amd64 or x86_64 in the following
+ examples). '''Failure to do this will result in the source either
+ not applying to the client, or only architecture independent
+ packages being made available to the client.'''
#. Add Package entries to bundles.
#. Sit back and relax, as dependencies are resolved, and automatically
added to client configurations.
diff --git a/doc/server/plugins/generators/tcheetah.txt b/doc/server/plugins/generators/tcheetah.txt
deleted file mode 100644
index ab147ce56..000000000
--- a/doc/server/plugins/generators/tcheetah.txt
+++ /dev/null
@@ -1,197 +0,0 @@
-.. -*- mode: rst -*-
-
-.. _server-plugins-generators-tcheetah:
-
-========
-TCheetah
-========
-
-.. warning::
-
- TCheetah is deprecated. You should instead use
- :ref:`server-plugins-generators-cfg-cheetah` in the Cfg plugin.
-
-This document reflects the ``TCheetah`` plugin.
-
-The ``TCheetah`` plugin allows you to use the `cheetah templating system
-<http://www.cheetahtemplate.org/>`_ to create files, instead of the
-various diff-based methods offered by the ``Cfg`` plugin. It also allows
-you to include the results of probes executed on the client in the
-created files.
-
-To begin, you will need to download and install the Cheetah templating
-engine from http://www.cheetahtemplate.org/. Once it is installed,
-you can enable it by adding ``TCheetah`` to the ``plugins`` line in
-``/etc/bcfg2.conf`` on your Bcfg server. For example::
-
- plugins = Base,Bundler,Cfg,...,TCheetah
-
-The ``TCheetah`` plugin makes use of a ``Cfg``-like directory structure
-located in in a ``TCheetah`` subdirectory of your repository, usually
-``/var/lib/bcfg2/TCheetah``. Each file has a directory containing two
-files, ``template`` and ``info``. The template is a standard Cheetah
-template with two additions:
-
-* `self.metadata` is the client's :ref:`metadata <server-plugins-grouping-metadata-clientmetadata>`
-* `self.metadata.Properties.xdata` is an xml document of unstructured data
-
-The ``info`` file is formatted like ``:info`` files from Cfg.
-
-Mostly, people will want to use client metadata.
-
-File permissions
-================
-
-File permissions for entries handled by TCheetah are controlled via the
-use of :ref:`server-info` files. Note that you **cannot** use both a
-Permissions entry and a Path entry to handle the same file.
-
-self.metadata variables
-=======================
-
-self.metadata is an instance of the class ClientMetadata and documented
-:ref:`here <server-plugins-grouping-metadata-clientmetadata>`.
-
-self.metadata.Properties.xdata
-==============================
-
-.. note::
-
- If you want to use Properties, you will need to enable the
- :ref:`server-plugins-connectors-properties` plugin in
- ``/etc/bcfg2.conf``.
-
-Properties.xdata is a python `ElementTree <http://codespeak.net/lxml/>`_
-object, loaded from the data in ``/var/lib/bcfg2/Properties/<properties
-file>.xml``. That file should have a ``Properties`` node at its root.
-
-Example ``Properties/example.xml``:
-
-.. code-block:: xml
-
- <Properties>
- <host>
- <www.example.com>
- <rootdev>/dev/sda</rootdev>
- </www.example.com>
- </host>
- </Properties>
-
-You may use any of the ElementTree methods to access data in your
-template. Several examples follow, each producing an identical result
-on the host 'www.example.com'::
-
- $self.metadata.Properties['example.xml'].xdata.find('host').find('www.example.com').find('rootdev').text
- $self.metadata.Properties['example.xml'].xdata.find('host').find($self.metadata.hostname).find('rootdev').text
- ${self.metadata.Properties['example.xml'].xdata.xpath('host/www.example.com/rootdev')[0].text}
- ${self.metadata.Properties['example.xml'].xdata.xpath('host/' + self.metadata.hostname + '/rootdev')[0].text}
- #set $path = 'host/' + $self.metadata.hostname + '/rootdev'
- ${self.metadata.Properties['example.xml'].xdata.xpath($path)[0].text}
- ${self.metadata.Properties['example.xml'].xdata.xpath(path)[0].text}
-
-Other Variables
-===============
-
-* **Template.searchList(self)[1]['path']** is the Path name specified in a Bundle
-* **Template.searchList(self)[1]['source_path']** is the path to the TCheetah template on the Bcfg2 server
-
-Simple Example
-==============
-
-TCheetah works similar to Cfg in that you define all literal information
-about a particular file in a directory rooted at TGenshi/path_to_file.
-The actual file contents are placed in a file named `template` in that
-directory. Below is a simple example a file ``/foo``.
-
-``/var/lib/bcfg2/TCheetah/foo/template``
-
-.. code-block:: none
-
- > buildfile /foo <clientname>
- Hostname is $self.metadata.hostname
- Filename is $Template.searchList(self)[1]['path']
- Template is $Template.searchList(self)[1]['source_path']
- Groups:
- #for $group in $self.metadata.groups:
- * $group
- #end for
- Categories:
- #for $category in $self.metadata.categories:
- * $category -- $self.metadata.categories[$category]
- #end for
-
- Probes:
- #for $probe in $self.metadata.Probes:
- * $probe -- $self.metadata.Probes[$probe]
- #end for
-
-``/var/lib/bcfg2/TCheetah/foo/info``
-
-.. code-block:: none
-
- mode: 624
-
-Output
-------
-
-The following output can be generated with bcfg2-info. Note that probe
-information is not persistent, hence, it only works when clients directly
-query the server. For this reason, bcfg2-info output doesn't reflect
-current client probe state.
-
-.. code-block:: xml
-
- <Path type="file" name="/foo" owner="root" mode="0624" group="root">
- Hostname is topaz.mcs.anl.gov
- Filename is /foo
- Template is /var/lib/bcfg2/TCheetah/foo/template
- Groups:
- * desktop
- * mcs-base
- * ypbound
- * workstation
- * xserver
- * debian-sarge
- * debian
- * a
- Categories:
- * test -- a
-
- Probes:
- </Path>
-
-Example: Replace the crontab plugin
-===================================
-
-In many cases you can use the TCheetah plugin to avoid writing custom
-plugins in Python. This example randomizes the time of cron.daily
-execution with a stable result. Cron.daily is run at a consistent,
-randomized time between midnight and 7am.::
-
- #import random
- #silent random.seed($self.metadata.hostname)
-
- # /etc/crontab: system-wide crontab
- # Unlike any other crontab you don't have to run the `crontab`
- # command to install the new version when you edit this file.
- # This file also has a username field, that none of the other crontabs do.
-
- SHELL=/bin/sh
- PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin://bin
-
- # m h dom mon dow user command
- 17 * * * * root run-parts --report /etc/cron.hourly
- $random.randrange(0,59) $random.randrange(0,6) * * * root test -x /usr/sbin/anacron || run-parts --report /etc/cron.daily
- 47 6 * * 7 root test -x /usr/sbin/anacron || run-parts --report /etc/cron.weekly
- 52 6 1 * * root test -x /usr/sbin/anacron || run-parts --report /etc/cron.monthly.
-
-.. note:: Comments and Cheetah
- As Cheetah processes your templates it will consider hash "#" style
- comments to be actual comments in the template and will strip them
- from the final config file. If you would like to preserve the comment
- in the final config file you need to escape the hash character '\#'
- which will tell Cheetah (and Python) that you do in fact want the
- comment to appear in the final config file.::
-
- # This is a comment in my template which will be stripped when it's processed through Cheetah
- \# This comment will appear in the generated config file.
diff --git a/doc/server/plugins/generators/tgenshi.txt b/doc/server/plugins/generators/tgenshi.txt
deleted file mode 100644
index 43a02f253..000000000
--- a/doc/server/plugins/generators/tgenshi.txt
+++ /dev/null
@@ -1,213 +0,0 @@
-.. -*- mode: rst -*-
-
-.. _server-plugins-generators-tgenshi-index:
-
-=======
-TGenshi
-=======
-
-.. warning::
-
- The TGenshi plugin is deprecated. You should instead use
- :ref:`server-plugins-generators-cfg-genshi` in the Cfg plugin.
-
-This page documents the TGenshi plugin. This plugin works with version
-0.4 and newer of the genshi library.
-
-The TGenshi plugin allows you to use the `Genshi
-<http://genshi.edgewall.org>`_ templating system to create files,
-instead of the various diff-based methods offered by the Cfg
-plugin. It also allows you to include the results of probes executed
-on the client in the created files.
-
-To begin, you will need to download and install the Genshi templating engine.
-
-To install on CentOS or RHEL, run::
-
- sudo yum install python-genshi
-
-Once it is installed, you can enable it by adding ``TGenshi`` to the
-generators line in ``/etc/bcfg2.conf`` on your Bcfg server. For example::
-
- plugins = Base,Bundler,Cfg,...,TGenshi
-
-The TGenshi plugin makes use of a Cfg-like directory structure
-located in in a TGenshi subdirectory of your repository, usually
-``/var/lib/bcfg2/TGenshi``. Each file has a directory containing two file
-types, template and info. Templates are named according to the genshi
-format used; template.txt uses the genshi text format, and template.xml
-uses the XML format.
-
-If used with Genshi 0.5 or later the plugin also supports the `new
-style
-<http://genshi.edgewall.org/wiki/Documentation/0.5.x/text-templates.html>`_
-text template format for files named template.newtxt. One of the
-advantages of the new format is that it does not use # as a command
-delimiter, making it easier to utilize for configuration files that
-use # as a comment character.
-
-Only one template format may be used per file served. Info files are
-identical to those used in ``Cfg``, and ``info.xml`` files are
-supported.
-
-Inside of templates
-===================
-
-* **metadata** is the client's :ref:`metadata
- <server-plugins-grouping-metadata-clientmetadata>`
-* **metadata.Properties** is an xml document of unstructured data (only
- available when used in conjunction with the
- :ref:`server-plugins-connectors-properties` plugin)
-* **name** is the path name specified in bcfg
-* **path** is the path to the TGenshi template. It starts with a
- leading slash, and is relative to the Bcfg2 specification root.
- E.g., ``/Cfg/etc/foo.conf/foo.conf.genshi`` or
- ``/TGenshi/etc/foo.conf/template.newtxt.H_foo.example.com``
-
-See the genshi `documentation
-<http://genshi.edgewall.org/wiki/Documentation>`_ for examples of
-Genshi syntax.
-
-Examples: Old Genshi Syntax
----------------------------
-
-Genshi's web pages recommend against using this syntax, as it may
-disappear from future releases.
-
-Group Negation
-^^^^^^^^^^^^^^
-
-Templates are also useful for cases where more sophisticated boolean
-operations than those supported by Cfg are needed. For example, the
-template::
-
- #if "ypbound" in metadata.groups and "workstation" in metadata.groups
- client is ypbound workstation
- #end
- #if "ubuntu" not in metadata.groups and "desktop" in metadata.groups
- client is a desktop, but not an ubuntu desktop
- #end
-
-Produces:
-
-.. code-block:: xml
-
- <Path type="file" name="/bar.conf" owner="root" mode="0644" group="root">client is ypbound workstation
- client is a desktop, but not an ubuntu desktop
- </Path>
-
-This flexibility provides the ability to build much more compact and
-succinct definitions of configuration contents than Cfg can.
-
-Troubleshooting
-===============
-
-When developing a template, you can see what the template would
-generate on a client with :ref:`bcfg2-info <server-bcfg2-info>`::
-
- bcfg2-info buildfile <path> <hostname>
-
-E.g.::
-
- bcfg2-info buildfile /etc/foo.conf foo.example.com
-
-To generate a file with an altsrc attribute, you can run::
-
- bcfg2-info buildfile /etc/foo/foo.conf --altsrc=/etc/foo.conf \
- foo.example.com
-
-Sometimes, it's useful to be able to do more in-depth troubleshooting
-by running the template manually. To do this, run ``bcfg2-info
-debug``, and, once in the Python interpreter, run::
-
- metadata = self.build_metadata("<hostname>")
- path = "<relative path to template (see note below)>"
-
-``path`` should be set to the path to the template file with a leading
-slash, relative to the Bcfg2 specification root. See `Inside of
-Templates`_ for examples.
-
-Then, run::
-
- import os, Bcfg2.Options
- from genshi.template import TemplateLoader, NewTextTemplate
- name = os.path.dirname(path[path.find('/', 1):])
- setup = Bcfg2.Options.OptionParser({'repo':
- Bcfg2.Options.SERVER_REPOSITORY})
- setup.parse('--')
- template = TemplateLoader().load(setup['repo'] + path, cls=NewTextTemplate)
- print template.generate(metadata=metadata, path=path, name=name).render()
-
-This gives you more fine-grained control over how your template is
-rendered.
-
-You can also use this approach to render templates that depend on
-:ref:`altsrc <server-plugins-structures-altsrc>` tags by setting
-``path`` to the path to the template, and setting ``name`` to the path
-to the file to be generated, e.g.::
-
- metadata = self.build_metadata("foo.example.com")
- path = "/Cfg/etc/sysconfig/network-scripts/ifcfg-template/ifcfg-template.genshi"
- name = "/etc/sysconfig/network-scripts/ifcfg-bond0"
-
-File permissions
-================
-
-File permissions for entries handled by TGenshi are controlled via the
-use of :ref:`server-info` files. Note that you **cannot** use both a
-Permissions entry and a Path entry to handle the same file.
-
-Error handling
-================
-
-Situations may arise where a templated file cannot be generated due to
-missing or incomplete information. A TemplateError can be raised to
-force a bind failure and prevent sending an incomplete file to the
-client. For example, this template::
-
- {% python
- from genshi.template import TemplateError
- grp = None
- for g in metadata.groups:
- if g.startswith('ganglia-gmond-'):
- grp = g
- break
- else:
- raise TemplateError, "Missing group"
- %}\
-
-will fail to bind if the client is not a member of a group starting with
-"ganglia-gmond-". The syslogs on the server will contain this message::
-
- bcfg2-server[5957]: Genshi template error: Missing group
- bcfg2-server[5957]: Failed to bind entry: Path /etc/ganglia/gmond.conf
-
-indicating the bind failure and message raised with the TemplateError.
-
-FAQs
-====
-
-**Question**
-
-How do I escape the $ (dollar sign) in a TGenshi text template? For
-example, if I want to include SVN (subversion) keywords like $Id$ or
-$HeadURL$ in TGenshi-generated files, or am templating a bourne shell
-(sh/bash) script or Makefile (make).
-
-**Answer**
-
-Use $$ (double dollar sign) to output a literal $ (dollarsign)
-in a TGenshi text template. So instead of $Id$, you'd use
-$$Id$$. See also Genshi tickets `#282: Document $$ escape
-convention <http://genshi.edgewall.org/ticket/282>`_ and
-`#283: Allow for redefinition of template syntax per-file
-<http://genshi.edgewall.org/ticket/283>`_.
-
-Examples
-========
-
-.. toctree::
- :glob:
- :maxdepth: 1
-
- examples/genshi/*
diff --git a/doc/server/plugins/statistics/statistics.txt b/doc/server/plugins/statistics/statistics.txt
deleted file mode 100644
index d16f5a828..000000000
--- a/doc/server/plugins/statistics/statistics.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-.. -*- mode: rst -*-
-
-.. _server-plugins-statistics-statistics:
-
-==========
-Statistics
-==========
diff --git a/doc/server/plugins/structures/bundler/kernel.txt b/doc/server/plugins/structures/bundler/kernel.txt
index 2e3d84e93..c6aa5e3f3 100644
--- a/doc/server/plugins/structures/bundler/kernel.txt
+++ b/doc/server/plugins/structures/bundler/kernel.txt
@@ -30,7 +30,7 @@ some of which might be better than this one. Feel free to hack as needed.
<Path name='/boot/initrd'/>
<Path name='/boot/vmlinuz.old'/>
<Path name='/boot/initrd.old'/>
- <PostInstall name='/sbin/lilo'/>
+ <Action name='lilo'/>
<!-- Current kernel -->
<Package name='linux-2.4.21-314.tg1'/>
<Package name='linux-2.4.21-314.tg1-source'/>
diff --git a/doc/server/snapshots/index.txt b/doc/server/snapshots/index.txt
deleted file mode 100644
index 13a9fe2c0..000000000
--- a/doc/server/snapshots/index.txt
+++ /dev/null
@@ -1,156 +0,0 @@
-.. -*- mode: rst -*-
-
-.. _server-snapshots-index:
-
-===============
-Bcfg2 Snapshots
-===============
-
-.. versionadded:: 1.0.0
-
-This page describes the Snapshots plugin. This plugin is meant to replace
-the older :ref:`reports-dynamic`. It stores various aspects of a client's
-state when the client checks into the server.
-
-Before you begin
-================
-
-Make sure you have version 0.5 or greater of sqlalchemy.
-
-On CentOS/RHEL 5
-----------------
-
-* Download a tarball of SQLAlchemy.
-* Extract and build the RPM::
-
- tar xzf SQLAlchemy-0.5.6.tar.gz
- cd SQLAlchemy-0.5.6
- python setup.py bdist_rpm
-
-* Copy the RPM in ``SQLAlchemy-0.5.6/dist/`` to your Yum repository,
- and rebuild the repository using ``createrepo``.
-* Clear the Yum cache::
-
- sudo yum clean all
-
-* Install SQLAlchemy::
-
- sudo yum install SQLAlchemy
-
-* Manage the package in Bcfg2 as you would any other package.
-
-Configuration
-=============
-
-* A database location needs to be added to ``bcfg2.conf``. Three drivers
- are currently supported; mysql, postgres, and sqlite. When using the
- sqlite driver, only the driver and database lines are required.
-
- * For MySQL::
-
- [snapshots]
- driver = mysql
- database = snapshots
- user = snapshots
- password = snapshots
- host = dbserver
-
- * For SQLite::
-
- [snapshots]
- driver = sqlite
- database = /var/lib/bcfg2/var/snapshots.sqlite
-
-* The database needs to be initialized.::
-
- $ bcfg2-admin snapshots init
- 2009-03-22 21:40:24,683 INFO sqlalchemy.engine.base.Engine.0x...3e2c PRAGMA table_info("connkeyval")
- PRAGMA table_info("connkeyval")
- 2009-03-22 21:40:24,684 INFO sqlalchemy.engine.base.Engine.0x...3e2c ()
- ()
- 2009-03-22 21:40:24,686 INFO sqlalchemy.engine.base.Engine.0x...3e2c PRAGMA table_info("package")
- PRAGMA table_info("package")
- 2009-03-22 21:40:24,687 INFO sqlalchemy.engine.base.Engine.0x...3e2c ()
- ()
- .....
- COMMIT
-
-* The Snapshots plugin needs to be enabled for the bcfg2-server (by adding
- Snapshots to the plugins line in ``/etc/bcfg2.conf``). Once done,
- this will cause the the server to store statistics information when
- clients run.
-
-Using the reports interface
-===========================
-
-All hosts::
-
- $ bcfg2-admin snapshots reports -a
-
- ============= ========= ========================================== ============================
- Client Correct Revision Time
- ============= ========= ========================================== ============================
- bcfg2client True f46ac7773712bd3c3cfb765ae5d2a3b2a37ac9b7 2009-04-23 11:27:54.378941
- ============= ========= ========================================== ============================
-
-List bad entries for a single host::
-
- $ bcfg2-admin snapshots reports -b bcfg2client
- Bad entries:
- Package:nscd
- Package:cupsys
- File:/etc/ldap.conf
-
-List extra entries for a single host::
-
- $ bcfg2-admin snapshots reports -e bcfg2client
- Extra entries:
- Package:python-pyxattr
- Package:librsync1
- Package:python-pylibacl
- Package:gcc-4.2-multilib
- Package:nxlibs
- Package:freenx-session-launcher
- Package:dx-doc
- Package:dirdiff
- Package:libhdf4g
- Package:nxclient
- Package:freenx-rdp
- Package:freenx-vnc
- Package:libxml2-dev
- Package:mysql-client
- Package:mysql-client-5.0
- Package:libxcompext3
- Package:lib32gomp1
- Package:dx
- Package:freenx-media
- Package:dxsamples
- Package:gcc-multilib
- Package:rdiff-backup
- Package:libdbd-mysql-perl
- Package:libxcomp3
- Package:freenx-server
- Package:smbfs
- Package:planner
- Package:nxagent
- Package:libc6-dev-i386
- Package:libfltk1.1-dev
- Package:freenx
- Package:libdx4
- Package:libxcompshad3
- Service:freenx-server
-
-Detailed view of hosts for a particular date::
-
- $ bcfg2-admin snapshots reports --date 2009 5 30
- ============= ========= ========================================== ============================
- Client Correct Revision Time
- ============= ========= ========================================== ============================
- bcfg2client False 10c1a12c62c57c0861cc453b8d2640c4839a7357 2009-05-29 10:52:34.701056
-
-TODO/Wishlist
-=============
-
-* Identify per-client changes in correctness over time
-* Detailed view for a particular date
-* Track entry changes over time (glibc updated on these dates to these versions)
diff --git a/doc/unsorted/index.txt b/doc/unsorted/index.txt
index a369ee1b3..74d045990 100644
--- a/doc/unsorted/index.txt
+++ b/doc/unsorted/index.txt
@@ -13,7 +13,6 @@ list below.
.. _TitleIndex: https://trac.mcs.anl.gov/projects/bcfg2/wiki/TitleIndex
-* `Plugins/Snapshots`
* `PrecompiledPackages`
* `SchemaEvolution`
* `SecurityDevPlan`
diff --git a/examples/TGenshi/etc/dirvish/master.conf/template.newtxt b/examples/Cfg/etc/dirvish/master.conf/master.conf.genshi
index 6c9750f9d..6c9750f9d 100644
--- a/examples/TGenshi/etc/dirvish/master.conf/template.newtxt
+++ b/examples/Cfg/etc/dirvish/master.conf/master.conf.genshi
diff --git a/examples/TGenshi/etc/motd/template.newtxt b/examples/TGenshi/etc/motd/template.newtxt
deleted file mode 100644
index ca3cc5f18..000000000
--- a/examples/TGenshi/etc/motd/template.newtxt
+++ /dev/null
@@ -1,31 +0,0 @@
-------------------------------------------------------------------------
- GOALS FOR SERVER MANAGED BY BCFG2
-------------------------------------------------------------------------
-Hostname is ${metadata.hostname}
-
-Groups:
-{% for group in metadata.groups %}\
- * ${group}
-{% end %}\
-
-{% if metadata.categories %}\
-Categories:
-{% for category in metadata.categories %}\
- * ${category}
-{% end %}\
-{% end %}\
-
-
-{% if metadata.Probes %}\
-Probes:
-{% for probe, value in metadata.Probes.iteritems() %}\
- * ${probe} \
- ${value}
-{% end %}\
-{% end %}\
-
-------------------------------------------------------------------------
- ITOPS MOTD
-------------------------------------------------------------------------
-Please create a Ticket for any system level changes you need from IT.
-
diff --git a/examples/TGenshi/tmp/bar/template.txt b/examples/TGenshi/tmp/bar/template.txt
deleted file mode 100644
index dbf482c22..000000000
--- a/examples/TGenshi/tmp/bar/template.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-[communication]
-protocol = xmlrpc/ssl
-#if metadata.uuid != None
-user = $metadata.uuid
-#end
-#choose
-#when metadata.password is not None
-password = $metadata.password
-#end
-#when metadata.password is None
-password = GlobalPassword
-#end
-#end
-
-[client]
-drivers = Action,Chkconfig,POSIX,YUMng
-
-[components]
-bcfg2 = https://config.example.com:6789
diff --git a/examples/TGenshi/tmp/foo/template.xml b/examples/TGenshi/tmp/foo/template.xml
deleted file mode 100644
index 522c6e7fe..000000000
--- a/examples/TGenshi/tmp/foo/template.xml
+++ /dev/null
@@ -1,46 +0,0 @@
-<html xmlns:py="http://genshi.edgewall.org/">
- <head>
- <title>${name}</title>
- </head>
- <body>
- <table>
- <tr><th>Name:</th><td>${name}</td></tr>
- <tr><th>Hostname:</th><td>${metadata.hostname}</td></tr>
- <tr><th>Toolset:</th><td>${metadata.hostname}</td></tr>
- <tr><th>UUID:</th><td>${metadata.uuid}</td></tr>
- <tr><th>Password:</th><td>${metadata.password}</td></tr>
- <tr>
- <th>Bundles:</th>
- <td>
- <table>
- <tr py:for="bundle in metadata.bundles"><td>${bundle}</td></tr>
- </table>
- </td>
- </tr>
- <tr>
- <th>Groups:</th>
- <td>
- <table>
- <tr py:for="group in metadata.groups"><td>${group}</td></tr>
- </table>
- </td>
- </tr>
- <tr>
- <th>Categories:</th>
- <td>
- <table>
- <tr py:for="category in metadata.categories"><td>${category}</td></tr>
- </table>
- </td>
- </tr>
- <tr>
- <th>Probes:</th>
- <td>
- <table>
- <tr py:for="probe in metadata.probes"><td>${probe}</td><td>${metadata.probes[probe]}</td></tr>
- </table>
- </td>
- </tr>
- </table>
- </body>
-</html>
diff --git a/examples/bcfg2.confHostbase b/examples/bcfg2.confHostbase
deleted file mode 100644
index c9420e34a..000000000
--- a/examples/bcfg2.confHostbase
+++ /dev/null
@@ -1,33 +0,0 @@
-[server]
-repository = /var/lib/bcfg2
-plugins = Bundler,Rules,Metadata,SSHbase,Cfg
-
-[statistics]
-sendmailpath = /usr/sbin/sendmail
-
-[communication]
-protocol = xmlrpc/ssl
-password = foobat
-key = /etc/bcfg2.key
-
-[components]
-bcfg2 = https://localhost:6789
-
-[hostbase]
-# postgresql, mysql, sqlite3 or ado_mssql
-database_engine = mysql
-# Or path to database file if using sqlite3.
-database_name =
-# Not used with sqlite3.
-database_user =
-# Not used with sqlite3.
-database_password =
-# Set to empty string for localhost. Not used with sqlite3.
-database_host =
-# Set to empty string for default. Not used with sqlite3.
-database_port = 3306
-# enter an NIS group name you'd like to give access to edit hostbase records
-##authorized_group = support
-# default mx record for new hosts added to the database
-default_mx = mailserver.yourdomain.net
-priority = 30
diff --git a/misc/bcfg2.spec b/misc/bcfg2.spec
index a798471af..1530682a9 100644
--- a/misc/bcfg2.spec
+++ b/misc/bcfg2.spec
@@ -357,7 +357,6 @@ touch %{buildroot}%{_sysconfdir}/bcfg2.conf %{buildroot}%{_sysconfdir}/bcfg2-web
%{python_sitelib}/*egg-info
%dir %{_datadir}/bcfg2
-%{_datadir}/bcfg2/Hostbase
%{_datadir}/bcfg2/schemas
%{_datadir}/bcfg2/xsl-transforms
%config(noreplace) %{_sysconfdir}/default/bcfg2-server
diff --git a/osx/Makefile b/osx/Makefile
index dd6f19e2e..3757b0ad7 100644
--- a/osx/Makefile
+++ b/osx/Makefile
@@ -5,8 +5,7 @@ PREFLIGHT = preflight
POSTFLIGHT = postflight
PKGROOT = bcfg2pkg
PKGTMP = bcfg2tmp
-FILTERS = --filter Hostbase \
---filter Reports \
+FILTERS = --filter Reports \
--filter Server \
--filter xsd \
--filter xsl \
diff --git a/osx/macports/files/patch-setup.py.diff b/osx/macports/files/patch-setup.py.diff
index f78d27e5c..ececb8a33 100644
--- a/osx/macports/files/patch-setup.py.diff
+++ b/osx/macports/files/patch-setup.py.diff
@@ -1,6 +1,6 @@
--- setup.py 2010-11-15 15:30:28.000000000 -0600
+++ setup.py.macports 2010-11-18 19:06:49.155292524 -0600
-@@ -11,47 +11,22 @@
+@@ -11,38 +11,22 @@
setup(cmdclass=cmdclass,
name="Bcfg2",
version="1.1.1",
@@ -14,13 +14,10 @@
"Bcfg2.Client.Tools",
- 'Bcfg2.Server',
- "Bcfg2.Server.Admin",
-- "Bcfg2.Server.Hostbase",
-- "Bcfg2.Server.Hostbase.hostbase",
- "Bcfg2.Server.Plugins",
- "Bcfg2.Server.Reports",
- "Bcfg2.Server.Reports.reports",
- "Bcfg2.Server.Reports.reports.templatetags",
-- "Bcfg2.Server.Snapshots",
],
+ py_modules = ["Bcfg2.Options",
+ "Bcfg2.Proxy",
@@ -51,11 +48,5 @@
- glob('src/lib/Server/Reports/reports/templates/clients/*')),
- ('share/bcfg2/Reports/templates/config_items',
- glob('src/lib/Server/Reports/reports/templates/config_items/*')),
-- ('share/bcfg2/Hostbase/templates',
-- glob('src/lib/Server/Hostbase/hostbase/webtemplates/*.*')),
-- ('share/bcfg2/Hostbase/templates/hostbase',
-- glob('src/lib/Server/Hostbase/hostbase/webtemplates/hostbase/*')),
-- ('share/bcfg2/Hostbase/repo',
-- glob('src/lib/Server/Hostbase/templates/*')),
]
)
diff --git a/schemas/bundle.xsd b/schemas/bundle.xsd
index 68e793920..863e10b4b 100644
--- a/schemas/bundle.xsd
+++ b/schemas/bundle.xsd
@@ -35,10 +35,7 @@
<xsd:annotation>
<xsd:documentation>
Abstract implementation of a Path entry. The entry will
- either be handled by Cfg, TGenshi, or another
- Generator plugin; or handled by Rules, in which case
- the full specification of this entry will be included in
- Rules.
+ be handled by a Generator plugin, like Cfg or Rules.
</xsd:documentation>
</xsd:annotation>
</xsd:element>
@@ -80,15 +77,6 @@
</xsd:documentation>
</xsd:annotation>
</xsd:element>
- <xsd:element name='PostInstall' type='StructureEntry'>
- <xsd:annotation>
- <xsd:documentation>
- PostInstall entries are deprecated in favor of Action
- entries. Actions can do everything PostInstall entries can
- do and more.
- </xsd:documentation>
- </xsd:annotation>
- </xsd:element>
<xsd:element name='BoundPackage' type='PackageType'>
<xsd:annotation>
<xsd:documentation>
diff --git a/schemas/rules.xsd b/schemas/rules.xsd
index ddfb7ad0d..be60abef0 100644
--- a/schemas/rules.xsd
+++ b/schemas/rules.xsd
@@ -13,10 +13,6 @@
<xsd:import namespace="http://genshi.edgewall.org/"
schemaLocation="genshi.xsd"/>
- <xsd:complexType name='PostInstallType'>
- <xsd:attribute type='xsd:string' name='name' use='required'/>
- </xsd:complexType>
-
<xsd:group name="rulesElements">
<xsd:choice>
<xsd:group ref="py:genshiElements"/>
@@ -126,15 +122,6 @@
</xsd:documentation>
</xsd:annotation>
</xsd:element>
- <xsd:element name='PostInstall' type='PostInstallType'>
- <xsd:annotation>
- <xsd:documentation>
- PostInstall entries are deprecated in favor of Action
- entries. Actions can do everything PostInstall entries can
- do and more.
- </xsd:documentation>
- </xsd:annotation>
- </xsd:element>
<xsd:element name='Group' type='RContainerType'>
<xsd:annotation>
<xsd:documentation>
diff --git a/setup.py b/setup.py
index 509615627..b003d6440 100755
--- a/setup.py
+++ b/setup.py
@@ -41,8 +41,6 @@ setup(name="Bcfg2",
'Bcfg2.Server',
"Bcfg2.Server.Admin",
"Bcfg2.Server.FileMonitor",
- "Bcfg2.Server.Hostbase",
- "Bcfg2.Server.Hostbase.hostbase",
"Bcfg2.Server.Lint",
"Bcfg2.Server.Plugin",
"Bcfg2.Server.Plugins",
@@ -50,7 +48,6 @@ setup(name="Bcfg2",
"Bcfg2.Server.Plugins.Cfg",
"Bcfg2.Server.Reports",
"Bcfg2.Server.Reports.reports",
- "Bcfg2.Server.Snapshots",
],
install_requires=inst_reqs,
tests_require=['mock', 'nose', 'sqlalchemy'],
@@ -69,12 +66,6 @@ setup(name="Bcfg2",
('share/man/man1', glob("man/bcfg2.1")),
('share/man/man5', glob("man/*.5")),
('share/man/man8', glob("man/*.8")),
- ('share/bcfg2/Hostbase/templates',
- glob('src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/*.*')),
- ('share/bcfg2/Hostbase/templates/hostbase',
- glob('src/lib/Bcfg2/Server/Hostbase/hostbase/webtemplates/hostbase/*')),
- ('share/bcfg2/Hostbase/repo',
- glob('src/lib/Bcfg2/Server/Hostbase/templates/*')),
('share/bcfg2/site_media',
glob('reports/site_media/*')),
]
diff --git a/solaris/prototype.bcfg2 b/solaris/prototype.bcfg2
index 21b6cb564..46483381f 100644
--- a/solaris/prototype.bcfg2
+++ b/solaris/prototype.bcfg2
@@ -13,7 +13,7 @@ d none lib/PYVERSION/site-packages/Bcfg2/Client/Tools 0755 bin bin
f none lib/PYVERSION/site-packages/Bcfg2/Client/Tools/Action.py 0644 bin bin
f none lib/PYVERSION/site-packages/Bcfg2/Client/Tools/IPS.py 0644 bin bin
f none lib/PYVERSION/site-packages/Bcfg2/Client/Tools/FreeBSDInit.py 0644 bin bin
-f none lib/PYVERSION/site-packages/Bcfg2/Client/Tools/RPMng.py 0644 bin bin
+f none lib/PYVERSION/site-packages/Bcfg2/Client/Tools/RPM.py 0644 bin bin
f none lib/PYVERSION/site-packages/Bcfg2/Client/Tools/Chkconfig.py 0644 bin bin
f none lib/PYVERSION/site-packages/Bcfg2/Client/Tools/RcUpdate.py 0644 bin bin
f none lib/PYVERSION/site-packages/Bcfg2/Client/Tools/APT.py 0644 bin bin
@@ -24,7 +24,7 @@ f none lib/PYVERSION/site-packages/Bcfg2/Client/Tools/rpmtools.py 0644 bin bin
f none lib/PYVERSION/site-packages/Bcfg2/Client/Tools/launchd.py 0644 bin bin
f none lib/PYVERSION/site-packages/Bcfg2/Client/Tools/FreeBSDPackage.py 0644 bin bin
f none lib/PYVERSION/site-packages/Bcfg2/Client/Tools/Blast.py 0644 bin bin
-f none lib/PYVERSION/site-packages/Bcfg2/Client/Tools/YUMng.py 0644 bin bin
+f none lib/PYVERSION/site-packages/Bcfg2/Client/Tools/YUM.py 0644 bin bin
f none lib/PYVERSION/site-packages/Bcfg2/Client/Tools/Portage.py 0644 bin bin
f none lib/PYVERSION/site-packages/Bcfg2/Client/Tools/DebInit.py 0644 bin bin
f none lib/PYVERSION/site-packages/Bcfg2/Client/Tools/Encap.py 0644 bin bin
diff --git a/solaris/prototype.bcfg2-server b/solaris/prototype.bcfg2-server
index 590175329..0a1ff64e4 100644
--- a/solaris/prototype.bcfg2-server
+++ b/solaris/prototype.bcfg2-server
@@ -8,7 +8,6 @@ d none lib/PYVERSION/site-packages/Bcfg2/Server/Admin 0755 bin bin
f none lib/PYVERSION/site-packages/Bcfg2/Server/Admin/Tidy.py 0644 bin bin
f none lib/PYVERSION/site-packages/Bcfg2/Server/Admin/Minestruct.py 0644 bin bin
f none lib/PYVERSION/site-packages/Bcfg2/Server/Admin/__init__.py 0644 bin bin
-f none lib/PYVERSION/site-packages/Bcfg2/Server/Admin/Snapshots.py 0644 bin bin
f none lib/PYVERSION/site-packages/Bcfg2/Server/Admin/Init.py 0644 bin bin
f none lib/PYVERSION/site-packages/Bcfg2/Server/Admin/Group.py 0644 bin bin
f none lib/PYVERSION/site-packages/Bcfg2/Server/Admin/Compare.py 0644 bin bin
@@ -28,28 +27,19 @@ f none lib/PYVERSION/site-packages/Bcfg2/Server/Plugins/GroupPatterns.py 0644 bi
f none lib/PYVERSION/site-packages/Bcfg2/Server/Plugins/SSHbase.py 0644 bin bin
f none lib/PYVERSION/site-packages/Bcfg2/Server/Plugins/Trigger.py 0644 bin bin
f none lib/PYVERSION/site-packages/Bcfg2/Server/Plugins/__init__.py 0644 bin bin
-f none lib/PYVERSION/site-packages/Bcfg2/Server/Plugins/Snapshots.py 0644 bin bin
-f none lib/PYVERSION/site-packages/Bcfg2/Server/Plugins/TCheetah.py 0644 bin bin
-f none lib/PYVERSION/site-packages/Bcfg2/Server/Plugins/Account.py 0644 bin bin
f none lib/PYVERSION/site-packages/Bcfg2/Server/Plugins/Cfg.py 0644 bin bin
-f none lib/PYVERSION/site-packages/Bcfg2/Server/Plugins/Statistics.py 0644 bin bin
f none lib/PYVERSION/site-packages/Bcfg2/Server/Plugins/Metadata.py 0644 bin bin
f none lib/PYVERSION/site-packages/Bcfg2/Server/Plugins/Base.py 0644 bin bin
f none lib/PYVERSION/site-packages/Bcfg2/Server/Plugins/Pkgmgr.py 0644 bin bin
f none lib/PYVERSION/site-packages/Bcfg2/Server/Plugins/Ohai.py 0644 bin bin
f none lib/PYVERSION/site-packages/Bcfg2/Server/Plugins/Properties.py 0644 bin bin
-f none lib/PYVERSION/site-packages/Bcfg2/Server/Plugins/Editor.py 0644 bin bin
f none lib/PYVERSION/site-packages/Bcfg2/Server/Plugins/Bundler.py 0644 bin bin
f none lib/PYVERSION/site-packages/Bcfg2/Server/Plugins/NagiosGen.py 0644 bin bin
f none lib/PYVERSION/site-packages/Bcfg2/Server/Plugins/Deps.py 0644 bin bin
f none lib/PYVERSION/site-packages/Bcfg2/Server/Plugins/Svn.py 0644 bin bin
f none lib/PYVERSION/site-packages/Bcfg2/Server/Plugins/DBStats.py 0644 bin bin
-f none lib/PYVERSION/site-packages/Bcfg2/Server/Plugins/TGenshi.py 0644 bin bin
f none lib/PYVERSION/site-packages/Bcfg2/Server/Plugins/Git.py 0644 bin bin
f none lib/PYVERSION/site-packages/Bcfg2/Server/FileMonitor.py 0644 bin bin
-d none lib/PYVERSION/site-packages/Bcfg2/Server/Snapshots 0755 bin bin
-f none lib/PYVERSION/site-packages/Bcfg2/Server/Snapshots/model.py 0644 bin bin
-f none lib/PYVERSION/site-packages/Bcfg2/Server/Snapshots/__init__.py 0644 bin bin
f none lib/PYVERSION/site-packages/Bcfg2/Server/Core.py 0644 bin bin
f none lib/PYVERSION/site-packages/Bcfg2/__init__.py 0644 bin bin
f none lib/PYVERSION/site-packages/Bcfg2/Statistics.py 0644 bin bin
diff --git a/src/lib/Bcfg2/Client/Tools/Action.py b/src/lib/Bcfg2/Client/Tools/Action.py
index b1a897c81..5aada9c0b 100644
--- a/src/lib/Bcfg2/Client/Tools/Action.py
+++ b/src/lib/Bcfg2/Client/Tools/Action.py
@@ -11,9 +11,8 @@ from Bcfg2.Compat import input # pylint: disable=W0622
class Action(Bcfg2.Client.Tools.Tool):
"""Implement Actions"""
name = 'Action'
- __handles__ = [('PostInstall', None), ('Action', None)]
- __req__ = {'PostInstall': ['name'],
- 'Action': ['name', 'timing', 'when', 'command', 'status']}
+ __handles__ = [('Action', None)]
+ __req__ = {'Action': ['name', 'timing', 'when', 'command', 'status']}
def _action_allowed(self, action):
""" Return true if the given action is allowed to be run by
@@ -66,28 +65,14 @@ class Action(Bcfg2.Client.Tools.Tool):
"""Actions always verify true."""
return True
- def VerifyPostInstall(self, dummy, _):
- """Actions always verify true."""
- return True
-
def InstallAction(self, entry):
"""Run actions as pre-checks for bundle installation."""
if entry.get('timing') != 'post':
return self.RunAction(entry)
return True
- def InstallPostInstall(self, entry):
- """ Install a deprecated PostInstall entry """
- self.logger.warning("Installing deprecated PostInstall entry %s" %
- entry.get("name"))
- return self.InstallAction(entry)
-
def BundleUpdated(self, bundle, states):
"""Run postinstalls when bundles have been updated."""
- for postinst in bundle.findall("PostInstall"):
- if not self._action_allowed(postinst):
- continue
- self.cmd.run(postinst.get('name'))
for action in bundle.findall("Action"):
if action.get('timing') in ['post', 'both']:
if not self._action_allowed(action):
diff --git a/src/lib/Bcfg2/Client/Tools/RPM.py b/src/lib/Bcfg2/Client/Tools/RPM.py
index 3d93149ff..0964fdb80 100644
--- a/src/lib/Bcfg2/Client/Tools/RPM.py
+++ b/src/lib/Bcfg2/Client/Tools/RPM.py
@@ -26,8 +26,6 @@ class RPM(Bcfg2.Client.Tools.PkgTool):
__new_gpg_ireq__ = {'Package': ['name'],
'Instance': ['version', 'release']}
- conflicts = ['RPMng']
-
pkgtype = 'rpm'
pkgtool = ("rpm --oldpackage --replacepkgs --quiet -U %s", ("%s", ["url"]))
diff --git a/src/lib/Bcfg2/Client/Tools/RPMng.py b/src/lib/Bcfg2/Client/Tools/RPMng.py
deleted file mode 100644
index 0f0e4c700..000000000
--- a/src/lib/Bcfg2/Client/Tools/RPMng.py
+++ /dev/null
@@ -1,9 +0,0 @@
-""" RPM driver called 'RPMng' for backwards compat """
-
-from Bcfg2.Client.Tools.RPM import RPM
-
-
-class RPMng(RPM):
- """ RPM driver called 'RPMng' for backwards compat """
- deprecated = True
- name = "RPM"
diff --git a/src/lib/Bcfg2/Client/Tools/YUM.py b/src/lib/Bcfg2/Client/Tools/YUM.py
index c8414b4b2..a0dfe6dd9 100644
--- a/src/lib/Bcfg2/Client/Tools/YUM.py
+++ b/src/lib/Bcfg2/Client/Tools/YUM.py
@@ -126,7 +126,7 @@ class YUM(Bcfg2.Client.Tools.PkgTool):
__req__ = {'Package': ['name'],
'Path': ['type']}
- conflicts = ['YUM24', 'RPM', 'RPMng', 'YUMng']
+ conflicts = ['RPM']
def __init__(self, logger, setup, config):
self.yumbase = self._loadYumBase(setup=setup, logger=logger)
diff --git a/src/lib/Bcfg2/Client/Tools/YUM24.py b/src/lib/Bcfg2/Client/Tools/YUM24.py
deleted file mode 100644
index cd25ecf37..000000000
--- a/src/lib/Bcfg2/Client/Tools/YUM24.py
+++ /dev/null
@@ -1,404 +0,0 @@
-"""This provides bcfg2 support for yum."""
-
-import copy
-import os.path
-import sys
-import yum
-import Bcfg2.Client.XML
-from Bcfg2.Client.Tools.RPM import RPM
-
-
-def build_yname(pkgname, inst):
- """Build yum appropriate package name."""
- ypname = pkgname
- if inst.get('version') != 'any':
- ypname += '-'
- if inst.get('epoch', False):
- ypname += "%s:" % inst.get('epoch')
- if inst.get('version', False) and inst.get('version') != 'any':
- ypname += "%s" % (inst.get('version'))
- if inst.get('release', False) and inst.get('release') != 'any':
- ypname += "-%s" % (inst.get('release'))
- if inst.get('arch', False) and inst.get('arch') != 'any':
- ypname += ".%s" % (inst.get('arch'))
- return ypname
-
-
-class YUM24(RPM):
- """Support for Yum packages."""
- pkgtype = 'yum'
- deprecated = True
- __execs__ = ['/usr/bin/yum', '/var/lib/rpm']
- __handles__ = [('Package', 'yum'),
- ('Package', 'rpm'),
- ('Path', 'ignore')]
-
- __req__ = {'Package': ['name', 'version']}
- __ireq__ = {'Package': ['name']}
- #__ireq__ = {'Package': ['name', 'version']}
-
- __new_req__ = {'Package': ['name'],
- 'Instance': ['version', 'release', 'arch']}
- __new_ireq__ = {'Package': ['name'], \
- 'Instance': []}
- #__new_ireq__ = {'Package': ['name', 'uri'], \
- # 'Instance': ['simplefile', 'version', 'release', 'arch']}
-
- __gpg_req__ = {'Package': ['name', 'version']}
- __gpg_ireq__ = {'Package': ['name', 'version']}
-
- __new_gpg_req__ = {'Package': ['name'],
- 'Instance': ['version', 'release']}
- __new_gpg_ireq__ = {'Package': ['name'],
- 'Instance': ['version', 'release']}
-
- def __init__(self, logger, setup, config):
- RPM.__init__(self, logger, setup, config)
- self.__important__ = self.__important__ + \
- [entry.get('name') for struct in config \
- for entry in struct \
- if entry.tag in ['Path', 'ConfigFile'] and \
- (entry.get('name').startswith('/etc/yum.d') \
- or entry.get('name').startswith('/etc/yum.repos.d')) \
- or entry.get('name') == '/etc/yum.conf']
- self.autodep = setup.get("yum24_autodep")
- self.yum_avail = dict()
- self.yum_installed = dict()
- self.yb = yum.YumBase()
- self.yb.doConfigSetup()
- self.yb.doTsSetup()
- self.yb.doRpmDBSetup()
- yup = self.yb.doPackageLists(pkgnarrow='updates')
- if hasattr(self.yb.rpmdb, 'pkglist'):
- yinst = self.yb.rpmdb.pkglist
- else:
- yinst = self.yb.rpmdb.getPkgList()
- for dest, source in [(self.yum_avail, yup.updates),
- (self.yum_installed, yinst)]:
- for pkg in source:
- if dest is self.yum_avail:
- pname = pkg.name
- data = {pkg.arch: (pkg.epoch, pkg.version, pkg.release)}
- else:
- pname = pkg[0]
- if pkg[1] is None:
- a = 'noarch'
- else:
- a = pkg[1]
- if pkg[2] is None:
- e = '0'
- else:
- e = pkg[2]
- data = {a: (e, pkg[3], pkg[4])}
- if pname in dest:
- dest[pname].update(data)
- else:
- dest[pname] = dict(data)
-
- def VerifyPackage(self, entry, modlist):
- pinned_version = None
- if entry.get('version', False) == 'auto':
- # old style entry; synthesize Instances from current installed
- if entry.get('name') not in self.yum_installed and \
- entry.get('name') not in self.yum_avail:
- # new entry; fall back to default
- entry.set('version', 'any')
- else:
- data = copy.copy(self.yum_installed[entry.get('name')])
- if entry.get('name') in self.yum_avail:
- # installed but out of date
- data.update(self.yum_avail[entry.get('name')])
- for (arch, (epoch, vers, rel)) in list(data.items()):
- x = Bcfg2.Client.XML.SubElement(entry, "Instance",
- name=entry.get('name'),
- version=vers, arch=arch,
- release=rel, epoch=epoch)
- if 'verify_flags' in entry.attrib:
- x.set('verify_flags', entry.get('verify_flags'))
- if 'verify' in entry.attrib:
- x.set('verify', entry.get('verify'))
-
- if entry.get('type', False) == 'yum':
- # Check for virtual provides or packages. If we don't have
- # this package use Yum to resolve it to a real package name
- knownPkgs = list(self.yum_installed.keys()) + list(self.yum_avail.keys())
- if entry.get('name') not in knownPkgs:
- # If the package name matches something installed
- # or available the that's the correct package.
- try:
- pkgDict = dict([(i.name, i) for i in \
- self.yb.returnPackagesByDep(entry.get('name'))])
- except yum.Errors.YumBaseError:
- e = sys.exc_info()[1]
- self.logger.error('Yum Error Depsolving for %s: %s' % \
- (entry.get('name'), str(e)))
- pkgDict = {}
-
- if len(pkgDict) > 1:
- # What do we do with multiple packages?
- s = "YUM24: returnPackagesByDep(%s) returned many packages"
- self.logger.info(s % entry.get('name'))
- s = "YUM24: matching packages: %s"
- self.logger.info(s % str(list(pkgDict.keys())))
- pkgs = set(pkgDict.keys()) & set(self.yum_installed.keys())
- if len(pkgs) > 0:
- # Virtual packages matches an installed real package
- pkg = pkgDict[pkgs.pop()]
- s = "YUM24: chosing: %s" % pkg.name
- self.logger.info(s)
- else:
- # What's the right package? This will fail verify
- # and Yum should Do The Right Thing on package install
- pkg = None
- elif len(pkgDict) == 1:
- pkg = list(pkgDict.values())[0]
- else: # len(pkgDict) == 0
- s = "YUM24: returnPackagesByDep(%s) returned no results"
- self.logger.info(s % entry.get('name'))
- pkg = None
-
- if pkg is not None:
- s = "YUM24: remapping virtual package %s to %s"
- self.logger.info(s % (entry.get('name'), pkg.name))
- entry.set('name', pkg.name)
-
- return RPM.VerifyPackage(self, entry, modlist)
-
- def Install(self, packages, states):
- """
- Try and fix everything that YUM24.VerifyPackages() found wrong for
- each Package Entry. This can result in individual RPMs being
- installed (for the first time), deleted, downgraded
- or upgraded.
-
- NOTE: YUM can not reinstall a package that it thinks is already
- installed.
-
- packages is a list of Package Elements that has
- states[<Package Element>] == False
-
- The following effects occur:
- - states{} is conditionally updated for each package.
- - self.installed{} is rebuilt, possibly multiple times.
- - self.instance_status{} is conditionally updated for each instance
- of a package.
- - Each package will be added to self.modified[] if its states{}
- entry is set to True.
-
- """
- self.logger.info('Running YUM24.Install()')
-
- install_pkgs = []
- gpg_keys = []
- upgrade_pkgs = []
-
- # Remove extra instances.
- # Can not reverify because we don't have a package entry.
- if len(self.extra_instances) > 0:
- if (self.setup.get('remove') == 'all' or \
- self.setup.get('remove') == 'packages'):
- self.Remove(self.extra_instances)
- else:
- self.logger.info("The following extra package instances will be removed by the '-r' option:")
- for pkg in self.extra_instances:
- for inst in pkg:
- self.logger.info(" %s %s" % \
- ((pkg.get('name'), self.str_evra(inst))))
-
- # Figure out which instances of the packages actually need something
- # doing to them and place in the appropriate work 'queue'.
- for pkg in packages:
- insts = [pinst for pinst in pkg \
- if pinst.tag in ['Instance', 'Package']]
- if insts:
- for inst in insts:
- if self.FixInstance(inst, self.instance_status[inst]):
- if self.instance_status[inst].get('installed', False) \
- == False:
- if pkg.get('name') == 'gpg-pubkey':
- gpg_keys.append(inst)
- else:
- install_pkgs.append(inst)
- elif self.instance_status[inst].get('version_fail', \
- False) == True:
- upgrade_pkgs.append(inst)
- else:
- install_pkgs.append(pkg)
-
- # Install GPG keys.
- # Alternatively specify the required keys using 'gpgkey' in the
- # repository definition in yum.conf. YUM will install the keys
- # automatically.
- if len(gpg_keys) > 0:
- for inst in gpg_keys:
- self.logger.info("Installing GPG keys.")
- if inst.get('simplefile') is None:
- self.logger.error("GPG key has no simplefile attribute")
- continue
- key_arg = os.path.join(self.instance_status[inst].get('pkg').get('uri'), \
- inst.get('simplefile'))
- cmdrc, output = self.cmd.run("rpm --import %s" % key_arg)
- if cmdrc != 0:
- self.logger.debug("Unable to install %s-%s" % \
- (self.instance_status[inst].get('pkg').get('name'), \
- self.str_evra(inst)))
- else:
- self.logger.debug("Installed %s-%s-%s" % \
- (self.instance_status[inst].get('pkg').get('name'), \
- inst.get('version'), inst.get('release')))
- self.RefreshPackages()
- self.gpg_keyids = self.getinstalledgpg()
- pkg = self.instance_status[gpg_keys[0]].get('pkg')
- states[pkg] = self.VerifyPackage(pkg, [])
-
- # Install packages.
- if len(install_pkgs) > 0:
- self.logger.info("Attempting to install packages")
-
- if self.autodep:
- pkgtool = "/usr/bin/yum -d0 -y install %s"
- else:
- pkgtool = "/usr/bin/yum -d0 install %s"
-
- install_args = []
- for inst in install_pkgs:
- pkg_arg = self.instance_status[inst].get('pkg').get('name')
- install_args.append(build_yname(pkg_arg, inst))
-
- cmdrc, output = self.cmd.run(pkgtool % " ".join(install_args))
- if cmdrc == 0:
- # The yum command succeeded. All packages installed.
- self.logger.info("Single Pass for Install Succeeded")
- self.RefreshPackages()
- else:
- # The yum command failed. No packages installed.
- # Try installing instances individually.
- self.logger.error("Single Pass Install of Packages Failed")
- installed_instances = []
- for inst in install_pkgs:
- pkg_arg = build_yname(self.instance_status[inst].get('pkg').get('name'), inst)
-
- cmdrc, output = self.cmd.run(pkgtool % pkg_arg)
- if cmdrc == 0:
- installed_instances.append(inst)
- else:
- self.logger.debug("%s %s would not install." % \
- (self.instance_status[inst].get('pkg').get('name'), \
- self.str_evra(inst)))
- self.RefreshPackages()
-
- # Fix upgradeable packages.
- if len(upgrade_pkgs) > 0:
- self.logger.info("Attempting to upgrade packages")
-
- if self.autodep:
- pkgtool = "/usr/bin/yum -d0 -y update %s"
- else:
- pkgtool = "/usr/bin/yum -d0 update %s"
-
- upgrade_args = []
- for inst in upgrade_pkgs:
- pkg_arg = build_yname(self.instance_status[inst].get('pkg').get('name'), inst)
- upgrade_args.append(pkg_arg)
-
- cmdrc, output = self.cmd.run(pkgtool % " ".join(upgrade_args))
- if cmdrc == 0:
- # The yum command succeeded. All packages installed.
- self.logger.info("Single Pass for Install Succeeded")
- self.RefreshPackages()
- else:
- # The yum command failed. No packages installed.
- # Try installing instances individually.
- self.logger.error("Single Pass Install of Packages Failed")
- installed_instances = []
- for inst in upgrade_pkgs:
- pkg_arg = build_yname(self.instance_status[inst].get('pkg').get('name'), inst)
- cmdrc, output = self.cmd.run(pkgtool % pkg_arg)
- if cmdrc == 0:
- installed_instances.append(inst)
- else:
- self.logger.debug("%s %s would not install." % \
- (self.instance_status[inst].get('pkg').get('name'), \
- self.str_evra(inst)))
-
- self.RefreshPackages()
-
- if not self.setup['kevlar']:
- for pkg_entry in [p for p in packages if self.canVerify(p)]:
- self.logger.debug("Reverifying Failed Package %s" % (pkg_entry.get('name')))
- states[pkg_entry] = self.VerifyPackage(pkg_entry, \
- self.modlists.get(pkg_entry, []))
-
- for entry in [ent for ent in packages if states[ent]]:
- self.modified.append(entry)
-
- def Remove(self, packages):
- """
- Remove specified entries.
-
- packages is a list of Package Entries with Instances generated
- by FindExtra().
- """
- self.logger.debug('Running YUM24.Remove()')
-
- if self.autodep:
- pkgtool = "/usr/bin/yum -d0 -y erase %s"
- else:
- pkgtool = "/usr/bin/yum -d0 erase %s"
-
- erase_args = []
- for pkg in packages:
- for inst in pkg:
- if pkg.get('name') != 'gpg-pubkey':
- pkg_arg = pkg.get('name') + '-'
- if inst.get('epoch', False):
- pkg_arg = pkg_arg + inst.get('epoch') + ':'
- pkg_arg = pkg_arg + inst.get('version') + '-' + inst.get('release')
- if inst.get('arch', False):
- pkg_arg = pkg_arg + '.' + inst.get('arch')
- erase_args.append(pkg_arg)
- else:
- pkgspec = {'name': pkg.get('name'),
- 'version': inst.get('version'),
- 'release': inst.get('release')}
- self.logger.info("WARNING: gpg-pubkey package not in configuration %s %s"\
- % (pkgspec.get('name'), self.str_evra(pkgspec)))
- self.logger.info(" This package will be deleted in a future version of the YUM24 driver.")
-
- cmdrc, output = self.cmd.run(pkgtool % " ".join(erase_args))
- if cmdrc == 0:
- self.modified += packages
- for pkg in erase_args:
- self.logger.info("Deleted %s" % (pkg))
- else:
- self.logger.info("Bulk erase failed with errors:")
- self.logger.debug("Erase results = %s" % output)
- self.logger.info("Attempting individual erase for each package.")
- for pkg in packages:
- pkg_modified = False
- for inst in pkg:
- if pkg.get('name') != 'gpg-pubkey':
- pkg_arg = pkg.get('name') + '-'
- if 'epoch' in inst.attrib:
- pkg_arg = pkg_arg + inst.get('epoch') + ':'
- pkg_arg = pkg_arg + inst.get('version') + '-' + inst.get('release')
- if 'arch' in inst.attrib:
- pkg_arg = pkg_arg + '.' + inst.get('arch')
- else:
- self.logger.info("WARNING: gpg-pubkey package not in configuration %s %s"\
- % (pkg.get('name'), self.str_evra(pkg)))
- self.logger.info(" This package will be deleted in a future version of the YUM24 driver.")
- continue
-
- cmdrc, output = self.cmd.run(self.pkgtool % pkg_arg)
- if cmdrc == 0:
- pkg_modified = True
- self.logger.info("Deleted %s" % pkg_arg)
- else:
- self.logger.error("unable to delete %s" % pkg_arg)
- self.logger.debug("Failure = %s" % output)
- if pkg_modified == True:
- self.modified.append(pkg)
-
- self.RefreshPackages()
- self.extra = self.FindExtra()
diff --git a/src/lib/Bcfg2/Client/Tools/YUMng.py b/src/lib/Bcfg2/Client/Tools/YUMng.py
deleted file mode 100644
index 22fbba537..000000000
--- a/src/lib/Bcfg2/Client/Tools/YUMng.py
+++ /dev/null
@@ -1,9 +0,0 @@
-""" YUM driver called 'YUMng' for backwards compat """
-
-from Bcfg2.Client.Tools.YUM import YUM
-
-
-class YUMng(YUM):
- """ YUM driver called 'YUMng' for backwards compat """
- deprecated = True
- conflicts = ['YUM24', 'RPM', 'RPMng']
diff --git a/src/lib/Bcfg2/Options.py b/src/lib/Bcfg2/Options.py
index 11c61a634..decb726d0 100644
--- a/src/lib/Bcfg2/Options.py
+++ b/src/lib/Bcfg2/Options.py
@@ -587,33 +587,27 @@ SERVER_UMASK = \
DB_ENGINE = \
Option('Database engine',
default='sqlite3',
- cf=('database', 'engine'),
- deprecated_cf=('statistics', 'database_engine'))
+ cf=('database', 'engine'))
DB_NAME = \
Option('Database name',
default=os.path.join(SERVER_REPOSITORY.default, "etc/bcfg2.sqlite"),
- cf=('database', 'name'),
- deprecated_cf=('statistics', 'database_name'))
+ cf=('database', 'name'))
DB_USER = \
Option('Database username',
default=None,
- cf=('database', 'user'),
- deprecated_cf=('statistics', 'database_user'))
+ cf=('database', 'user'))
DB_PASSWORD = \
Option('Database password',
default=None,
- cf=('database', 'password'),
- deprecated_cf=('statistics', 'database_password'))
+ cf=('database', 'password'))
DB_HOST = \
Option('Database host',
default='localhost',
- cf=('database', 'host'),
- deprecated_cf=('statistics', 'database_host'))
+ cf=('database', 'host'))
DB_PORT = \
Option('Database port',
default='',
- cf=('database', 'port'),
- deprecated_cf=('statistics', 'database_port'))
+ cf=('database', 'port'))
# Django options
WEB_CFILE = \
@@ -635,8 +629,7 @@ DJANGO_DEBUG = \
DJANGO_WEB_PREFIX = \
Option('Web prefix',
default=None,
- cf=('reporting', 'web_prefix'),
- deprecated_cf=('statistics', 'web_prefix'),)
+ cf=('reporting', 'web_prefix'))
# Reporting options
REPORTING_FILE_LIMIT = \
@@ -869,125 +862,65 @@ CLIENT_RPM_INSTALLONLY = \
'kernel-default', 'kernel-largesmp-devel',
'kernel-largesmp', 'kernel-xen', 'gpg-pubkey'],
cf=('RPM', 'installonlypackages'),
- deprecated_cf=('RPMng', 'installonlypackages'),
cook=list_split)
CLIENT_RPM_PKG_CHECKS = \
Option("Perform RPM package checks",
default=True,
cf=('RPM', 'pkg_checks'),
- deprecated_cf=('RPMng', 'pkg_checks'),
cook=get_bool)
CLIENT_RPM_PKG_VERIFY = \
Option("Perform RPM package verify",
default=True,
cf=('RPM', 'pkg_verify'),
- deprecated_cf=('RPMng', 'pkg_verify'),
cook=get_bool)
CLIENT_RPM_INSTALLED_ACTION = \
Option("RPM installed action",
default="install",
- cf=('RPM', 'installed_action'),
- deprecated_cf=('RPMng', 'installed_action'))
+ cf=('RPM', 'installed_action'))
CLIENT_RPM_ERASE_FLAGS = \
Option("RPM erase flags",
default=["allmatches"],
cf=('RPM', 'erase_flags'),
- deprecated_cf=('RPMng', 'erase_flags'),
cook=list_split)
CLIENT_RPM_VERSION_FAIL_ACTION = \
Option("RPM version fail action",
default="upgrade",
- cf=('RPM', 'version_fail_action'),
- deprecated_cf=('RPMng', 'version_fail_action'))
+ cf=('RPM', 'version_fail_action'))
CLIENT_RPM_VERIFY_FAIL_ACTION = \
Option("RPM verify fail action",
default="reinstall",
- cf=('RPM', 'verify_fail_action'),
- deprecated_cf=('RPMng', 'verify_fail_action'))
+ cf=('RPM', 'verify_fail_action'))
CLIENT_RPM_VERIFY_FLAGS = \
Option("RPM verify flags",
default=[],
cf=('RPM', 'verify_flags'),
- deprecated_cf=('RPMng', 'verify_flags'),
cook=list_split)
-CLIENT_YUM24_INSTALLONLY = \
- Option('YUM24 install-only packages',
- default=['kernel', 'kernel-bigmem', 'kernel-enterprise',
- 'kernel-smp', 'kernel-modules', 'kernel-debug',
- 'kernel-unsupported', 'kernel-devel', 'kernel-source',
- 'kernel-default', 'kernel-largesmp-devel',
- 'kernel-largesmp', 'kernel-xen', 'gpg-pubkey'],
- cf=('YUM24', 'installonlypackages'),
- cook=list_split)
-CLIENT_YUM24_PKG_CHECKS = \
- Option("Perform YUM24 package checks",
- default=True,
- cf=('YUM24', 'pkg_checks'),
- cook=get_bool)
-CLIENT_YUM24_PKG_VERIFY = \
- Option("Perform YUM24 package verify",
- default=True,
- cf=('YUM24', 'pkg_verify'),
- cook=get_bool)
-CLIENT_YUM24_INSTALLED_ACTION = \
- Option("YUM24 installed action",
- default="install",
- cf=('YUM24', 'installed_action'))
-CLIENT_YUM24_ERASE_FLAGS = \
- Option("YUM24 erase flags",
- default=["allmatches"],
- cf=('YUM24', 'erase_flags'),
- cook=list_split)
-CLIENT_YUM24_VERSION_FAIL_ACTION = \
- Option("YUM24 version fail action",
- cf=('YUM24', 'version_fail_action'),
- default="upgrade")
-CLIENT_YUM24_VERIFY_FAIL_ACTION = \
- Option("YUM24 verify fail action",
- default="reinstall",
- cf=('YUM24', 'verify_fail_action'))
-CLIENT_YUM24_VERIFY_FLAGS = \
- Option("YUM24 verify flags",
- default=[],
- cf=('YUM24', 'verify_flags'),
- cook=list_split)
-CLIENT_YUM24_AUTODEP = \
- Option("YUM24 autodependency processing",
- default=True,
- cf=('YUM24', 'autodep'),
- cook=get_bool)
CLIENT_YUM_PKG_CHECKS = \
Option("Perform YUM package checks",
default=True,
cf=('YUM', 'pkg_checks'),
- deprecated_cf=('YUMng', 'pkg_checks'),
cook=get_bool)
CLIENT_YUM_PKG_VERIFY = \
Option("Perform YUM package verify",
default=True,
cf=('YUM', 'pkg_verify'),
- deprecated_cf=('YUMng', 'pkg_verify'),
cook=get_bool)
CLIENT_YUM_INSTALLED_ACTION = \
Option("YUM installed action",
default="install",
- cf=('YUM', 'installed_action'),
- deprecated_cf=('YUMng', 'installed_action'))
+ cf=('YUM', 'installed_action'))
CLIENT_YUM_VERSION_FAIL_ACTION = \
Option("YUM version fail action",
default="upgrade",
- cf=('YUM', 'version_fail_action'),
- deprecated_cf=('YUMng', 'version_fail_action'))
+ cf=('YUM', 'version_fail_action'))
CLIENT_YUM_VERIFY_FAIL_ACTION = \
Option("YUM verify fail action",
default="reinstall",
- cf=('YUM', 'verify_fail_action'),
- deprecated_cf=('YUMng', 'verify_fail_action'))
+ cf=('YUM', 'verify_fail_action'))
CLIENT_YUM_VERIFY_FLAGS = \
Option("YUM verify flags",
default=[],
cf=('YUM', 'verify_flags'),
- deprecated_cf=('YUMng', 'verify_flags'),
cook=list_split)
CLIENT_POSIX_UID_WHITELIST = \
Option("UID ranges the POSIXUsers tool will manage",
@@ -1147,15 +1080,6 @@ DRIVER_OPTIONS = \
rpm_version_fail_action=CLIENT_RPM_VERSION_FAIL_ACTION,
rpm_verify_fail_action=CLIENT_RPM_VERIFY_FAIL_ACTION,
rpm_verify_flags=CLIENT_RPM_VERIFY_FLAGS,
- yum24_installonly=CLIENT_YUM24_INSTALLONLY,
- yum24_pkg_checks=CLIENT_YUM24_PKG_CHECKS,
- yum24_pkg_verify=CLIENT_YUM24_PKG_VERIFY,
- yum24_installed_action=CLIENT_YUM24_INSTALLED_ACTION,
- yum24_erase_flags=CLIENT_YUM24_ERASE_FLAGS,
- yum24_version_fail_action=CLIENT_YUM24_VERSION_FAIL_ACTION,
- yum24_verify_fail_action=CLIENT_YUM24_VERIFY_FAIL_ACTION,
- yum24_verify_flags=CLIENT_YUM24_VERIFY_FLAGS,
- yum24_autodep=CLIENT_YUM24_AUTODEP,
yum_pkg_checks=CLIENT_YUM_PKG_CHECKS,
yum_pkg_verify=CLIENT_YUM_PKG_VERIFY,
yum_installed_action=CLIENT_YUM_INSTALLED_ACTION,
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)
diff --git a/src/sbin/bcfg2-build-reports b/src/sbin/bcfg2-build-reports
deleted file mode 100755
index 27e7c2475..000000000
--- a/src/sbin/bcfg2-build-reports
+++ /dev/null
@@ -1,306 +0,0 @@
-#!/usr/bin/env python
-
-"""
-bcfg2-build-reports generates & distributes reports of statistic
-information for Bcfg2."""
-
-import copy
-import getopt
-import re
-import os
-import socket
-import sys
-from time import asctime, strptime
-from lxml.etree import XML, XSLT, parse, Element, ElementTree, SubElement, tostring, XMLSyntaxError
-# Compatibility imports
-from Bcfg2.Compat import ConfigParser
-
-def generatereport(rspec, nrpt):
- """
- generatereport creates and returns an ElementTree representation
- of a report adhering to the XML spec for intermediate reports.
- """
- reportspec = copy.deepcopy(rspec)
- nodereprt = copy.deepcopy(nrpt)
-
- reportgood = reportspec.get("good", default = 'Y')
- reportmodified = reportspec.get("modified", default = 'Y')
- current_date = asctime()[:10]
-
- """Build regex of all the nodes we are reporting about."""
- pattern = re.compile( '|'.join([item.get("name") for item in reportspec.findall('Machine')]))
-
- for node in nodereprt.findall('Node'):
- if not (node.findall("Statistics") and pattern.match(node.get('name'))):
- # Don't know enough about node.
- nodereprt.remove(node)
- continue
-
- # Reduce to most recent Statistics entry.
- statisticslist = node.findall('Statistics')
- # This line actually sorts from most recent to oldest.
- statisticslist.sort(lambda y, x: cmp(strptime(x.get("time")), strptime(y.get("time"))))
- stats = statisticslist[0]
-
- [node.remove(item) for item in node.findall('Statistics')]
-
- # Add a good tag if node is good and we wnat to report such.
- if reportgood == 'Y' and stats.get('state') == 'clean':
- SubElement(stats,"Good")
-
- [stats.remove(item) for item in stats.findall("Bad") + stats.findall("Modified") if \
- item.getchildren() == []]
- [stats.remove(item) for item in stats.findall("Modified") if reportmodified == 'N']
-
- # Test for staleness -if stale add Stale tag.
- if stats.get("time").find(current_date) == -1:
- SubElement(stats,"Stale")
- node.append(stats)
- return nodereprt
-
-def mail(mailbody, confi):
- """mail mails a previously generated report."""
-
- try:
- mailer = confi.get('statistics', 'sendmailpath')
- except (ConfigParser.NoSectionError, ConfigParser.NoOptionError):
- mailer = "/usr/sbin/sendmail"
- # Open a pipe to the mail program and
- # write the data to the pipe.
- pipe = os.popen("%s -t" % mailer, 'w')
- pipe.write(mailbody)
- exitcode = pipe.close()
- if exitcode:
- print("Exit code: %s" % exitcode)
-
-def rss(reportxml, delivery, report):
- """rss appends a new report to the specified rss file
- keeping the last 9 articles.
- """
- # Check and see if rss file exists.
- for destination in delivery.findall('Destination'):
- try:
- fil = open(destination.attrib['address'], 'r')
- olddoc = XML(fil.read())
-
- # Defines the number of recent articles to keep.
- items = olddoc.find("channel").findall("item")[0:9]
- fil.close()
- fil = open(destination.attrib['address'], 'w')
- except (IOError, XMLSyntaxError):
- fil = open(destination.attrib['address'], 'w')
- items = []
-
- rssdata = Element("rss")
- channel = SubElement(rssdata, "channel")
- rssdata.set("version", "2.0")
- chantitle = SubElement(channel, "title")
- chantitle.text = report.attrib['name']
- chanlink = SubElement(channel, "link")
-
- # This can later link to WWW report if one gets published
- # simultaneously?
- chanlink.text = "http://www.mcs.anl.gov/cobalt/bcfg2"
- chandesc = SubElement(channel, "description")
- chandesc.text = "Information regarding the 10 most recent bcfg2 runs."
-
- channel.append(XML(reportxml))
-
- if items != []:
- for item in items:
- channel.append(item)
-
- tree = tostring(rssdata, xml_declaration=False).decode('UTF-8')
- fil.write(tree)
- fil.close()
-
-def www(reportxml, delivery):
- """www outputs report to."""
-
- # This can later link to WWW report if one gets published
- # simultaneously?
- for destination in delivery.findall('Destination'):
- fil = open(destination.attrib['address'], 'w')
-
- fil.write(reportxml)
- fil.close()
-
-def fileout(reportxml, delivery):
- """Outputs to plain text file."""
- for destination in delivery.findall('Destination'):
- fil = open(destination.attrib['address'], 'w')
-
- fil.write(reportxml)
- fil.close()
-
-def pretty_print(element, level=0):
- """Produce a pretty-printed text representation of element."""
- if element.text:
- fmt = "%s<%%s %%s>%%s</%%s>" % (level*" ")
- data = (element.tag, (" ".join(["%s='%s'" % keyval for keyval in list(element.attrib.items())])),
- element.text, element.tag)
- if element._children:
- fmt = "%s<%%s %%s>\n" % (level*" ",) + (len(element._children) * "%s") + "%s</%%s>\n" % (level*" ")
- data = (element.tag, ) + (" ".join(["%s='%s'" % keyval for keyval in list(element.attrib.items())]),)
- data += tuple([pretty_print(entry, level+2) for entry in element._children]) + (element.tag, )
- else:
- fmt = "%s<%%s %%s/>\n" % (level * " ")
- data = (element.tag, " ".join(["%s='%s'" % keyval for keyval in list(element.attrib.items())]))
- return fmt % data
-
-
-if __name__ == '__main__':
- all=False
- if '-C' in sys.argv:
- cfpath = sys.argv[sys.argv.index('-C') + 1]
- else:
- cfpath = '/etc/bcfg2.conf'
- c = ConfigParser.ConfigParser()
- c.read([cfpath])
- configpath = "%s/etc/report-configuration.xml" % c.get('server', 'repository')
- statpath = "%s/etc/statistics.xml" % c.get('server', 'repository')
- clientsdatapath = "%s/Metadata/clients.xml" % c.get('server', 'repository')
- try:
- prefix = c.get('server', 'prefix')
- except (ConfigParser.NoSectionError, ConfigParser.NoOptionError):
- prefix = '/usr'
-
- transformpath = "/%s/share/bcfg2/xsl-transforms/" % (prefix)
- #websrcspath = "/usr/share/bcfg2/web-rprt-srcs/"
-
- try:
- opts, args = getopt.getopt(sys.argv[1:], "C:hAc:Ns:", ["help", "all", "config=", "stats="])
- except getopt.GetoptError:
- mesg = sys.exc_info()[1]
- # Print help information and exit:
- print("%s\nUsage:\nbcfg2-build-reports [-h][-A (include ALL clients)] [-c <configuration-file>] [-s <statistics-file>]" % (mesg))
- raise SystemExit(2)
- for o, a in opts:
- if o in ("-h", "--help"):
- print("Usage:\nbcfg2-build-reports [-h] [-c <configuration-file>] [-s <statistics-file>]")
- raise SystemExit
- if o in ("-A", "--all"):
- all=True
- if o in ("-c", "--config"):
- configpath = a
- if o in ("-s", "--stats"):
- statpath = a
-
-
- """Reads data & config files."""
- try:
- statsdata = XML(open(statpath).read())
- except (IOError, XMLSyntaxError):
- print("bcfg2-build-reports: Failed to parse %s"%(statpath))
- raise SystemExit(1)
- try:
- configdata = XML(open(configpath).read())
- except (IOError, XMLSyntaxError):
- print("bcfg2-build-reports: Failed to parse %s"%(configpath))
- raise SystemExit(1)
- try:
- clientsdata = XML(open(clientsdatapath).read())
- except (IOError, XMLSyntaxError):
- print("bcfg2-build-reports: Failed to parse %s"%(clientsdatapath))
- raise SystemExit(1)
-
- # Merge data from three sources.
- nodereport = Element("Report", attrib={"time" : asctime()})
- # Should all of the other info in Metadata be appended?
- # What about all of the package stuff for other types of reports?
- for client in clientsdata.findall("Client"):
- nodel = Element("Node", attrib={"name" : client.get("name")})
- nodel.append(client)
- for nod in statsdata.findall("Node"):
- if client.get('name').find(nod.get('name')) == 0:
- for statel in nod.findall("Statistics"):
- nodel.append(statel)
- nodereport.append(nodel)
-
- if all:
- for nod in statsdata.findall("Node"):
- for client in clientsdata.findall("Client"):
- if client.get('name').find(nod.get('name')) == 0:
- break
- else:
- nodel = Element("Node", attrib={"name" : nod.get("name")})
- client = Element("Client", attrib={"name" : nod.get("name"), "profile" : "default"})
- nodel.append(client)
- for statel in nod.findall("Statistics"):
- nodel.append(statel)
- nodereport.append(nodel)
-
-
- for reprt in configdata.findall('Report'):
- nodereport.set("name", reprt.get("name", default="BCFG Report"))
-
- if reprt.get('refresh-time') != None:
- nodereport.set("refresh-time", reprt.get("refresh-time", default="600"))
-
- procnodereport = generatereport(reprt, nodereport)
-
- for deliv in reprt.findall('Delivery'):
- # Is a deepcopy of procnodereport necessary?
-
- delivtype = deliv.get('type', default='nodes-digest')
- deliverymechanism = deliv.get('mechanism', default='www')
-
- # Apply XSLT, different ones based on report type, and options
- if deliverymechanism == 'null-operator': # Special Cases
- fileout(tostring(ElementTree(procnodereport).getroot(), xml_declaration=False).decode('UTF-8'), deliv)
- break
- transform = delivtype + '-' + deliverymechanism + '.xsl'
-
- try: # Make sure valid stylesheet is selected.
- os.stat(transformpath + transform)
- except:
- print("bcfg2-build-reports: Invalid report type or delivery mechanism.\n Can't find: "\
- + transformpath + transform)
- raise SystemExit(1)
-
- try: # Try to parse stylesheet.
- stylesheet = XSLT(parse(transformpath + transform))
- except:
- print("bcfg2-build-reports: invalid XSLT transform file.")
- raise SystemExit(1)
-
- if deliverymechanism == 'mail':
- if delivtype == 'nodes-individual':
- reportdata = copy.deepcopy(procnodereport)
- for noden in reportdata.findall("Node"):
- [reportdata.remove(y) for y in reportdata.findall("Node")]
- reportdata.append(noden)
- result = stylesheet.apply(ElementTree(reportdata))
- outputstring = stylesheet.tostring(result)
-
- if not outputstring == None:
- toastring = ''
- for desti in deliv.findall("Destination"):
- toastring = "%s%s " % \
- (toastring, desti.get('address'))
- # Prepend To: and From:
- outputstring = "To: %s\nFrom: root@%s\n%s"% \
- (toastring, socket.getfqdn(), outputstring)
- mail(outputstring, c) #call function to send
-
- else:
- reportdata = copy.deepcopy(procnodereport)
-
- result = stylesheet.apply(ElementTree(reportdata))
- outputstring = stylesheet.tostring(result)
-
- if not outputstring == None:
- toastring = ''
- for desti in deliv.findall("Destination"):
- toastring = "%s%s " % \
- (toastring, desti.get('address'))
- # Prepend To: and From:
- outputstring = "To: %s\nFrom: root@%s\n%s"% \
- (toastring, socket.getfqdn(), outputstring)
- mail(outputstring, c) #call function to send
- else:
- outputstring = tostring(stylesheet.apply(ElementTree(procnodereport)).getroot(), xml_declaration=False).decode('UTF-8')
- if deliverymechanism == 'rss':
- rss(outputstring, deliv, reprt)
- else: # Must be deliverymechanism == 'www':
- www(outputstring, deliv)
diff --git a/testsuite/Testsrc/Testlib/TestServer/TestPlugin/Testhelpers.py b/testsuite/Testsrc/Testlib/TestServer/TestPlugin/Testhelpers.py
index 3d4df3e0b..fc9b5610c 100644
--- a/testsuite/Testsrc/Testlib/TestServer/TestPlugin/Testhelpers.py
+++ b/testsuite/Testsrc/Testlib/TestServer/TestPlugin/Testhelpers.py
@@ -114,10 +114,10 @@ class TestFileBacked(Bcfg2TestCase):
test_obj = FileBacked
path = os.path.join(datastore, "test")
- def get_obj(self, path=None, fam=None):
+ def get_obj(self, path=None):
if path is None:
path = self.path
- return self.test_obj(path, fam=fam)
+ return self.test_obj(path)
@patch("%s.open" % builtins)
def test_HandleEvent(self, mock_open):
@@ -163,24 +163,20 @@ class TestDirectoryBacked(Bcfg2TestCase):
""" ensure that the child object has the correct interface """
self.assertTrue(hasattr(self.test_obj.__child__, "HandleEvent"))
- def get_obj(self, fam=None):
- if fam is None:
- fam = Mock()
-
+ def get_obj(self):
@patch("%s.%s.add_directory_monitor" % (self.test_obj.__module__,
self.test_obj.__name__),
Mock())
def inner():
return self.test_obj(os.path.join(datastore,
- self.test_obj.__name__),
- fam)
+ self.test_obj.__name__))
return inner()
def test__init(self):
@patch("%s.%s.add_directory_monitor" % (self.test_obj.__module__,
self.test_obj.__name__))
def inner(mock_add_monitor):
- db = self.test_obj(datastore, Mock())
+ db = self.test_obj(datastore)
mock_add_monitor.assert_called_with('')
inner()
@@ -249,10 +245,9 @@ class TestDirectoryBacked(Bcfg2TestCase):
db.fam = Mock()
class MockChild(Mock):
- def __init__(self, path, fam, **kwargs):
+ def __init__(self, path, **kwargs):
Mock.__init__(self, **kwargs)
self.path = path
- self.fam = fam
self.HandleEvent = Mock()
db.__child__ = MockChild
@@ -262,7 +257,6 @@ class TestDirectoryBacked(Bcfg2TestCase):
self.assertIn(path, db.entries)
self.assertEqual(db.entries[path].path,
os.path.join(db.data, path))
- self.assertEqual(db.entries[path].fam, db.fam)
db.entries[path].HandleEvent.assert_called_with(event)
@patch("os.path.isdir")
@@ -400,27 +394,23 @@ class TestXMLFileBacked(TestFileBacked):
should_monitor = None
path = os.path.join(datastore, "test", "test1.xml")
- def get_obj(self, path=None, fam=None, should_monitor=False):
+ def get_obj(self, path=None, should_monitor=False):
if path is None:
path = self.path
- return self.test_obj(path, fam=fam, should_monitor=should_monitor)
+ return self.test_obj(path, should_monitor=should_monitor)
- def test__init(self):
- fam = Mock()
+ @patch("Bcfg2.Server.FileMonitor.get_fam")
+ def test__init(self, mock_get_fam):
xfb = self.get_obj()
- if self.should_monitor is True:
- self.assertIsNotNone(xfb.fam)
- else:
- self.assertIsNone(xfb.fam)
+ self.assertEqual(xfb.fam, mock_get_fam.return_value)
if self.should_monitor is not True:
- xfb = self.get_obj(fam=fam)
- self.assertFalse(fam.AddMonitor.called)
+ xfb = self.get_obj()
+ self.assertFalse(xfb.fam.AddMonitor.called)
if self.should_monitor is not False:
- fam.reset_mock()
- xfb = self.get_obj(fam=fam, should_monitor=True)
- fam.AddMonitor.assert_called_with(self.path, xfb)
+ xfb = self.get_obj(should_monitor=True)
+ xfb.fam.AddMonitor.assert_called_with(self.path, xfb)
@patch("os.path.exists")
@patch("lxml.etree.parse")
@@ -568,6 +558,7 @@ class TestXMLFileBacked(TestFileBacked):
test3 = lxml.etree.Element("Test", name="test3")
replacements = {"/test/test2.xml": test2,
"/test/test_dir/test3.xml": test3}
+
def xinclude():
for el in xfb.xdata.findall('//%sinclude' %
Bcfg2.Server.XI_NAMESPACE):
@@ -585,25 +576,24 @@ class TestXMLFileBacked(TestFileBacked):
self.assertItemsEqual([tostring(e) for e in xfb.entries],
[tostring(e) for e in children])
+ @patch("Bcfg2.Server.FileMonitor.get_fam", Mock())
def test_add_monitor(self):
xfb = self.get_obj()
xfb.add_monitor("/test/test2.xml")
self.assertIn("/test/test2.xml", xfb.extras)
- fam = Mock()
if self.should_monitor is not True:
- fam.reset_mock()
- xfb = self.get_obj(fam=fam)
- fam.reset_mock()
+ xfb = self.get_obj()
+ xfb.fam = Mock()
xfb.add_monitor("/test/test3.xml")
- self.assertFalse(fam.AddMonitor.called)
+ self.assertFalse(xfb.fam.AddMonitor.called)
self.assertIn("/test/test3.xml", xfb.extras)
if self.should_monitor is not False:
- fam.reset_mock()
- xfb = self.get_obj(fam=fam, should_monitor=True)
+ xfb = self.get_obj(should_monitor=True)
+ xfb.fam = Mock()
xfb.add_monitor("/test/test4.xml")
- fam.AddMonitor.assert_called_with("/test/test4.xml", xfb)
+ xfb.fam.AddMonitor.assert_called_with("/test/test4.xml", xfb)
self.assertIn("/test/test4.xml", xfb.extras)
@@ -1636,25 +1626,25 @@ class TestEntrySet(TestDebuggable):
eset.reset_metadata.reset_mock()
eset.entry_init.reset_mock()
- for fname in ["info", "info.xml", ":info"]:
- for evt in ["exists", "created", "changed"]:
- reset()
- event = Mock()
- event.code2str.return_value = evt
- event.filename = fname
- eset.handle_event(event)
- eset.update_metadata.assert_called_with(event)
- self.assertFalse(eset.entry_init.called)
- self.assertFalse(eset.reset_metadata.called)
-
+ fname = "info.xml"
+ for evt in ["exists", "created", "changed"]:
reset()
event = Mock()
- event.code2str.return_value = "deleted"
+ event.code2str.return_value = evt
event.filename = fname
eset.handle_event(event)
- eset.reset_metadata.assert_called_with(event)
+ eset.update_metadata.assert_called_with(event)
self.assertFalse(eset.entry_init.called)
- self.assertFalse(eset.update_metadata.called)
+ self.assertFalse(eset.reset_metadata.called)
+
+ reset()
+ event = Mock()
+ event.code2str.return_value = "deleted"
+ event.filename = fname
+ eset.handle_event(event)
+ eset.reset_metadata.assert_called_with(event)
+ self.assertFalse(eset.entry_init.called)
+ self.assertFalse(eset.update_metadata.called)
for evt in ["exists", "created", "changed"]:
reset()
@@ -1813,25 +1803,6 @@ class TestEntrySet(TestDebuggable):
self.assertFalse(mock_InfoXML.called)
eset.infoxml.HandleEvent.assert_called_with(event)
- for fname in [':info', 'info']:
- event = Mock()
- event.filename = fname
-
- idata = ["owner:owner",
- "group: GROUP",
- "mode: 775",
- "important: true",
- "bogus: line"]
- mock_open.return_value.readlines.return_value = idata
- eset.metadata = default_path_metadata()
- eset.update_metadata(event)
- expected = default_path_metadata()
- expected['owner'] = 'owner'
- expected['group'] = 'GROUP'
- expected['mode'] = '0775'
- expected['important'] = 'true'
- self.assertItemsEqual(eset.metadata, expected)
-
@patch("Bcfg2.Server.Plugin.helpers.default_path_metadata")
def test_reset_metadata(self, mock_default_path_metadata):
eset = self.get_obj()
@@ -1843,14 +1814,6 @@ class TestEntrySet(TestDebuggable):
eset.reset_metadata(event)
self.assertIsNone(eset.infoxml)
- for fname in [':info', 'info']:
- event = Mock()
- event.filename = fname
- eset.metadata = Mock()
- eset.reset_metadata(event)
- self.assertEqual(eset.metadata,
- mock_default_path_metadata.return_value)
-
@patch("Bcfg2.Server.Plugin.helpers.bind_info")
def test_bind_info_to_entry(self, mock_bind_info):
# There's a strange scoping issue in py3k that prevents this
@@ -2098,6 +2061,3 @@ class TestGroupSpool(TestPlugin, TestGenerator):
gs.event_id.assert_called_with(event)
self.assertNotIn("/baz/quux", gs.entries)
self.assertNotIn("/baz/quux", gs.Entries[gs.entry_type])
-
-
-
diff --git a/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestMetadata.py b/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestMetadata.py
index f627e4465..0afa5220d 100644
--- a/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestMetadata.py
+++ b/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestMetadata.py
@@ -204,9 +204,9 @@ class TestXMLMetadataConfig(TestXMLFileBacked):
watch_clients=watch_clients)
return XMLMetadataConfig(self.metadata, watch_clients, basefile)
+ @patch("Bcfg2.Server.FileMonitor.get_fam", Mock())
def test__init(self):
xmc = self.get_obj()
- self.assertEqual(self.metadata.core.fam, xmc.fam)
self.assertFalse(xmc.fam.AddMonitor.called)
def test_xdata(self):
@@ -251,20 +251,21 @@ class TestXMLMetadataConfig(TestXMLFileBacked):
self.assertEqual(config.base_xdata, "<test/>")
def test_add_monitor(self):
- core = MagicMock()
- config = self.get_obj(core=core)
+ config = self.get_obj()
+ config.fam = Mock()
fname = "test.xml"
fpath = os.path.join(self.metadata.data, fname)
config.extras = []
config.add_monitor(fpath)
- self.assertFalse(core.fam.AddMonitor.called)
+ self.assertFalse(config.fam.AddMonitor.called)
self.assertEqual(config.extras, [fpath])
- config = self.get_obj(core=core, watch_clients=True)
+ config = self.get_obj(watch_clients=True)
+ config.fam = Mock()
config.add_monitor(fpath)
- core.fam.AddMonitor.assert_called_with(fpath, config.metadata)
+ config.fam.AddMonitor.assert_called_with(fpath, config.metadata)
self.assertItemsEqual(config.extras, [fpath])
def test_Index(self):
@@ -488,7 +489,8 @@ class TestMetadata(_TestMetadata, TestStatistics, TestDatabaseBacked):
client_name = "%s%s" % (prefix, i)
return client_name
- def test__init(self):
+ @patch("Bcfg2.Server.FileMonitor.get_fam")
+ def test__init(self, mock_get_fam):
# test with watch_clients=False
core = MagicMock()
metadata = self.get_obj(core=core)
@@ -501,18 +503,19 @@ class TestMetadata(_TestMetadata, TestStatistics, TestDatabaseBacked):
self.assertEqual(metadata.states, dict())
# test with watch_clients=True
- core.fam = MagicMock()
metadata = self.get_obj(core=core, watch_clients=True)
self.assertEqual(len(metadata.states), 2)
- core.fam.AddMonitor.assert_any_call(os.path.join(metadata.data,
- "groups.xml"),
- metadata)
- core.fam.AddMonitor.assert_any_call(os.path.join(metadata.data,
- "clients.xml"),
- metadata)
-
- core.fam.reset_mock()
- core.fam.AddMonitor = Mock(side_effect=IOError)
+ mock_get_fam.return_value.AddMonitor.assert_any_call(
+ os.path.join(metadata.data, "groups.xml"),
+ metadata)
+ mock_get_fam.return_value.AddMonitor.assert_any_call(
+ os.path.join(metadata.data, "clients.xml"),
+ metadata)
+
+ mock_get_fam.reset_mock()
+ fam = Mock()
+ fam.AddMonitor = Mock(side_effect=IOError)
+ mock_get_fam.return_value = fam
self.assertRaises(Bcfg2.Server.Plugin.PluginInitError,
self.get_obj, core=core, watch_clients=True)
@@ -575,6 +578,7 @@ class TestMetadata(_TestMetadata, TestStatistics, TestDatabaseBacked):
def test_add_group(self):
metadata = self.get_obj()
metadata.groups_xml.write = Mock()
+ metadata.groups_xml.load_xml = Mock()
metadata.groups_xml.data = lxml.etree.XML('<Groups/>').getroottree()
metadata.groups_xml.basedata = copy.copy(metadata.groups_xml.data)
@@ -607,6 +611,7 @@ class TestMetadata(_TestMetadata, TestStatistics, TestDatabaseBacked):
def test_update_group(self):
metadata = self.get_obj()
metadata.groups_xml.write_xml = Mock()
+ metadata.groups_xml.load_xml = Mock()
metadata.groups_xml.data = copy.deepcopy(get_groups_test_tree())
metadata.groups_xml.basedata = copy.copy(metadata.groups_xml.data)
@@ -624,6 +629,7 @@ class TestMetadata(_TestMetadata, TestStatistics, TestDatabaseBacked):
def test_remove_group(self):
metadata = self.get_obj()
metadata.groups_xml.write_xml = Mock()
+ metadata.groups_xml.load_xml = Mock()
metadata.groups_xml.data = copy.deepcopy(get_groups_test_tree())
metadata.groups_xml.basedata = copy.copy(metadata.groups_xml.data)
@@ -639,6 +645,7 @@ class TestMetadata(_TestMetadata, TestStatistics, TestDatabaseBacked):
def test_add_bundle(self):
metadata = self.get_obj()
metadata.groups_xml.write = Mock()
+ metadata.groups_xml.load_xml = Mock()
metadata.groups_xml.data = lxml.etree.XML('<Groups/>').getroottree()
metadata.groups_xml.basedata = copy.copy(metadata.groups_xml.data)
@@ -662,6 +669,7 @@ class TestMetadata(_TestMetadata, TestStatistics, TestDatabaseBacked):
def test_remove_bundle(self):
metadata = self.get_obj()
metadata.groups_xml.write_xml = Mock()
+ metadata.groups_xml.load_xml = Mock()
metadata.groups_xml.data = copy.deepcopy(get_groups_test_tree())
metadata.groups_xml.basedata = copy.copy(metadata.groups_xml.data)
@@ -677,6 +685,7 @@ class TestMetadata(_TestMetadata, TestStatistics, TestDatabaseBacked):
def test_add_client(self):
metadata = self.get_obj()
metadata.clients_xml.write = Mock()
+ metadata.clients_xml.load_xml = Mock()
metadata.clients_xml.data = lxml.etree.XML('<Clients/>').getroottree()
metadata.clients_xml.basedata = copy.copy(metadata.clients_xml.data)
@@ -711,6 +720,7 @@ class TestMetadata(_TestMetadata, TestStatistics, TestDatabaseBacked):
def test_update_client(self):
metadata = self.get_obj()
metadata.clients_xml.write_xml = Mock()
+ metadata.clients_xml.load_xml = Mock()
metadata.clients_xml.data = copy.deepcopy(get_clients_test_tree())
metadata.clients_xml.basedata = copy.copy(metadata.clients_xml.data)
@@ -1259,25 +1269,24 @@ class TestMetadataBase(TestMetadata):
return client_name
@patch('os.path.exists')
- def test__init(self, mock_exists):
- core = MagicMock()
- core.fam = Mock()
+ @patch('Bcfg2.Server.FileMonitor.get_fam')
+ def test__init(self, mock_get_fam, mock_exists):
mock_exists.return_value = False
- metadata = self.get_obj(core=core, watch_clients=True)
+ metadata = self.get_obj(watch_clients=True)
self.assertIsInstance(metadata, Bcfg2.Server.Plugin.DatabaseBacked)
- core.fam.AddMonitor.assert_called_once_with(os.path.join(metadata.data,
- "groups.xml"),
- metadata)
+ mock_get_fam.return_value.AddMonitor.assert_called_with(
+ os.path.join(metadata.data, "groups.xml"),
+ metadata)
mock_exists.return_value = True
- core.fam.reset_mock()
- metadata = self.get_obj(core=core, watch_clients=True)
- core.fam.AddMonitor.assert_any_call(os.path.join(metadata.data,
- "groups.xml"),
- metadata)
- core.fam.AddMonitor.assert_any_call(os.path.join(metadata.data,
- "clients.xml"),
- metadata)
+ mock_get_fam.reset_mock()
+ metadata = self.get_obj(watch_clients=True)
+ mock_get_fam.return_value.AddMonitor.assert_any_call(
+ os.path.join(metadata.data, "groups.xml"),
+ metadata)
+ mock_get_fam.return_value.AddMonitor.assert_any_call(
+ os.path.join(metadata.data, "clients.xml"),
+ metadata)
def test_add_group(self):
pass
@@ -1516,9 +1525,12 @@ class TestMetadata_ClientsXML(TestMetadataBase):
def load_clients_data(self, metadata=None, xdata=None):
if metadata is None:
metadata = self.get_obj()
- metadata.core.fam = Mock()
+ fam = Bcfg2.Server.FileMonitor._FAM
+ Bcfg2.Server.FileMonitor._FAM = MagicMock()
metadata.clients_xml = metadata._handle_file("clients.xml")
metadata = TestMetadata.load_clients_data(self, metadata=metadata,
xdata=xdata)
- return TestMetadataBase.load_clients_data(self, metadata=metadata,
- xdata=xdata)
+ rv = TestMetadataBase.load_clients_data(self, metadata=metadata,
+ xdata=xdata)
+ Bcfg2.Server.FileMonitor._FAM = fam
+ return rv
diff --git a/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestProbes.py b/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestProbes.py
index 899fb24a0..958dba4ff 100644
--- a/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestProbes.py
+++ b/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestProbes.py
@@ -91,22 +91,20 @@ class TestProbeSet(TestEntrySet):
ignore = ["foo~", ".#foo", ".foo.swp", ".foo.swx", "probed.xml"]
bogus_names = ["test.py"]
- def get_obj(self, path=datastore, fam=None, encoding=None,
+ def get_obj(self, path=datastore, encoding=None,
plugin_name="Probes", basename=None):
# get_obj() accepts the basename argument, accepted by the
# parent get_obj() method, and just throws it away, since
# ProbeSet uses a regex for the "basename"
- if fam is None:
- fam = Mock()
- rv = self.test_obj(path, fam, encoding, plugin_name)
+ rv = self.test_obj(path, encoding, plugin_name)
rv.entry_type = MagicMock()
return rv
- def test__init(self):
- fam = Mock()
- ps = self.get_obj(fam=fam)
+ @patch("Bcfg2.Server.FileMonitor.get_fam")
+ def test__init(self, mock_get_fam):
+ ps = self.get_obj()
self.assertEqual(ps.plugin_name, "Probes")
- fam.AddMonitor.assert_called_with(datastore, ps)
+ mock_get_fam.return_value.AddMonitor.assert_called_with(datastore, ps)
TestEntrySet.test__init(self)
def test_HandleEvent(self):
@@ -256,9 +254,6 @@ text
def test__init(self):
mock_load_data = Mock()
probes = self.get_probes_object(load_data=mock_load_data)
- probes.core.fam.AddMonitor.assert_called_with(os.path.join(datastore,
- probes.name),
- probes.probes)
mock_load_data.assert_any_call()
self.assertEqual(probes.probedata, ClientProbeDataSet())
self.assertEqual(probes.cgroups, dict())
diff --git a/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestTemplateHelper.py b/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestTemplateHelper.py
index 43d594482..4db92b7c4 100644
--- a/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestTemplateHelper.py
+++ b/testsuite/Testsrc/Testlib/TestServer/TestPlugins/TestTemplateHelper.py
@@ -25,7 +25,7 @@ class TestHelperModule(Bcfg2TestCase):
def get_obj(self, path=None):
if path is None:
path = self.path
- return self.test_obj(path, fam=Mock())
+ return self.test_obj(path)
def test__init(self):
hm = self.get_obj()
diff --git a/testsuite/Testsrc/test_code_checks.py b/testsuite/Testsrc/test_code_checks.py
index ded9cd8e3..323f64f49 100644
--- a/testsuite/Testsrc/test_code_checks.py
+++ b/testsuite/Testsrc/test_code_checks.py
@@ -43,7 +43,7 @@ contingent_checks = {
"lib/Bcfg2/Server/Admin": ["Reports.py", "Syncdb.py"],
"sbin": ["bcfg2-reports"]},
("pyinotify",): {"lib/Bcfg2/Server/FileMonitor": ["Inotify.py"]},
- ("yum",): {"lib/Bcfg2/Client/Tools": ["YUM*"]},
+ ("yum",): {"lib/Bcfg2/Client/Tools": ["YUM.py"]},
("genshi",): {"lib/Bcfg2/Server/Plugins/Cfg": ["CfgGenshiGenerator.py"]},
("Cheetah",): {"lib/Bcfg2/Server/Plugins/Cfg": ["CfgCheetahGenerator.py"]},
("M2Crypto",): {"lib/Bcfg2": ["Encryption.py"],
@@ -57,11 +57,10 @@ contingent_checks = {
# perform only error checking on the listed files
error_checks = {
- "sbin": ["bcfg2-build-reports", "bcfg2-reports"],
+ "sbin": ["bcfg2-reports"],
"lib/Bcfg2": ["Proxy.py", "SSLServer.py", "Reporting"],
"lib/Bcfg2/Server": ["Reports", "SchemaUpdater"],
- "lib/Bcfg2/Server/Admin": ["Compare.py",
- "Snapshots.py"],
+ "lib/Bcfg2/Server/Admin": ["Compare.py"],
"lib/Bcfg2/Client/Tools": ["launchd.py",
"OpenCSW.py",
"Blast.py",
@@ -69,8 +68,7 @@ error_checks = {
"FreeBSDInit.py",
"DebInit.py",
"RcUpdate.py",
- "VCS.py",
- "YUM24.py"],
+ "VCS.py"],
"lib/Bcfg2/Server/Plugins": ["Deps.py",
"Ldap.py",
"Pkgmgr.py"]
@@ -79,17 +77,9 @@ error_checks = {
# perform no checks at all on the listed files
no_checks = {
"lib/Bcfg2/Client/Tools": ["APT.py", "RPM.py", "rpmtools.py"],
- "lib/Bcfg2/Server": ["Snapshots", "Hostbase"],
"lib/Bcfg2": ["manage.py"],
"lib/Bcfg2/Server/Reports": ["manage.py"],
- "lib/Bcfg2/Server/Plugins": ["Account.py",
- "Base.py",
- "Editor.py",
- "Hostbase.py",
- "Snapshots.py",
- "Statistics.py",
- "TCheetah.py",
- "TGenshi.py"],
+ "lib/Bcfg2/Server/Plugins": ["Base.py"],
}
diff --git a/tools/README b/tools/README
index 335363898..dc21426b8 100644
--- a/tools/README
+++ b/tools/README
@@ -7,9 +7,6 @@ accounts2xml.py
basebuilder.py <image directory>
- builds v2 base.xml from bcfg1 repo
-batchadd.py <filename>
- - Add records to Hostbase
-
bcfg2-completion.bash
- Bash tab completion for bcfg2-admin
@@ -65,15 +62,6 @@ export.sh
generate-manpages.bash
- Generate man pages from the Sphinx source
-hostbasepush.py
- - Call the Hostbase.rebuildState XML-RPC method
-
-hostbase.py {-l|-c} <hostname>
- - Display or create host information for Hostbase
-
-hostinfo.py {-q <query>|--showfields}
- - Query the hostbase databse
-
pkgmgr_gen.py
- Generate Pkgmgr XML files from a list of directories that
contain RPMS
diff --git a/tools/batchadd.py b/tools/batchadd.py
deleted file mode 100755
index e8008b330..000000000
--- a/tools/batchadd.py
+++ /dev/null
@@ -1,168 +0,0 @@
-#!/usr/bin/python
-
-from datetime import date
-import os
-import sys
-
-os.environ['DJANGO_SETTINGS_MODULE'] = 'Bcfg2.Server.Hostbase.settings'
-from Bcfg2.Server.Hostbase.hostbase.models import *
-from Bcfg2.Server.Hostbase.settings import DEFAULT_MX, PRIORITY
-import Bcfg2.Server.Hostbase.regex
-
-host_attribs = ['administrator',
- 'comments',
- 'csi',
- 'expiration_date',
- 'hostname',
- 'location',
- 'netgroup',
- 'outbound_smtp',
- 'primary_user',
- 'printq',
- 'security_class',
- 'support',
- 'whatami']
-
-
-def handle_error(field):
- if '-f' in sys.argv:
- return
- print("Error: %s is already defined in hostbase" % field)
- if '-s' in sys.argv:
- sys.exit(1)
-
-
-def checkformat(values, indices):
- """Ensures file contains all necessary attributes in order """
- filelist = [pair[0] for pair in values]
-
- # lines = len(filelist)
-
- filelist = filelist[indices[0]:]
-
- for index in indices:
- if filelist[0:13] != host_attribs:
- # figure out what to do here
- return False
- else:
- # process rest of host attributes
- try:
- next = filelist[1:].index('hostname')
- remaining = filelist[13:next + 1]
- filelist = filelist[next + 1:]
- except:
- remaining = filelist[13:]
- needfields = ['mac_addr', 'hdwr_type', 'ip_addr']
- if [item for item in needfields if item not in remaining]:
- return False
- return True
-
-
-if __name__ == '__main__':
-
- # argument handling for batchadd
- try:
- fd = open(sys.argv[1], 'r')
- except (IndexError, IOError):
- print("\nUsage: batchadd.py filename\n")
- sys.exit()
-
- lines = fd.readlines()
- # splits and strips lines into (attribute, value)
- info = [[item.strip() for item in line.split("->")] for line in lines
- if line.lstrip(' ')[0] != '#' and line != '\n']
-
- if info[0][0] == 'mx' and info[1][0] == 'priority':
- mx, created = MX.objects.get_or_create(mx=info[0][1],
- priority=info[1][1])
- info = info[2:]
- else:
- mx, created = MX.objects.get_or_create(mx=DEFAULT_MX,
- priority=PRIORITY)
- if created:
- mx.save()
-
- hostindices = [num for num in range(0, len(info))
- if info[num][0] == 'hostname']
-
- if not checkformat(info, hostindices):
- print("Error: file format")
- sys.exit()
-
-#################
-
- for host in hostindices:
- try:
- host = Host.objects.get(hostname=info[host][1])
- handle_error(info[host][1])
- except:
- # do something here
- pass
-
- macindices = [num for num in range(0, len(info))
- if info[num][0] == 'mac_addr']
- for mac_addr in macindices:
- try:
- host = Interface.objects.get(mac_addr=info[mac_addr][1])
- handle_error(info[mac_addr][1])
- except:
- # do something here
- pass
-
- for host in hostindices:
- blank = Host()
- for attrib in host_attribs:
- pair = info.pop(0)
- if pair[0] == 'outbound_smtp':
- if pair[1] == 'y':
- blank.__dict__[pair[0]] = 1
- else:
- blank.__dict__[pair[0]] = 0
- elif pair[0] == 'expiration_date':
- (year, month, day) = pair[1].split("-")
- blank.expiration_date = date(int(year),
- int(month),
- int(day))
- else:
- blank.__dict__[pair[0]] = pair[1]
- blank.status = 'active'
- blank.save()
- newhostname = blank.hostname.split(".")[0]
- newdomain = blank.hostname.split(".", 1)[1]
- while info and info[0][0] != 'hostname':
- if info[0][0] == 'mac_addr':
- pair = info.pop(0)
- inter = Interface.objects.create(host=blank,
- mac_addr=pair[1],
- hdwr_type='eth')
- if not pair[1]:
- inter.dhcp = False
- inter.save()
- elif info[0][0] == 'hdwr_type':
- pair = info.pop(0)
- inter.hdwr_type = pair[1]
- inter.save()
- elif info[0][0] == 'ip_addr':
- pair = info.pop(0)
- ip = IP.objects.create(interface=inter, ip_addr=pair[1])
- hostnamenode = Name(ip=ip,
- name=blank.hostname,
- dns_view='global',
- only=False)
- hostnamenode.save()
- namenode = Name(ip=ip,
- name=".".join([newhostname + "-" + inter.hdwr_type,
- newdomain]),
- dns_view="global", only=False)
- namenode.save()
- subnetnode = Name(ip=ip, name=newhostname + "-" +
- ip.ip_addr.split(".")[2] + "." +
- newdomain, dns_view="global", only=False)
- subnetnode.save()
- hostnamenode.mxs.add(mx)
- namenode.mxs.add(mx)
- subnetnode.mxs.add(mx)
- elif info[0][0] == 'cname':
- pair = info.pop(0)
- cname = CName.objects.create(name=hostnamenode, cname=pair[1])
- cname.save()
diff --git a/tools/bcfg2-import-config b/tools/bcfg2-import-config
index d6273f0c6..fec007e7e 100755
--- a/tools/bcfg2-import-config
+++ b/tools/bcfg2-import-config
@@ -11,7 +11,6 @@
usage() {
echo "$0: tool to import files in to bcfg2-server repository"
echo " -s Copy SSH Key files"
- echo " -p Create :info files with current file permissions"
echo " -n No suffix. Generate global files"
echo " --debian Run debsums to detect changed configuration files"
echo " ** debsums is only able to detect part of changes!"
@@ -28,7 +27,6 @@ eval set -- "$TEMP"
## Start Defaults
NEEDSSH=0
-NEEDPERM=0
DEBSUMS=0
NOSUFFIX=0
# End Defaults
@@ -37,7 +35,6 @@ NOSUFFIX=0
while true ; do
case "$1" in
-s) NEEDSSH=1; shift ;;
- -p) NEEDPERM=1; shift ;;
--debian) DEBSUMS=1; shift ;;
-n) NOSUFFIX=1; shift ;;
-h|--help)
@@ -102,11 +99,6 @@ get_files() {
FILE=$(basename $i)
mkdir -p $CFGREPO/$i
cp $i $CFGREPO/$i/${FILE}${SUFFIX}
- if [ $NEEDPERM -ne 0 ]; then
- # Get permissions for the file
- echo -n "(permissions) "
- find $i -printf "owner:%u\ngroup:%g\nperms:%#m\n" > "$CFGREPO/$i/:info"
- fi
echo "OK"
else
echo "$i: Not a file"
@@ -126,7 +118,7 @@ get_debsums() {
}
## End Functions
-if [ $(($NEEDPERM + $NEEDSSH + $DEBSUMS)) -eq 0 -a -z "$FILES" ]; then usage ; exit 0; fi
+if [ $(($NEEDSSH + $DEBSUMS)) -eq 0 -a -z "$FILES" ]; then usage ; exit 0; fi
init_temp_repo
get_debsums
diff --git a/tools/bcfg2-profile-templates.py b/tools/bcfg2-profile-templates.py
index fe7146d27..54f8e87f3 100755
--- a/tools/bcfg2-profile-templates.py
+++ b/tools/bcfg2-profile-templates.py
@@ -73,40 +73,38 @@ def main():
clients = [core.build_metadata(setup['client'])]
times = dict()
- for plugin in ['Cfg', 'TGenshi', 'TCheetah']:
- if plugin not in core.plugins:
- logger.debug("Skipping disabled plugin %s" % plugin)
- continue
- logger.info("Rendering templates from plugin %s" % plugin)
+ if 'Cfg' not in core.plugins:
+ logger.error("Cfg is not enabled")
+ return 1
- entrysets = []
- for template in templates:
- try:
- entrysets.append(core.plugins[plugin].entries[template])
- except KeyError:
- logger.debug("Template %s not found in plugin %s" %
- (template, plugin))
- if not entrysets:
- logger.debug("Using all entrysets in plugin %s" % plugin)
- entrysets = core.plugins[plugin].entries.values()
+ cfg = core.plugins['Cfg']
+ entrysets = []
+ for template in templates:
+ try:
+ entrysets.append(cfg.entries[template])
+ except KeyError:
+ logger.debug("Template %s not found" % template)
+ if not entrysets:
+ logger.debug("Using all entrysets")
+ entrysets = cfg.entries.values()
- for eset in entrysets:
- path = eset.path.replace(setup['repo'], '')
- logger.info("Rendering %s..." % path)
- times[path] = dict()
- for metadata in clients:
- avg = 0.0
- for i in range(runs):
- entry = lxml.etree.Element("Path")
- start = time.time()
- try:
- eset.bind_entry(entry, metadata)
- avg += (time.time() - start) / runs
- except:
- break
- if avg:
- logger.debug(" %s: %.02f sec" % (metadata.hostname, avg))
- times[path][metadata.hostname] = avg
+ for eset in entrysets:
+ path = eset.path.replace(setup['repo'], '')
+ logger.info("Rendering %s..." % path)
+ times[path] = dict()
+ for metadata in clients:
+ avg = 0.0
+ for i in range(runs):
+ entry = lxml.etree.Element("Path")
+ start = time.time()
+ try:
+ eset.bind_entry(entry, metadata)
+ avg += (time.time() - start) / runs
+ except:
+ break
+ if avg:
+ logger.debug(" %s: %.02f sec" % (metadata.hostname, avg))
+ times[path][metadata.hostname] = avg
# print out per-template results
tmpltimes = []
diff --git a/tools/hostbase.py b/tools/hostbase.py
deleted file mode 100755
index 7474e68b7..000000000
--- a/tools/hostbase.py
+++ /dev/null
@@ -1,79 +0,0 @@
-#!/usr/bin/python
-import os
-from getopt import getopt, GetoptError
-from re import split
-import sys
-
-os.environ['DJANGO_SETTINGS_MODULE'] = 'Hostbase.settings'
-from Hostbase.hostbase.models import Host
-
-attribs = ['administrator',
- 'comments',
- 'csi',
- 'dhcp',
- 'expiration_date',
- 'hostname',
- 'last',
- 'location',
- 'netgroup',
- 'outbound_smtp',
- 'primary_user',
- 'printq',
- 'security_class',
- 'support',
- 'status',
- 'whatami']
-
-already_exists = None
-#here's my attempt at making the command line idiot proof
-#you must supply and arugument and hostname for hostbase.py to run
-try:
- (opts, args) = getopt(sys.argv[1:], 'l:c:')
- sys.argv[1]
- if len(split("\.", opts[0][1])) == 1:
- hosttouse = opts[0][1] + ".mcs.anl.gov"
- else:
- hosttouse = opts[0][1]
-except (GetoptError, IndexError):
- print("\nUsage: hostbase.py -flag (hostname)\n")
- print("Flags:")
- print("\t-l look (hostname)\n")
-# print("\t-c copy (hostname)\n")
- sys.exit()
-
-try:
- host = Host.objects.get(hostname=hosttouse)
-except:
- print("Error: host %s not in hostbase" % hosttouse)
- sys.exit(1)
-interfaces = []
-for interface in host.interface_set.all():
- interfaces.append([interface, interface.ip_set.all()])
-hostinfo = "\n"
-for attrib in attribs:
- if not (opts[0][0] == '-c' and attrib in ['status', 'last']):
- if attrib == 'dhcp' or attrib == 'outbound_smtp':
- if host.__dict__[attrib]:
- hostinfo += "%-32s-> %s\n" % (attrib, 'y')
- else:
- hostinfo += "%-32s-> %s\n" % (attrib, 'n')
- else:
- hostinfo += "%-32s-> %s\n" % (attrib, host.__dict__[attrib])
-for interface in interfaces:
- hostinfo += "\n%-32s-> %s\n" % ('mac_addr', interface[0].mac_addr)
- hostinfo += "%-32s-> %s\n" % ('hdwr_type', interface[0].hdwr_type)
- for ip in interface[1]:
- hostinfo += "%-32s-> %s\n" % ('ip_addr', ip.ip_addr)
-
-if opts[0][0] == '-l':
- """Displays general host information"""
- print(hostinfo)
-
-if opts[0][0] == '-c':
- """Provides pre-filled template to copy a host record"""
- fd = open('/tmp/hostbase.%s.tmp' % host.id, 'w')
- fd.write(hostinfo)
- fd.close()
- os.system('vi + /tmp/hostbase.%s.tmp' % host.id)
- os.system('batchadd.py /tmp/hostbase.%s.tmp' % host.id)
- os.system('rm /tmp/hostbase.%s.tmp' % host.id)
diff --git a/tools/hostbasepush.py b/tools/hostbasepush.py
deleted file mode 100755
index 02b7a582f..000000000
--- a/tools/hostbasepush.py
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/usr/bin/python
-
-import os
-import Bcfg2.Client.Proxy
-
-if not os.getuid() == 0:
- print("this command must be run as root")
- raise SystemExit
-
-proxy = Bcfg2.Client.Proxy.bcfg2()
-print("building files...")
-proxy.run_method('Hostbase.rebuildState', ())
-print("running bcfg...")
-os.system('bcfg2 -q -d -v')
diff --git a/tools/hostinfo.py b/tools/hostinfo.py
deleted file mode 100755
index 8ae5c4df6..000000000
--- a/tools/hostinfo.py
+++ /dev/null
@@ -1,197 +0,0 @@
-#!/usr/bin/python
-"""Hostinfo queries the hostbase database according to user-defined data"""
-
-from os import system, environ
-environ['DJANGO_SETTINGS_MODULE'] = 'Hostbase.settings'
-from getopt import gnu_getopt, GetoptError
-from django.db import connection
-import sys
-
-logic_ops = ["and", "or"]
-host_attribs = ["hostname", "whatami", "netgroup", "security_class",
- "support", "csi", "memory", "printq", "dhcp", "outbound_smtp",
- "primary_user", "administrator", "location",
- "comments", "last", "expiration_date"]
-dispatch = {'mac_addr': ' i.',
- 'hdwr_type': ' i.',
- 'ip_addr': ' p.',
- 'name': ' n.',
- 'dns_view': ' n.',
- 'cname': ' c.',
- 'mx': ' m.',
- 'priority': ' m.'}
-
-
-def pinger(hosts):
- """Function that uses fping to ping multiple hosts in parallel"""
- hostnames = ""
- for each in hosts:
- hostnames += each[0] + " "
- system("fping -r 1" + hostnames)
- sys.exit()
-
-
-def get_query(arguments):
- """Parses the command line options and returns the necessary
- data for an SQL query"""
- logic = None
- resultset = []
- querystring = ''
- while 1:
- notflag = False
- if arguments[0] == 'not':
- notflag = True
- querypos = 1
- elif arguments[0] in logic_ops:
- logic = arguments[0]
- if arguments[1] == 'not':
- notflag = True
- querypos = 2
- else:
- querypos = 1
- else:
- querypos = 0
- if len(arguments[querypos].split("==")) > 1:
- operator = "="
- if notflag:
- operator = "<>"
- querysplit = arguments[querypos].split("==")
- if querysplit[0] in host_attribs:
- querystring = " h.%s%s\'%s\'" % (querysplit[0],
- operator,
- querysplit[1])
- elif querysplit[0] in dispatch:
- querystring = dispatch[querysplit[0]]
- querystring += "%s%s\'%s\'" % (querysplit[0],
- operator,
- querysplit[1])
- elif len(arguments[querypos].split("=")) > 1:
- notstring = ''
- if notflag:
- notstring = 'NOT '
- querysplit = arguments[querypos].split("=")
- if querysplit[0] in host_attribs:
- querystring = " h.%s %sLIKE \'%%%%%s%%%%\'" % (querysplit[0],
- notstring,
- querysplit[1])
- elif querysplit[0] in dispatch:
- querystring = dispatch[querysplit[0]]
- querystring += "%s %sLIKE \'%%%%%s%%%%\'" % (querysplit[0],
- notstring,
- querysplit[1])
- else:
- print("ERROR: bad query format")
- sys.exit()
- if not querystring:
- print("ERROR: bad query format")
- sys.exit()
- resultset.append((querystring, logic))
- arguments = arguments[querypos + 1:]
- if arguments == [] or arguments[0] not in logic_ops:
- break
- return resultset
-
-try:
- (opts, args) = gnu_getopt(sys.argv[1:],
- 'q:', ['showfields', 'fields', 'ping', 'summary'])
- cursor = connection.cursor()
- if ('--showfields', '') in opts:
- print("\nhost fields:\n")
- for field in host_attribs:
- print(field)
- for field in dispatch:
- print(field)
- print("")
- sys.exit()
- if opts[0][0] == '-q':
- results = get_query(sys.argv[2:])
- queryoptions = ""
- for result in results:
- if result[1] == 'and':
- queryoptions += " AND " + result[0]
- elif result[1] == 'or':
- queryoptions += " OR " + result[0]
- else:
- queryoptions += result[0]
- if ('--summary', '') in opts:
- fields = "h.hostname, h.whatami, h.location, h.primary_user"
- query = """SELECT DISTINCT %s FROM (((((hostbase_host h
- INNER JOIN hostbase_interface i ON h.id = i.host_id)
- INNER JOIN hostbase_ip p ON i.id = p.interface_id)
- INNER JOIN hostbase_name n ON p.id = n.ip_id)
- INNER JOIN hostbase_name_mxs x ON x.name_id = n.id)
- INNER JOIN hostbase_mx m ON m.id = x.mx_id)
- LEFT JOIN hostbase_cname c ON n.id = c.name_id
- WHERE %s ORDER BY h.hostname
- """ % (fields, queryoptions)
- cursor.execute(query)
- results = cursor.fetchall()
- if not results:
- print("No matches were found for your query")
- sys.exit()
- print("\n%-32s %-10s %-10s %-10s" % ('Hostname', 'Type', 'Location', 'User'))
- print("================================ ========== ========== ==========")
- for host in results:
- print("%-32s %-10s %-10s %-10s" % (host))
- print("")
- elif ('--fields', '') in opts:
- tolook = [arg for arg in args if arg in host_attribs or arg in dispatch]
- fields = ""
- fields = ", ".join(tolook)
- if not fields:
- print("No valid fields were entered. exiting...")
- sys.exit()
- query = """SELECT DISTINCT %s FROM (((((hostbase_host h
- INNER JOIN hostbase_interface i ON h.id = i.host_id)
- INNER JOIN hostbase_ip p ON i.id = p.interface_id)
- INNER JOIN hostbase_name n ON p.id = n.ip_id)
- INNER JOIN hostbase_name_mxs x ON x.name_id = n.id)
- INNER JOIN hostbase_mx m ON m.id = x.mx_id)
- LEFT JOIN hostbase_cname c ON n.id = c.name_id
- WHERE %s ORDER BY h.hostname
- """ % (fields, queryoptions)
-
- cursor.execute(query)
- results = cursor.fetchall()
-
- last = results[0]
- for field in results[0]:
- print(repr(field) + "\t")
- for host in results:
- if not host == last:
- for field in host:
- print(repr(field) + "\t")
- last = host
- print("")
- else:
- basequery = """SELECT DISTINCT h.hostname FROM (((((hostbase_host h
- INNER JOIN hostbase_interface i ON h.id = i.host_id)
- INNER JOIN hostbase_ip p ON i.id = p.interface_id)
- INNER JOIN hostbase_name n ON p.id = n.ip_id)
- INNER JOIN hostbase_name_mxs x ON x.name_id = n.id)
- INNER JOIN hostbase_mx m ON m.id = x.mx_id)
- LEFT JOIN hostbase_cname c ON n.id = c.name_id
- WHERE
- """
- cursor.execute(basequery + queryoptions + " ORDER BY h.hostname")
- results = cursor.fetchall()
-
- if not results:
- print("No matches were found for your query")
- sys.exit()
-
- if ("--ping", '') in opts:
- pinger(results)
-
- for host in results:
- print(host[0])
-
-
-except (GetoptError, IndexError):
- print("\nUsage: hostinfo.py -q <field>=[=]<value> [and/or <field>=<value> [--long option]]")
- print(" hostinfo.py --showfields\tshows all data fields")
- print("\n long options:")
- print("\t --fields f1 f2 ...\tspecifies the fields displayed from the queried hosts")
- print("\t --summary\t\tprints out a predetermined set of fields")
- print("\t --ping\t\t\tuses fping to ping all queried hosts\n")
- sys.exit()