<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>techslaves.org &#187; script</title>
	<atom:link href="http://techslaves.org/tag/script/feed/" rel="self" type="application/rss+xml" />
	<link>http://techslaves.org</link>
	<description>Owned (and fascinated) by technology!</description>
	<lastBuildDate>Thu, 23 Feb 2012 04:55:07 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Cfengine 3 Snippets Part 2: sudo</title>
		<link>http://techslaves.org/2010/10/02/cfengine-3-snippets-part-2-sudo/</link>
		<comments>http://techslaves.org/2010/10/02/cfengine-3-snippets-part-2-sudo/#comments</comments>
		<pubDate>Sat, 02 Oct 2010 02:59:42 +0000</pubDate>
		<dc:creator>rthomson</dc:creator>
				<category><![CDATA[Sysadmin]]></category>
		<category><![CDATA[cfengine]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[policy]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[security]]></category>
		<category><![CDATA[server]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[sudo]]></category>

		<guid isPermaLink="false">http://techslaves.org/?p=87</guid>
		<description><![CDATA[It&#8217;s been a while since I&#8217;ve really had time to delve too much further into cfengine 3 since my previous post on the subject way back in May but I do have another simple example to share. This time it&#8217;s about managing your sudo policy via the sudoers file. The example is that of a very, [...]
Related posts:<ol>
<li><a href='http://techslaves.org/2010/05/18/cfengine-3-snippets-part-1-denyhosts/' rel='bookmark' title='Cfengine 3 Snippets Part 1: DenyHosts'>Cfengine 3 Snippets Part 1: DenyHosts</a></li>
<li><a href='http://techslaves.org/2010/03/29/nanorcs/' rel='bookmark' title='Nanorcs: Ultrasimplistic Configuration File Revision Control'>Nanorcs: Ultrasimplistic Configuration File Revision Control</a></li>
<li><a href='http://techslaves.org/2010/05/07/rhelcentos-nfs-and-firewalls/' rel='bookmark' title='RHEL/CentOS, NFS and Firewalls'>RHEL/CentOS, NFS and Firewalls</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s been a while since I&#8217;ve really had time to delve too much further into cfengine 3 since my <a href="http://techslaves.org/2010/05/18/cfengine-3-snippets-part-1-denyhosts/">previous post</a> on the subject way back in May but I do have another simple example to share. This time it&#8217;s about managing your sudo policy via the <em>sudoers</em> file.</p>
<p>The example is that of a very, very basic <em>sudoers</em> policy but the principles are easily extended to create much more complex policy. The general idea here is that we want cfengine to ensure that specific rules are always in place. Instructed properly, cfengine accomplishes this very well.</p>
<p>Warning: I don&#8217;t know anything. I&#8217;m just someone learning cfengine 3 and posting about it. If I&#8217;m wrong about something, let me know! If you find this at all useful, be my guest. That is all.</p>
<p><span id="more-87"></span></p>
<pre>################################################################################
##
## FILE: sudo.cf
## DESC: Control /etc/sudoers file on various servers
##
################################################################################

bundle agent sudo
{

vars:

  "sudoers" string =&gt; "/etc/sudoers";

  "sudo"     slist =&gt; {
                      "%admin ALL = ALL",
                      "%sysadmin ALL = /sbin/mount",
                      "%devel ALL = /sbin/mount"
                      };

packages:

  Night::

  "sudo" -&gt; "Security policy"
    comment               =&gt; "Ensure sudo is up to date every 24 hours (and only at night)",
    package_policy        =&gt; "update",
    package_method        =&gt; yum,
    package_architectures =&gt; { "$(sys.arch)" },
    action                =&gt; if_elapsed("1440");

files:

  "$(sudoers)" -&gt; "Security Policy"
    comment      =&gt; "Append common configuration to sudoers",
    edit_line    =&gt; append_if_no_lines("$(sudo)");

}</pre>
<p>As with last snippet I posted, the above does not even resemble a complete cfengine policy/configuration, just a small portion that can be contained in it&#8217;s own bundle. It can be put in a separate .cf file, imported by promises.cf and added to the bundle sequence, inheriting variables and classes! Also, just like last time I&#8217;m using cfengine&#8217;s built in interface for package management systems to ensure &#8220;sudo&#8221; is always installed via yum at night, every 24 hours.</p>
<p>What&#8217;s new here is file editing with <em>edit_line</em> and the use of iteration which proves to be very powerful in cfengine 3.</p>
<h2>Editing Files</h2>
<p>Editing files with cfengine is supposed to be easy but initially it seemed a bit awkward to me.</p>
<p>First you have the promise file promise:</p>
<pre>files:

  "$(sudoers)" -&gt; "Security Policy"
    comment      =&gt; "Append common configuration to sudoers",
    edit_line    =&gt; append_if_no_lines("$(sudo)");</pre>
<p>Which makes some reference to the <em>edit_line</em> facility and what looks like a function name with <em>append_if_no_lines(&#8230;)</em>.</p>
<p>Then you have the <em>edit_line</em> bundle defined elsewhere:</p>
<pre>bundle edit_line append_if_no_lines(list)
{
insert_lines:

 "$(list)";
}</pre>
<p>Which describes what &#8220;append_if_no_lines&#8221; actually does.</p>
<p>Of course I&#8217;m just learning cfengine and new things can often seem strange and scary but I am finally warming up to editing files with cfengine&#8230; I think. What I seemed to have initial trouble with was with the <em>bundles</em> necessary for <em>edit_lines</em>, as described above. The bundle within a bundle concept. The <em>append_if_no_lines</em> and <em>append_if_no_line</em> bundles I&#8217;m using are implemented in the <a href="http://www.cfengine.org/manuals/cfengine_stdlib.cf">cfengine std library</a>, which is highly recommended so that you may avoid re-inventing the wheel a little bit.</p>
<p>For basic promises, to add or remove, comment or uncomments lines and the such there are good <em>edit_lines</em> bundles available in the stdlib. For other more complex or customized file editing, writing your own bundles will be necessary. Either way, understanding what a <em>bundle</em> is and how to create your own is key to fully grasping file editing and getting the most out of it. This seems obvious in retrospect but something I didn&#8217;t pickup instantly.</p>
<p>See the cfengine documentation for more about editing files, check the cfengine documentation. There&#8217;s waaaaay more good information over there and it&#8217;s from the cfengine team, not some random newb.</p>
<h2><strong>Iteration</strong></h2>
<p>Iteration is powerful mechanism within cfengine that harnesses the power of lists to express a large possible number of actions/operations with very little amount of code. When lists are used, single actions can be made to repeat for every item in a list by using the <em>$(varname)</em> syntax to refer to the list&#8230; which as it turns out is the same for scalar values! Funny that!</p>
<p>So cfengine allows us to define X different lines of code to ensure are in a file using only a single <em>file:</em> promise all with the same simple syntax as scalar variables? Brilliant!</p>
<p>A demonstration of iteration can be seen with the <em>$(sudo)</em> slist and the &#8220;Append common configuration to sudoers&#8221; <em>file:</em> promise. With this single promise definition, <em>up to</em> 6 actual promises are made because the <em>$(sudo)</em> variable is an slist. Each element or item in the list is iterated over in sequence and the promise is evaluated and acted upon, if necessary. The reason that <em>up to</em> 6 promises will be evaluated is the <em>ifvarclass</em> property of promise, ensuring the promise will only be kept if we&#8217;re in the context of the class&#8230; and looking at the promise to find out which class, we see another example of iteration using the <em>$(sudo)</em> list and the <em>canonify</em> function that turns a string into a class. Thusly, if the host currently running this policy defines all the classes that are tested by the <em>ifvarclass</em> iteration, 6 promises will be made. If the host defines 3 of the classes, then 3 promises will be made and so on, and so forth.</p>
<p>As a beginner, using lists and iteration effectively and creatively seems fairly important to getting the most out of cfengine 3.</p>
<h2>Editing Files vs. Copying Files</h2>
<p>In my previous snippet, I demonstrated how to promise to copy a file from a secure remote server if the local file does not match the server&#8217;s file in order to manage a configuration with cfengine. This time, I&#8217;m promising to add lines to a configuration file if they do not already exist exactly as provided.</p>
<p>This represents two rather different takes on policy. The first says: &#8220;The configuration must always be exactly like this file, byte per byte!&#8221; the second says &#8220;These lines must exist but I don&#8217;t care about anything else in the file&#8221;. The file copy method is what I would call hard policy and the second is soft policy. In the cfengine community solutions, they recommend managing sudo by copying an <em>/etc/sudoers</em> from a remote server. That way is great (just like my DenyHosts example) but this is just another way if you have a use case for cfengine not owning every byte of your configuration file.</p>
<h2>Conclusion</h2>
<p>Yeah, that&#8217;s about it. Enjoy.</p>
<p>Related posts:<ol>
<li><a href='http://techslaves.org/2010/05/18/cfengine-3-snippets-part-1-denyhosts/' rel='bookmark' title='Cfengine 3 Snippets Part 1: DenyHosts'>Cfengine 3 Snippets Part 1: DenyHosts</a></li>
<li><a href='http://techslaves.org/2010/03/29/nanorcs/' rel='bookmark' title='Nanorcs: Ultrasimplistic Configuration File Revision Control'>Nanorcs: Ultrasimplistic Configuration File Revision Control</a></li>
<li><a href='http://techslaves.org/2010/05/07/rhelcentos-nfs-and-firewalls/' rel='bookmark' title='RHEL/CentOS, NFS and Firewalls'>RHEL/CentOS, NFS and Firewalls</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://techslaves.org/2010/10/02/cfengine-3-snippets-part-2-sudo/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Nanorcs: Ultrasimplistic Configuration File Revision Control</title>
		<link>http://techslaves.org/2010/03/29/nanorcs/</link>
		<comments>http://techslaves.org/2010/03/29/nanorcs/#comments</comments>
		<pubDate>Mon, 29 Mar 2010 23:52:44 +0000</pubDate>
		<dc:creator>rthomson</dc:creator>
				<category><![CDATA[Sysadmin]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[script]]></category>

		<guid isPermaLink="false">http://techslaves.org/?p=28</guid>
		<description><![CDATA[I present to you nanorcs, my ultrasimplistic configuration file revision control method. It&#8217;s nothing significant but at least it&#8217;s something to post about. What is nanorcs? It&#8217;s a very simple bash script wrapper around the nano, the cute GNU version of pico and RCS, a basic but functional revision control software package. The script is [...]
Related posts:<ol>
<li><a href='http://techslaves.org/2010/08/05/time-navigator-ha-cluster-agent-configuration/' rel='bookmark' title='Time Navigator HA Cluster Agent Configuration'>Time Navigator HA Cluster Agent Configuration</a></li>
<li><a href='http://techslaves.org/2010/03/30/l2c-pl/' rel='bookmark' title='l2c.pl &#8211; Lines to Columns'>l2c.pl &#8211; Lines to Columns</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>I present to you nanorcs, my ultrasimplistic configuration file revision control method. It&#8217;s nothing significant but at least it&#8217;s something to post about.</p>
<p>What is nanorcs? It&#8217;s a very simple bash script wrapper around the nano, the cute GNU version of pico and RCS, a basic but functional revision control software package. The script is used in place of a call to &#8216;nano&#8217; when editing a file and it automates the tasks related to change management of configuration files including tasks such as check in/out, and prompting the user when a discrepancy between the current file version and the RCS version exist.</p>
<h3><span id="more-28"></span>Basic Prerequisites</h3>
<p>While few prerequisites exist for nanorcs, most of them should be quite simple to satisfy on any Linux system:</p>
<div id="_mcePaste">
<ul>
<li>nano is installed</li>
<li>RCS is installed</li>
</ul>
</div>
<p>Nanorcs also makes some assumptions regarding the path to certain executables: it assumes the required executables are in your path!. I know I could have made it &#8220;cleaner&#8221; by providing a variable in which to set the paths, but this script was 99% written for me, on my systems&#8230; where the RCS and nano commands are in my path&#8230; and besides, if you&#8217;re reading this you can probably figure out how to edit it to suit you anyways! This is just an example of how this might be done, not necessarily a working solution for your systems.</p>
<h3>Functionality</h3>
<div id="_mcePaste">Nanorcs does a few &#8220;nice&#8221; things.</div>
<div id="_mcePaste">
<ul>
<li>The script checks to see if the file you are editing already exists in RCS and if not, does the initial check in before any changes are made.</li>
<li>The script will notify you if the local copy of the file you are editing is different from the latest revision in RCS. It then provides a mechanism to check in the local version to RCS so you do not clobber any changes made that may have not been commited to RCS. If you do not wish to commit the current changes, the script asks if you instead want to pull down the latest version from RCS and work with that one. Summed up, if the local version is different from RCS you have the option to clobber the local version or commit the local version to RCS.</li>
<li>After you are done editing the file with nano, you are asked if you wish to commit the changes. If you answer yes, the changes are commited and the script exits. If you do not wish to commit the edits to RCS, you are asked if you want to pull down the latest version from RCS again or if you want to leave the changes. Leaving the changes without committing them is bad form but there could be a good reason to do so (you realize after exiting the editor that you didn&#8217;t make all the changes you wanted or the changes were only slightly incorrect and it would be easier to update the current version than to pull down the last version from RCS and start over).</li>
</ul>
</div>
<h3>Using nanorcs</h3>
<p>Using nanorcs is easy, but you always have to remember the key point that it must be invoked against a file that is in your current working directory! The basic calling convention is (assing the script is in your path!):</p>
<pre>root@box:/etc/ssh
# nanorcs sshd_config</pre>
<h3>The Script</h3>
<p>And finally, the script itself:</p>
<pre>#!/bin/bash
#
# Name: 	nanorcs
# Desc: 	RCS wrapper around nano for editing config files
#

# Check if file exists in RCS
#
if [ ! -e $1,v ]; then
  echo "First time editing, checking file into RCS..."
  ci -l $1,v $1
else
  # Check if RCS version is different from local version
  rcsdiff $1,v $1 &amp;&gt; /dev/null
  if [ "$?" -eq 1 ]; then
    echo -n "File $1 is not the same as RCS version, clobber it (y/n)? "
    read clobber
    if [ "$clobber" = "y" ]; then
      co -l $1,v $1
    else
      echo -n "Commit current version to RCS (y/n)? "
      read commitfirst
      if [ "$commitfirst" = "y" ]; then
        rcs -l $1,v
        ci -l $1,v $1
      else
        echo "Nothing left to do, exiting..."
        exit
      fi
    fi
  else
    co -l $1,v $1
  fi
fi

nano $1

echo -n "Commit changes to RCS (y/n)? "
read commitfinal
if [ "$commitfinal" = "y" ]; then
  echo "Committing changes..."
  ci -u $1,v $1
else
  rcsdiff $1,v $1 &amp;&gt; /dev/null
  if [ "$?" ]; then
    echo -n "Do you want to revert to RCS version of $1 (y/n)? "
    read revert
    if [ "$revert" = "y" ]; then
      echo "Reverting to RCS version..."
      co -u $1,v $1
    else
      echo "Changes made have NOT been committed!"
    fi
  else
    echo "File unchanged from RCS version, BYE!"
  fi
fi

#
# END
#</pre>
<p>That is all. Nanorcs is my ultra-simplistic solution to the minor hassle of managing configuration file revision. For more advanced users and admins, things like cfengine and pikt are certainly light years ahead of this in every way imaginable, but for those of you who don&#8217;t necessarily need or want a configuration engine, this type of solution seems to be suitable enough.</p>
<p>Related posts:<ol>
<li><a href='http://techslaves.org/2010/08/05/time-navigator-ha-cluster-agent-configuration/' rel='bookmark' title='Time Navigator HA Cluster Agent Configuration'>Time Navigator HA Cluster Agent Configuration</a></li>
<li><a href='http://techslaves.org/2010/03/30/l2c-pl/' rel='bookmark' title='l2c.pl &#8211; Lines to Columns'>l2c.pl &#8211; Lines to Columns</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://techslaves.org/2010/03/29/nanorcs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

