diff options
-rw-r--r-- | doc/server/plugins/generators/tgenshi/bcfg2-cron.txt | 25 | ||||
-rw-r--r-- | doc/server/plugins/generators/tgenshi/clientsxml.txt | 94 | ||||
-rw-r--r-- | doc/server/plugins/generators/tgenshi/ganglia.txt | 174 | ||||
-rw-r--r-- | doc/server/plugins/generators/tgenshi/grubconf.txt | 35 | ||||
-rw-r--r-- | doc/server/plugins/generators/tgenshi/hosts.txt | 21 | ||||
-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.txt | 301 | ||||
-rw-r--r-- | doc/server/plugins/generators/tgenshi/motd.txt | 169 | ||||
-rw-r--r-- | doc/server/plugins/generators/tgenshi/mycnf.txt | 34 | ||||
-rw-r--r-- | doc/server/plugins/generators/tgenshi/test.txt | 157 | ||||
-rw-r--r-- | doc/server/plugins/index.txt | 1 | ||||
-rw-r--r-- | doc/unsorted/index.txt | 9 |
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` |