summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/server/plugins/generators/tgenshi/bcfg2-cron.txt25
-rw-r--r--doc/server/plugins/generators/tgenshi/clientsxml.txt94
-rw-r--r--doc/server/plugins/generators/tgenshi/ganglia.txt174
-rw-r--r--doc/server/plugins/generators/tgenshi/grubconf.txt35
-rw-r--r--doc/server/plugins/generators/tgenshi/hosts.txt21
-rw-r--r--doc/server/plugins/generators/tgenshi/index.txt (renamed from doc/server/plugins/generators/tgenshi.txt)59
-rw-r--r--doc/server/plugins/generators/tgenshi/iptables.txt301
-rw-r--r--doc/server/plugins/generators/tgenshi/motd.txt169
-rw-r--r--doc/server/plugins/generators/tgenshi/mycnf.txt34
-rw-r--r--doc/server/plugins/generators/tgenshi/test.txt157
-rw-r--r--doc/server/plugins/index.txt1
-rw-r--r--doc/unsorted/index.txt9
12 files changed, 1054 insertions, 25 deletions
diff --git a/doc/server/plugins/generators/tgenshi/bcfg2-cron.txt b/doc/server/plugins/generators/tgenshi/bcfg2-cron.txt
new file mode 100644
index 000000000..56def1e3d
--- /dev/null
+++ b/doc/server/plugins/generators/tgenshi/bcfg2-cron.txt
@@ -0,0 +1,25 @@
+.. -*- mode: rst -*-
+
+.. _server-plugins-generators-tgenshi-bcfg2-cron:
+
+bcfg2-cron
+==========
+
+As submitted by Kamil Kisiel
+
+The following is my ``/etc/cron.d/bcfg2`` file. It uses the python random
+module seeded with the client hostname to generate a random time for the
+client to check in. The hostname seed ensures the generated file is the
+same each time the client checks in. This cron file helps to distribute
+the load on the Bcfg2 server since not all machines are checking in at
+the same time.::
+
+ {% python
+ from genshi.builder import tag
+ import random
+ random.seed(metadata.hostname)
+ %}\
+ ${random.randint(0,60)} * * * * root /usr/sbin/bcfg2 &> /dev/null
+
+You can apply the same concept to the other time fields by adding another
+``${random.randint()}`` call.
diff --git a/doc/server/plugins/generators/tgenshi/clientsxml.txt b/doc/server/plugins/generators/tgenshi/clientsxml.txt
new file mode 100644
index 000000000..3d5553570
--- /dev/null
+++ b/doc/server/plugins/generators/tgenshi/clientsxml.txt
@@ -0,0 +1,94 @@
+.. -*- mode: rst -*-
+
+.. _server-plugins-generators-tgenshi-clientsxml:
+
+clientsxml
+==========
+
+As submitted by dclark
+
+Here is an example of maintaining the bcfg2 server's
+``/var/lib/bcfg2/Metadata/clients.xml`` file using TGenshi.
+
+There are two main advantages:
+
+#. Password storage is centralized in the ``etc/properties.xml`` file
+ this helps maintain consistency, makes changing passwords easier,
+ and also makes it easier to share your configurations with other
+ sites/people.
+
+#. You can template the file using Genshi's `{% def %}` syntax,
+ which makes `clients.xml` much more readable. An important
+ thing to note is how the `name` variable is handled - when
+ just referring to it the standard `${name}` syntax is used, but
+ when it is used as a variable in the expression to get the password,
+ `password="${properties.properties.find('password').find('bcfg2-client').find(name).text}"`,
+ it is just referred to as `name`.
+
+There is the disadvantage that sometimes 2 passes will be needed to get
+to a consistent state.
+
+Possible improvements:
+
+#. Wrapper for bcfg2 client runs on the bcfg2 server, perhaps using a call
+ to `bcfg2-info buildfile`, so clients.xml is always generated before
+ everything else happens (since the state of clients.xml can influence
+ everything else bcfg2-server does).
+
+#. We really don't care what the client passwords are, just that they
+ exist, so instead of listing them a master password combined with
+ some kind of one-way hash based on the `name` might make more sense,
+ and make `properties.xml` easier to maintain.
+
+ * TGenshi/var/lib/bcfg2/Metadata/clients.xml/template.newtxt:
+
+ .. code-block:: xml
+
+ <!-- TGenshi/var/lib/bcfg2/Metadata/clients.xml/template.newtxt -->
+ <!-- Do not edit this file directly - edit only the above template -->
+
+ {# Doc: http://bcfg2.org/wiki/Authentication #}\
+ {% def static(profile,name,address) %}
+ <Client
+ profile="${profile}"
+ name="${name}"
+ uuid="${name}"
+ password="${properties.properties.find('password').find('bcfg2-client').find(name).text}"
+ address="${address}"
+ location="fixed"
+ secure="true"
+ />\
+ {% end %}\
+ {% def dynamic(profile,name) %}
+ <Client
+ profile="${profile}"
+ name="${name}"
+ uuid="${name}"
+ password="${properties.properties.find('password').find('bcfg2-client').find(name).text}"
+ location="floating"
+ secure="true"
+ />\
+ {% end %}\
+ <Clients version="3.0">\
+ ${static('group-server-collab','campaigns.example.com','192.168.111.1')}
+ ${static('group-server-collab','info.office.example.com','192.168.111.2')}
+ ${static('group-server-config','config.example.com','192.168.111.3')}
+ ${dynamic('group-project-membercard','membercard')}
+ ${dynamic('group-person-somename','somename.office.example.com')}
+ </Clients>
+
+ * etc/properties.xml snippit:
+
+ .. code-block:: xml
+
+ <Properties>
+ <password>
+ <bcfg2-client>
+ <campaigns.example.com>FAKEpassword1</campaigns.example.com>
+ <info.office.example.com>FAKEpassword2</info.office.example.com>
+ <config.example.com>FAKEpassword3</config.example.com>
+ <membercard>FAKEpassword4</membercard>
+ <somename.office.example.com>FAKEpassword5</somename.office.example.com>
+ </bcfg2-client>
+ </password>
+ </Properties>
diff --git a/doc/server/plugins/generators/tgenshi/ganglia.txt b/doc/server/plugins/generators/tgenshi/ganglia.txt
new file mode 100644
index 000000000..1ad737900
--- /dev/null
+++ b/doc/server/plugins/generators/tgenshi/ganglia.txt
@@ -0,0 +1,174 @@
+.. -*- mode: rst -*-
+
+.. _server-plugins-generators-tgenshi-ganglia:
+
+ganglia
+=======
+
+Another interesting example of **TGenshi** templating is to automatically
+generate ``gmond``/``gmetad`` configuration files. The idea is that each
+cluster is headless: it communicates with the rest of the cluster members
+on an isolated multicast IP address and port. Any of the cluster members
+is therefore isolated on that particular ip/port pair. Additionally,
+each ``gmond`` instance **also** listens on UDP. This allows for any of
+the cluster members to be polled for information on the entire cluster!
+
+The second part of the trick is in ``gmetad.conf``. Here, we dynamically
+generate a list of clusters (based on profiles names) and a list of
+members to poll (based on the clients in said profiles). As the number of
+profiles and client grows, this list will grow automatically as well. When
+a new host is added, ``gmetad`` will receive an updated configuration and
+act accordingly.
+
+There **is** one caveat though. The ``gmetad.conf`` parser is hard coded
+to read 16 arguments per ``data_source`` line. If you have more than 15
+nodes in a cluster, you will see a warning in the logs. You can either
+ignore it, or truncate the list to the first 15 members.
+
+In our environment, a profile is a one to one match with the role of
+that particular host. You can also do this based on groups, or any other
+client property.
+
+Bundler/ganglia.xml
+-------------------
+
+.. code-block:: xml
+
+ <Bundle name='ganglia' version='2.0' revision='$Revision$' origin='$HeadURL$' >
+ <Package name='ganglia-gmond' />
+ <Package name='ganglia-gmond-modules-python' />
+ <ConfigFile name='/etc/ganglia/gmond.conf' />
+ <Service name='gmond' />
+ <Action name='gmond-reload' />
+
+ <Group name='gmetad-server'>
+ <Package name='ganglia-gmetad'/>
+ <Package name='ganglia-web'/>
+ <Package name='rrdtool'/>
+ <ConfigFile name='/etc/ganglia/gmetad.conf' />
+ <Service name='gmetad' />
+ </Group>
+ </Bundle>
+
+Rules/services-ganglia.xml
+--------------------------
+
+.. code-block:: xml
+
+ <Rules priority='10' revision='$Revision$' origin='$HeadURL$' >
+ <Service name='gmond' type='chkconfig' status='on' />
+ <Group name='gmetad-server'>
+ <Service name='gmetad' type='chkconfig' status='on' />
+ </Group>
+ </Rules>
+
+TGenshi/etc/ganglia/gmetad.conf/template.newtxt
+-----------------------------------------------
+
+::
+
+ {% python
+ client_metadata = metadata.query.all()
+ profile_array = {}
+ seen = []
+ for item in client_metadata:
+ if item.profile not in seen:
+ seen.append(item.profile)
+ profile_array[item.profile]=[]
+ profile_array[item.profile].append(item.hostname)
+ seen.sort()
+ %}\
+
+ gridname "Our Grid"
+
+ {% for profile in seen %}
+ data_source "${profile}" \
+ {% for host in profile_array[profile] %}\
+ ${host} \
+ {% end %}\
+ {% end %}
+
+ rrd_rootdir "/var/lib/ganglia/rrds"
+
+TGenshi/etc/ganglia/gmond.conf/template.newtxt
+----------------------------------------------
+
+::
+
+ {% python
+ from genshi.builder import tag
+ import random
+ random.seed(metadata.profile)
+ last_octet=random.randint(2,254)
+ %}\
+ /*
+ $$Id$$
+ $$HeadURL$$
+ */
+
+ /* This configuration is as close to 2.5.x default behavior as possible
+ The values closely match ./gmond/metric.h definitions in 2.5.x */
+ globals {
+ daemonize = yes
+ setuid = yes
+ user = nobody
+ debug_level = 0
+ max_udp_msg_len = 1472
+ mute = no
+ deaf = no
+ host_dmax = 1800 /* 30 minutes */
+ cleanup_threshold = 604800 /*secs=1 week */
+ gexec = no
+ send_metadata_interval = 0
+ }
+
+ /* If a cluster attribute is specified, then all gmond hosts are wrapped inside
+ * of a <CLUSTER> tag. If you do not specify a cluster tag, then all <HOSTS> will
+ * NOT be wrapped inside of a <CLUSTER> tag. */
+ cluster {
+ name = "${metadata.profile}"
+ owner = "user@company.net"
+ latlong = "unspecified"
+ url = "unspecified"
+ }
+
+ /* The host section describes attributes of the host, like the location */
+ host {
+ location = "unspecified"
+ }
+
+ /* Feel free to specify as many udp_send_channels as you like. Gmond
+ used to only support having a single channel */
+ udp_send_channel {
+ host = ${metadata.hostname}
+ port = 8649
+ }
+ udp_send_channel {
+ mcast_join = 239.2.11.${last_octet}
+ port = 8649
+ ttl = 1
+ }
+
+ /* You can specify as many udp_recv_channels as you like as well. */
+ udp_recv_channel {
+ port = 8649
+ bind = ${metadata.hostname}
+ }
+ udp_recv_channel {
+ mcast_join = 239.2.11.${last_octet}
+ bind = 239.2.11.${last_octet}
+ port = 8649
+ }
+
+ /* You can specify as many tcp_accept_channels as you like to share
+ an xml description of the state of the cluster */
+ tcp_accept_channel {
+ port = 8649
+ }
+
+ /* Each metrics module that is referenced by gmond must be specified and
+ loaded. If the module has been statically linked with gmond, it does not
+ require a load path. However all dynamically loadable modules must include
+ a load path. */
+ modules {
+ /* [snip] */
diff --git a/doc/server/plugins/generators/tgenshi/grubconf.txt b/doc/server/plugins/generators/tgenshi/grubconf.txt
new file mode 100644
index 000000000..d4381f10b
--- /dev/null
+++ b/doc/server/plugins/generators/tgenshi/grubconf.txt
@@ -0,0 +1,35 @@
+.. -*- mode: rst -*-
+
+.. _server-plugins-generators-tgenshi-grubconf:
+
+grubconf
+========
+
+Automate the build of grub.conf based on probe data. In this case, we take
+the results from three probes, serial-console-speed, grub-serial-order,
+and current-kernel to fill in a few variables. In addition, we want
+at least two entries set up for the kernel: a multiuser and a single
+user option.
+
+::
+
+ # grub.conf generated by anaconda
+ #
+ # Note that you do not have to rerun grub after making changes to this file
+ # NOTICE: You have a /boot partition. This means that
+ # all kernel and initrd paths are relative to /boot/, eg.
+ # root (hd0,0)
+ # kernel /vmlinuz-version ro root=/dev/VolGroup00/LogVol00
+ # initrd /initrd-version.img
+ #boot=/dev/sda
+ default=0
+ timeout=5
+ serial --unit=0 --speed=${metadata.Probes['serial-console-speed']}
+ terminal --timeout=5 ${metadata.Probes['grub-serial-order']}
+
+ {% for kernbootoption in ["", "single"] %}\
+ title Red Hat Enterprise Linux Server (${metadata.Probes['current-kernel']})) ${kernbootoption}
+ root (hd0,0)
+ kernel /vmlinuz-${metadata.Probes['current-kernel']} ro root=/dev/VolGroup00/LogVol00 console=ttyS0,${metadata.Probes['serial-console-speed']}n8 console=tty0 rhgb quiet ${kernbootoption}
+ initrd /initrd-${metadata.Probes['current-kernel']}.img
+ {% end %}\
diff --git a/doc/server/plugins/generators/tgenshi/hosts.txt b/doc/server/plugins/generators/tgenshi/hosts.txt
new file mode 100644
index 000000000..fd3446df8
--- /dev/null
+++ b/doc/server/plugins/generators/tgenshi/hosts.txt
@@ -0,0 +1,21 @@
+.. -*- mode: rst -*-
+
+.. _server-plugins-generators-tgenshi-hosts:
+
+hosts
+=====
+
+This is an example of creating ``/etc/hosts`` based on metadata.hostname::
+
+ # Do not remove the following line, or various programs
+ # that require network functionality will fail.
+ 127.0.0.1 localhost.localdomain localhost
+ ::1 localhost6.localdomain6 localhost6
+ {% python
+ import socket
+ import re
+ ip = socket.gethostbyname(metadata.hostname)
+
+ shortname = re.split("\.", metadata.hostname)
+ %}\
+ ${ip} ${metadata.hostname} ${shortname[0]}
diff --git a/doc/server/plugins/generators/tgenshi.txt b/doc/server/plugins/generators/tgenshi/index.txt
index c0d9427b1..f482fa143 100644
--- a/doc/server/plugins/generators/tgenshi.txt
+++ b/doc/server/plugins/generators/tgenshi/index.txt
@@ -1,12 +1,13 @@
.. -*- mode: rst -*-
-.. _server-plugins-generators-tgenshi:
+.. _server-plugins-generators-tgenshi-index:
=======
TGenshi
=======
-This page documents the TGenshi plugin. This plugin works with version 0.4 and newer of the genshi library.
+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,
@@ -25,7 +26,12 @@ generators line in ``/etc/bcfg2.conf`` on your Bcfg server. For example::
generators = SSHbase,Cfg,Pkgmgr,Svcmgr,Rules,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.
+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
@@ -49,11 +55,6 @@ See the genshi `documentation
<http://genshi.edgewall.org/wiki/Documentation>`_ for examples of
Genshi syntax.
-Examples
-========
-
-See [wiki:Plugins/TGenshi/examples] for some TGenshi template examples, including the great starting point [wiki:Plugins/TGenshi/examples/motd /etc/motd]. They will use the new style of Genshi syntax, unless noted otherwise.
-
Examples: Old Genshi Syntax
---------------------------
@@ -62,7 +63,9 @@ Genshi's web pages recommend against using this syntax, as it may disappear from
Group Negation
--------------
-Templates are also useful for cases where more sophisticated boolean operations than those supported by Cfg are needed. For example, the template::
+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
@@ -79,16 +82,40 @@ Produces:
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.
+This flexibility provides the ability to build much more compact and
+succinct definitions of configuration contents than Cfg can.
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).
+**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
+**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::
+ :maxdepth: 1
+
+ bcfg2-cron
+ clientsxml
+ ganglia
+ grubconf
+ hosts
+ iptables
+ motd
+ mycnf
+ test
diff --git a/doc/server/plugins/generators/tgenshi/iptables.txt b/doc/server/plugins/generators/tgenshi/iptables.txt
new file mode 100644
index 000000000..6f635a7a1
--- /dev/null
+++ b/doc/server/plugins/generators/tgenshi/iptables.txt
@@ -0,0 +1,301 @@
+.. -*- mode: rst -*-
+
+.. _server-plugins-generators-tgenshi-iptables:
+
+iptables
+========
+
+* Setup a TGenshi base iptables file that contains the basic rules you
+ want every host to have
+* Create a custom dir that has group and host specific rules you want
+ to apply
+* To be safe you should have a client side IptablesDeadmanScript if you
+ intend on having bcfg2 bounce iptables upon rule updates
+
+/repository/TGenshi/etc/sysconfig/iptables/template.newtxt
+----------------------------------------------------------
+
+::
+
+ {% python
+ from genshi.builder import tag
+ import os,sys
+ import Bcfg2.Options
+
+ opts = { 'repo': Bcfg2.Options.SERVER_REPOSITORY }
+ setup = Bcfg2.Options.OptionParser(opts)
+ setup.parse('--')
+ repo = setup['repo']
+ basedir = '%s' % (repo)
+
+ # for instance: /var/lib/bcfg2/custom/etc/sysconfig/iptables/
+ bcfg2BaseDir = basedir + '/includes' + name + '/'
+
+
+ def checkHostFile(hostName, type):
+ fileName = bcfg2BaseDir + type + '.H_' + hostName
+ if os.path.isfile(fileName)==True :
+ return fileName
+ else:
+ return fileName
+
+ def checkGroupFile(groupName, type):
+ fileName = bcfg2BaseDir + type + '.G_' + groupName
+ if os.path.isfile(fileName)==True :
+ return fileName
+ else:
+ return fileName
+
+ %}\
+ # BCFG2 GENERATED IPTABLES
+ # DO NOT CHANGE THIS
+ # $$Id$$
+ # $$HeadURL$$
+ # Templates live in ${bcfg2BaseDir}
+ # Manual customization of this file will get reverted.
+ # ----------------------------- FILTER --------------------------------- #
+ # Default CHAINS for FILTER:
+ *filter
+ :INPUT DROP [0:0]
+ :FORWARD DROP [0:0]
+ :OUTPUT ACCEPT [0:0]
+ :NO-SMTP - [0:0]
+
+ #Default rules
+ #discard malicious packets
+ -A INPUT -p tcp --tcp-flags ALL ACK,RST,SYN,FIN -j DROP
+ -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
+ -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
+ #Allow incoming ICMP
+ -A INPUT -p icmp -m icmp -j ACCEPT
+ #Accept localhost traffic
+ -A INPUT -i lo -j ACCEPT
+ # Allow already established sessions to remain
+ -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
+
+ # Deny inbound SMTP delivery (still allows outbound connections)
+ -A INPUT -m state --state NEW -m tcp -p tcp --tcp-flags FIN,SYN,RST,ACK SYN --dport 25 -j NO-SMTP
+ -A NO-SMTP -j LOG --log-prefix " Incoming SMTP (denied) "
+ -A NO-SMTP -j DROP
+
+ # Allow SSH Access
+ -A INPUT -p tcp -m state --state NEW -m tcp --tcp-flags FIN,SYN,RST,ACK SYN --dport 22 -j SSH
+ -A SSH -s 192.0.0.0/255.0.0.0 -j ACCEPT
+
+ # Allow Ganglia Access
+ -A INPUT -m state --state NEW -m tcp -p tcp --tcp-flags FIN,SYN,RST,ACK SYN --src 192.168.1.1 --dport 8649 -j ACCEPT
+ # Gmetad access to gmond
+ -A INPUT -m state --state NEW -m tcp -p tcp --tcp-flags FIN,SYN,RST,ACK SYN --src 192.168.1.1 --dport 8649 -j ACCEPT
+ # Gmond UDP multicast
+ -A INPUT -m state --state NEW -m udp -p udp --dport 8649 -j ACCEPT
+
+ {% if metadata.groups %}\
+ # group custom FILTER rules:
+ {% for group in metadata.groups %}\
+ {% include ${checkGroupFile(group,'custom-filter')} %}\
+ {% end %}\
+ {% end %}\
+
+ # host-specific FILTER rules:
+ {% include ${checkHostFile(metadata.hostname, 'custom-filter')} %}\
+
+ COMMIT
+ # ------------------------------- NAT ---------------------------------- #
+ *nat
+
+ # Default CHAINS for NAT:
+ :PREROUTING ACCEPT [0:0]
+ :OUTPUT ACCEPT [0:0]
+ :POSTROUTING ACCEPT [0:0]
+
+ {% if metadata.groups %}\
+ # group NAT for PREROUTING:
+ {% for group in metadata.groups %}\
+ {% include ${checkGroupFile(group,'nat-prerouting')} %}\
+ {% end %}\
+ {% end %}\
+
+ {% if metadata.groups %}\
+ # group NAT for OUTPUT:
+ {% for group in metadata.groups %}\
+ {% include ${checkGroupFile(group,'nat-output')} %}\
+ {% end %}\
+ {% end %}\
+
+ {% if metadata.groups %}\
+ # group NAT for POSTROUTING:
+ {% for group in metadata.groups %}\
+ {% include ${checkGroupFile(group,'nat-postrouting')} %}\
+ {% end %}\
+ {% end %}\
+
+ {% if metadata.groups %}\
+ # group custom NAT rules:
+ {% for group in metadata.groups %}\
+ {% include ${checkGroupFile(group,'custom-nat')} %}\
+ {% end %}\
+ {% end %}\
+
+ # host-specific NAT ruls:
+ {% include ${checkHostFile(metadata.hostname, 'custom-nat')} %}\
+ COMMIT
+ # ----------------------------- MANGLE -------------------------------- #
+ *mangle
+
+ # Default CHAINS for MANGLE:
+ :PREROUTING ACCEPT [0:0]
+ :INPUT ACCEPT [0:0]
+ :FORWARD ACCEPT [0:0]
+ :OUTPUT ACCEPT [0:0]
+ :POSTROUTING ACCEPT [0:0]
+
+ {% if metadata.groups %}\
+ # group MANGLE for PREROUTING:
+ {% for group in metadata.groups %}\
+ {% include ${checkGroupFile(group,'mangle-prerouting')} %}\
+ {% end %}\
+ {% end %}\
+
+ {% if metadata.groups %}\
+ # group MANGLE for INPUT:
+ {% for group in metadata.groups %}\
+ {% include ${checkGroupFile(group,'mangle-input')} %}\
+ {% end %}\
+ {% end %}\
+
+ {% if metadata.groups %}\
+ # group MANGLE for FORWARD:
+ {% for group in metadata.groups %}\
+ {% include ${checkGroupFile(group,'mangle-forward')} %}\
+ {% end %}\
+ {% end %}\
+
+ {% if metadata.groups %}\
+ # group MANGLE for OUTPUT:
+ {% for group in metadata.groups %}\
+ {% include ${checkGroupFile(group,'mangle-output')} %}\
+ {% end %}\
+ {% end %}\
+
+ {% if metadata.groups %}\
+ # group MANGLE for POSTROUTING rules:
+ {% for group in metadata.groups %}\
+ {% include ${checkGroupFile(group,'mangle-postrouting')} %}\
+ {% end %}\
+ {% end %}\
+
+ {% if metadata.groups %}\
+ # group custom MANGLE rules:
+ {% for group in metadata.groups %}\
+ {% include ${checkGroupFile(group,'custom-mangle')} %}\
+ {% end %}\
+ {% end %}\
+
+ # host-specific MANGLE rules:
+ {% include ${checkHostFile(metadata.hostname, 'custom-mangle')} %}\
+ COMMIT
+
+/var/lib/bcfg2/custom/etc/sysconfig/iptables/custom-filter.G_mysql-server
+-------------------------------------------------------------------------
+
+::
+
+ :MYSQL - [0:0]
+ -A INPUT -p tcp -m state --state NEW -m tcp --dport 3306 --tcp-flags FIN,SYN,RST,ACK SYN -j MYSQL
+ -A MYSQL -s 192.168.0.0/255.0.0.0 -j ACCEPT
+
+For a host that is in the mysql-server group you get an iptables file
+that looks like the following::
+
+ # BCFG2 GENERATED IPTABLES
+ # DO NOT CHANGE THIS
+ # $Id: template.newtxt 5402 2009-08-19 22:50:06Z unixmouse$
+ # $HeadURL: https://svn.fakecompany.net/bcfg2/trunk/repository/TGenshi/etc/sysconfig/iptables/template.newtxt $
+ # Templates live in /var/lib/bcfg2/custom/etc/sysconfig/iptables/
+ # Manual customization of this file will get reverted.
+ # ----------------------------- FILTER --------------------------------- #
+ # Default CHAINS for FILTER:
+ *filter
+ :INPUT DROP [0:0]
+ :FORWARD DROP [0:0]
+ :OUTPUT ACCEPT [0:0]
+ :NO-SMTP - [0:0]
+
+ #Default rules
+ #discard malicious packets
+ -A INPUT -p tcp --tcp-flags ALL ACK,RST,SYN,FIN -j DROP
+ -A INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP
+ -A INPUT -p tcp --tcp-flags SYN,RST SYN,RST -j DROP
+ # Allow incoming ICMP
+ -A INPUT -p icmp -m icmp -j ACCEPT
+ # Accept localhost traffic
+ -A INPUT -i lo -j ACCEPT
+ # Allow already established sessions to remain
+ -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
+
+ # Deny inbound SMTP delivery (still allows outbound connections)
+ -A INPUT -m state --state NEW -m tcp -p tcp --tcp-flags FIN,SYN,RST,ACK SYN --dport 25 -j NO-SMTP
+ -A NO-SMTP -j LOG --log-prefix " Incoming SMTP (denied) "
+ -A NO-SMTP -j DROP
+
+ # Allow SSH Access
+ :SSH - [0:0]
+ -A INPUT -p tcp -m state --state NEW -m tcp --tcp-flags FIN,SYN,RST,ACK SYN --dport 22 -j SSH
+ -A SSH -s 192.168.0.0/255.0.0.0 -j ACCEPT
+
+ # Allow Ganglia Access
+ -A INPUT -m state --state NEW -m tcp -p tcp --tcp-flags FIN,SYN,RST,ACK SYN --src 192.168.1.1 --dport 8649 -j ACCEPT
+ #Gmetad access to gmond
+ -A INPUT -m state --state NEW -m tcp -p tcp --tcp-flags FIN,SYN,RST,ACK SYN --src 192.168.1.1 --dport 8649 -j ACCEPT
+ #Gmond UDP multicast
+ -A INPUT -m state --state NEW -m udp -p udp --dport 8649 -j ACCEPT
+
+ # group custom FILTER rules:
+ :MYSQL - [0:0]
+ -A INPUT -p tcp -m state --state NEW -m tcp --dport 3306 --tcp-flags FIN,SYN,RST,ACK SYN -j MYSQL
+ -A MYSQL -s 192.168.0.0/255.0.0.0 -j ACCEPT
+
+ # host-specific FILTER rules:
+
+ COMMIT
+ # ------------------------------- NAT ---------------------------------- #
+ *nat
+
+ # Default CHAINS for NAT:
+ :PREROUTING ACCEPT [0:0]
+ :OUTPUT ACCEPT [0:0]
+ :POSTROUTING ACCEPT [0:0]
+
+ # group NAT for PREROUTING:
+
+ # group NAT for OUTPUT:
+
+ # group NAT for POSTROUTING:
+
+ # group custom NAT rules:
+
+ # host-specific NAT rules:
+ COMMIT
+ # ----------------------------- MANGLE -------------------------------- #
+ *mangle
+
+ # Default CHAINS for MANGLE:
+ :PREROUTING ACCEPT [0:0]
+ :INPUT ACCEPT [0:0]
+ :FORWARD ACCEPT [0:0]
+ :OUTPUT ACCEPT [0:0]
+ :POSTROUTING ACCEPT [0:0]
+
+ # group MANGLE for PREROUTING:
+
+ # group MANGLE for INPUT:
+ # group MANGLE for FORWARD:
+
+ # group MANGLE for OUTPUT:
+
+ # group MANGLE for POSTROUTING rules:
+
+ # group custom MANGLE rules:
+
+ # host-specific MANGLE rules:
+ COMMIT
diff --git a/doc/server/plugins/generators/tgenshi/motd.txt b/doc/server/plugins/generators/tgenshi/motd.txt
new file mode 100644
index 000000000..89cf77dc5
--- /dev/null
+++ b/doc/server/plugins/generators/tgenshi/motd.txt
@@ -0,0 +1,169 @@
+.. -*- mode: rst -*-
+
+.. _server-plugins-generators-tgenshi-motd:
+
+motd
+====
+
+The following template automatically generates a MOTD (message of the
+day) file that describes the system in terms of its Bcfg2 metadata
+and probe responses. It conditionally displays groups, categories,
+and probe responses, if there exists any data for them.
+
+New Style of TGenshi
+--------------------
+
+This is the preferred way of creating TGenshi contents. It requires
+Genshi 0.5 or later.
+
+On the Bcfg2 server
+^^^^^^^^^^^^^^^^^^^
+
+Where, **$bcfg2** is your Bcfg2 repository on your Bcfg2 server, the
+following files need to be created:
+
+::
+
+ $bcfg2/TGenshi/etc/motd/info.xml
+ $bcfg2/TGenshi/etc/motd/template.newtxt
+
+The contents of ``motd/template.newtxt`` could be something like this::
+
+ ------------------------------------------------------------------------
+ GOALS FOR SERVER MANGED 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.
+
+This template gets the hostname, groups membership of the host, categories
+of the host (if any), and result of probes on the host (if any). The
+template formats this in with a header and footer that makes it visually
+more appealing.
+
+A ``motd/info.xml`` file isn't strictly needed, because ``/etc/motd``
+has the Bcfg2 default permissions (i.e. root:root 0644), but it can be
+included for completeness.
+
+Output
+^^^^^^
+
+One possible output of this template would be the following::
+
+ ------------------------------------------------------------------------
+ GOALS FOR SERVER MANGED BY BCFG2
+ ------------------------------------------------------------------------
+ Hostname is cobra.example.com
+
+ Groups:
+ * oracle-server
+ * centos5-5.2
+ * centos5
+ * redhat
+ * x86_64
+ * sys-vmware
+
+ Categories:
+ * os-variant
+ * os
+ * database-server
+ * os-version
+
+
+ Probes:
+ * arch x86_64
+ * network intranet_network
+ * diskspace Filesystem Size Used Avail Use% Mounted on
+ /dev/mapper/VolGroup00-LogVol00
+ 18G 2.1G 15G 13% /
+ /dev/sda1 99M 13M 82M 13% /boot
+ tmpfs 3.8G 0 3.8G 0% /dev/shm
+ /dev/mapper/mhcdbo-clear
+ 1.5T 198M 1.5T 1% /mnt/san-oracle
+ * virtual vmware
+
+ -------------------------------------------------------------------------
+ IT MOTD
+ -------------------------------------------------------------------------
+ Please create a Ticket for any system level changes you need from IT.
+
+Taking it to the next level
+^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+One way to make this even more useful, is to only include the result of
+certain probes. It would also be a nice feature to be able to include
+customer messages on a host or group level.
+
+Old Style of TGenshi
+--------------------
+
+The following is a way to do the same thing using the older,
+it-may-be-depreciated, style of Genshi (pre-0.5).::
+
+ 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
+
+This template results in::
+
+ > buildfile /bar.conf ubik3
+ <ConfigFile name="/bar.conf" owner="root" perms="0644" group="root">Hostname is ubik3
+
+ Groups:
+ * desktop
+ * computeserver
+ * mcs-base
+ * ypbound
+ * workstation
+ * mysql-4
+ * debian-sarge-base
+ * debian-sarge
+ * base
+ * debian
+
+ Categories:
+ * noyp
+ * mysql
+
+ </ConfigFile>
diff --git a/doc/server/plugins/generators/tgenshi/mycnf.txt b/doc/server/plugins/generators/tgenshi/mycnf.txt
new file mode 100644
index 000000000..7cf48ece0
--- /dev/null
+++ b/doc/server/plugins/generators/tgenshi/mycnf.txt
@@ -0,0 +1,34 @@
+.. -*- mode: rst -*-
+
+.. _server-plugins-generators-tgenshi-mycnf:
+
+mycnf
+=====
+
+The following template generates a ``server-id`` based on the last two
+numeric parts of the IP address. The "slave" portion of the configuration
+only applies to machines in the "slave" group.::
+
+ {% python
+ from genshi.builder import tag
+ import socket
+ parts = socket.gethostbyname(metadata.hostname).split('.')
+ server_id = parts[2] + parts[3]
+ %}\
+ [mysqld]
+
+ # [snip]
+
+ server-id = ${server_id}
+
+ # Replication configuration
+
+ {% if "slave" in metadata.groups %}\
+ relay-log = /data01/mysql/log/mysql-relay-bin
+ log-slave-updates = 1
+ {% end %}\
+ sync-binlog = 1
+ #read-only = 1
+ #report-host = <server fqdn>
+
+ # [snip]
diff --git a/doc/server/plugins/generators/tgenshi/test.txt b/doc/server/plugins/generators/tgenshi/test.txt
new file mode 100644
index 000000000..5dd5efae8
--- /dev/null
+++ b/doc/server/plugins/generators/tgenshi/test.txt
@@ -0,0 +1,157 @@
+.. -*- mode: rst -*-
+
+.. _server-plugins-generators-tgenshi-test:
+
+test
+====
+
+As submitted by dclark
+
+This file just shows you what's available. It assumes a
+``/var/lib/bcfg2/etc/properties.xml`` file with an entry like this:
+
+.. code-block:: xml
+
+ #!text/xml
+ <Properties>
+ <password>
+ <bcfg2>fakeBCFG2password</bcfg2>
+ </password>
+ </Properties>
+
+::
+
+ 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 %}\
+
+ Two main ways to get the same property value:
+ ${properties.properties.find('password').find('bcfg2').text}
+ ${properties.properties.xpath('password/bcfg2')[0].text}
+
+ One way to get information about metadata and properties:
+
+ dir(metadata):
+ {% for var in dir(metadata) %}\
+ ${var} \
+ {% end %}
+
+ dir(properties):
+ {% for var in dir(properties) %}\
+ ${var} \
+ {% end %}
+
+ dir(properties.entries):
+ {% for var in dir(properties.entries) %}\
+ ${var} \
+ {% end %}
+
+ dir(properties.label):
+ {% for var in dir(properties.label) %}\
+ ${var} \
+ {% end %}
+
+ dir(properties.name):
+ {% for var in dir(properties.name) %}\
+ ${var} \
+ {% end %}
+
+ dir(properties.properties):
+ {% for var in dir(properties.properties) %}\
+ ${var} \
+ {% end %}
+
+When the above file is saved as
+``/var/lib/bcfg2/TGenshi/test/template.newtxt`` and generated with
+``bcfg2-info buildfile /test test.hostname.org``, the results look like
+this (below reformatted a little bit to fit in 80 columns)::
+
+ Failed to read file probed.xml
+ Processed 44 gamin events in 0.108 seconds. 0 collapsed
+ Processed 17 gamin events in 0.245 seconds. 0 collapsed
+ Processed 17 gamin events in 0.163 seconds. 0 collapsed
+ Processed 21 gamin events in 0.197 seconds. 0 collapsed
+ Processed 0 gamin events in 0.100 seconds. 0 collapsed
+ Processed 12 gamin events in 0.105 seconds. 0 collapsed
+ Processed 0 gamin events in 0.100 seconds. 0 collapsed
+ <?xml version='1.0' encoding='UTF-8'?>
+ <ConfigFile name="/test" owner="root" perms="644" encoding="ascii" group="root" paranoid="false">
+ Hostname is test.hostname.org
+
+ Groups:
+ bcfg2-server
+
+
+ Two main ways to get the same property value:
+ fakeBCFG2password
+ fakeBCFG2password
+
+ One way to get information about metadata and properties:
+
+ dir(metadata):
+ __class__ __delattr__ __dict__ __doc__ __getattribute__ __hash__ __init__
+ __module__ __new__ __reduce__ __reduce_ex__ __repr__ __setattr__ __str__
+ __weakref__ all bundles categories get_clients_by_group get_clients_by_profile
+ groups hostname inGrouppassword probes uuid
+
+ dir(properties):
+ HandleEvent Index __class__ __delattr__ __dict__ __doc__ __getattribute__
+ __hash__ __identifier__ __init__ __iter__ __module__ __new__ __reduce__
+ __reduce_ex__ __repr__ __setattr__ __str__ __weakref__ entries label name
+ properties
+
+ dir(properties.entries):
+ __add__ __class__ __contains__ __delattr__ __delitem__ __delslice__ __doc__
+ __eq__ __ge__ __getattribute__ __getitem__ __getslice__ __gt__ __hash__
+ __iadd__ __imul__ __init__ __iter__ __le__ __len__ __lt__ __mul__ __ne__
+ __new__ __reduce__ __reduce_ex__ __repr__ __reversed__ __rmul__ __setattr__
+ __setitem__ __setslice__ __str__ append count extend index insert pop remove
+ reverse sort
+
+ dir(properties.label):
+ __add__ __class__ __contains__ __delattr__ __doc__ __eq__ __ge__
+ __getattribute__ __getitem__ __getnewargs__ __getslice__ __gt__ __hash__
+ __init__ __le__ __len__ __lt__ __mod__ __mul__ __ne__ __new__ __reduce__
+ __reduce_ex__ __repr__ __rmod__ __rmul__ __setattr__ __str__ capitalize center
+ count decode encode endswith expandtabs find index isalnum isalpha isdigit
+ islower isspace istitle isupper join ljust lower lstrip partition replace
+ rfind rindex rjust rpartition rsplit rstrip split splitlinesstartswith strip
+ swapcase title translate upper zfill
+
+ dir(properties.name):
+ __add__ __class__ __contains__ __delattr__ __doc__ __eq__ __ge__
+ __getattribute__ __getitem__ __getnewargs__ __getslice__ __gt__ __hash__
+ __init__ __le__ __len__ __lt__ __mod__ __mul__ __ne__ __new__ __reduce__
+ __reduce_ex__ __repr__ __rmod__ __rmul__ __setattr__ __str__ capitalize center
+ count decode encode endswith expandtabs find index isalnum isalpha isdigit
+ islower isspace istitle isupper join ljust lower lstrip partition replace
+ rfind rindex rjust rpartition rsplit rstrip split splitlinesstartswith strip
+ swapcase title translate upper zfill
+
+ dir(properties.properties):
+ __class__ __contains__ __copy__ __deepcopy__ __delattr__ __delitem__
+ __delslice__ __doc__ __getattribute__ __getitem__ __getslice__ __hash__
+ __init__ __iter__ __len__ __new__ __nonzero__ __reduce__ __reduce_ex__
+ __repr__ __reversed__ __setattr__ __setitem__ __setslice__ __str__ _init
+ addnext addprevious append attrib clear extend find findall findtext get
+ getchildren getiterator getnext getparent getprevious getroottree index insert
+ items iterancestors iterchildren iterdescendants itersiblings keys makeelement
+ nsmap prefix remove replace set sourceline tag tail text values xpath
+ </ConfigFile>
diff --git a/doc/server/plugins/index.txt b/doc/server/plugins/index.txt
index 37879d207..104d4b516 100644
--- a/doc/server/plugins/index.txt
+++ b/doc/server/plugins/index.txt
@@ -56,6 +56,7 @@ Literal Configuration (Generators)
:maxdepth: 2
:glob:
+ generators/tgenshi/index
generators/*
Each of these plugins has a corresponding subdirectory with the same name in the Bcfg2 repository.
diff --git a/doc/unsorted/index.txt b/doc/unsorted/index.txt
index f01aee67e..e9f7794ef 100644
--- a/doc/unsorted/index.txt
+++ b/doc/unsorted/index.txt
@@ -19,15 +19,6 @@ list below.
* `Plugins/Actions`
* `Plugins/Ohai`
* `Plugins/Snapshots`
-* `Plugins/TGenshi/examples/bcfg2_cron`
-* `Plugins/TGenshi/examples/clients.xml`
-* `Plugins/TGenshi/examples/ganglia`
-* `Plugins/TGenshi/examples/grub.conf`
-* `Plugins/TGenshi/examples/hosts`
-* `Plugins/TGenshi/examples/iptables`
-* `Plugins/TGenshi/examples/motd`
-* `Plugins/TGenshi/examples/my.cnf`
-* `Plugins/TGenshi/examples/test`
* `PrecompiledPackages`
* `Prereqs`
* `Publications`