<?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>phaq</title>
	<atom:link href="http://phaq.phunsites.net/feed/" rel="self" type="application/rss+xml" />
	<link>http://phaq.phunsites.net</link>
	<description>my daily IT madness</description>
	<lastBuildDate>Mon, 30 Jan 2012 10:07:54 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.3</generator>
		<item>
		<title>Install Icinga with MySQL and IDOUtils on FreeBSD</title>
		<link>http://phaq.phunsites.net/2012/01/28/install-icinga-with-mysql-and-idoutils-on-freebsd/</link>
		<comments>http://phaq.phunsites.net/2012/01/28/install-icinga-with-mysql-and-idoutils-on-freebsd/#comments</comments>
		<pubDate>Sat, 28 Jan 2012 17:24:23 +0000</pubDate>
		<dc:creator>gdelmatto</dc:creator>
				<category><![CDATA[FreeBSD]]></category>
		<category><![CDATA[Networking]]></category>
		<category><![CDATA[Operating Systems]]></category>
		<category><![CDATA[Utilities]]></category>

		<guid isPermaLink="false">http://phaq.phunsites.net/?p=920</guid>
		<description><![CDATA[It&#8217;s not hard to install Icinga on FreeBSD, at least if you&#8217;re satisfied with default options. Should you however require Icinga with IDOUtils and MySQL support, then you need to take additional steps. Note: This howto requires a patch to your FreeBSD ports tree. The patch has been submitted to the FreeBSD port maintainers. I [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s not hard to install <a href="http://www.icinga.org" target="_blank">Icinga</a> on FreeBSD, at least if you&#8217;re satisfied with default options.<br />
Should you however require Icinga with IDOUtils and MySQL support, then you need to take additional steps.</p>
<p><span id="more-920"></span></p>
<p><b>Note: This howto requires a <a href="http://phaq.phunsites.net/files/2012/01/patch_icinga_1.5.1_idoutils_fbs_port.txt">patch</a> to your FreeBSD ports tree. The patch has been submitted to the FreeBSD port maintainers. I hope that it will eventually end up in the ports tree.</b></p>
<p>My initial readings about this was on the official Icinga docs covering <a href="http://docs.icinga.org/latest/en/quickstart-idoutils-freebsd.html" target="_blank">installing Icinga on FreeBSD with IDOUtils</a>.<br />
However, as it turned out, the docs our a bit outdated, and yet do not reflect a way of doing the install using ports.</p>
<p>So here&#8217;s just a short primer on what I did do install Icinga from ports, imposing as little additional work four you, my fellow reader, as well <img src='http://phaq.phunsites.net/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p>Now let&#8217;s turn to Icinga, which has a port on it&#8217;s own, which you&#8217;ll find it at <strong>/usr/ports/net-mgtm/icinga</strong>. First change to that directory.</p>
<pre>cd /usr/ports/net-mgtm/icinga</pre>
<p>Now download the <a href="http://phaq.phunsites.net/files/2012/01/patch_icinga_1.5.1_idoutils_fbs_port.txt">patch file</a> I made into your ports directory.<br />
The patch will inject a new rc-script for ido2db and enable your port to build IDOutils.</p>
<pre>[root@localhost /usr/ports/net-mgmt/icinga]# fetch http://phaq.phunsites.net/files/2012/01/patch_icinga_1.5.1_idoutils_fbs_port.txt</pre>
<p>Then apply the patch like this:</p>
<pre>[root@localhost /usr/ports/net-mgmt/icinga]# patch -p0 &lt; patch_icinga_1.5.1_idoutils_fbs_port.txt
Hmm...  Looks like a unified diff to me...
The text leading up to this was:
--------------------------
|--- Makefile.org	2012-01-28 16:36:46.000000000 +0000
|+++ Makefile	2012-01-28 17:51:38.000000000 +0000
--------------------------
Patching file Makefile using Plan A...
Hunk #1 succeeded at 27.
Hunk #2 succeeded at 109.
Hmm...  The next patch looks like a unified diff to me...
The text leading up to this was:
--------------------------
|--- /dev/null	2012-01-28 18:00:51.000000000 +0000
|+++ files/ido2db.in	2012-01-28 18:00:30.000000000 +0000
--------------------------
(Creating file files/ido2db.in...)
Patching file files/ido2db.in using Plan A...
Hunk #1 succeeded at 1.
Hmm...  The next patch looks like a unified diff to me...
The text leading up to this was:
--------------------------
|--- files/pkg-message.in.org	2012-01-28 17:48:37.000000000 +0000
|+++ files/pkg-message.in	2012-01-28 17:49:38.000000000 +0000
--------------------------
Patching file files/pkg-message.in using Plan A...
Hunk #1 succeeded at 4.
done</pre>
<p>Now you&#8217;re ready to configure the port:</p>
<pre>[root@localhost /usr/ports/net-mgmt/icinga]# make config</pre>
<p>Note the now <strong>IDOUtils</strong> option that now has appeared. Check it to enable IDOUtils.</p>
<p><a href="http://phaq.phunsites.net/files/2012/01/idoutils_config_screen.png" rel="lightbox[920]"><img class="aligncenter size-medium wp-image-929" src="http://phaq.phunsites.net/files/2012/01/idoutils_config_screen-300x180.png" alt="" width="300" height="180" /></a></p>
<p>Then compile and install as usual. The port will install also all required dependies, two of them being mysql55-client and libdbi-drivers, both to be found at /usr/ports/databases.</p>
<pre>[root@localhost /usr/ports/net-mgmt/icinga]# make install clean</pre>
<p>Afterwards, you should end up with a few additional files, which would not be installed with the stock FreeBSD port.</p>
<pre>[root@localhost /usr/ports/net-mgmt/icinga]# ls -l /usr/local/bin/ido*
-rwxrwxr--  1 root  wheel  238326 Jan 28 16:53 /usr/local/bin/ido2db
-rwxrwxr--  1 root  wheel   80419 Jan 28 16:53 /usr/local/bin/idomod.o

[root@mgmp-bs01 /usr/ports/net-mgmt/icinga]# ls -l /usr/local/etc/rc.d/ido2db
-r-xr-xr-x  1 root  wheel  738 Jan 28 18:00 /usr/local/etc/rc.d/ido2db</pre>
<p>Now you can enable Icinage and IDO2DB in /etc/rc.conf by adding these lines:</p>
<pre>icinga_enable="YES"
ido2db_enable="YES"</pre>
<p>Of course, you still need to perform the usual Icinga configuration steps, which are not covered in this post.<br />
Please check with the <a href="http://docs.icinga.org/latest/en" target="_blank">official docs</a> for this procedure.</p>
<p>If your configuration is proper, you should notice this in your logs indicating that IDOMOD (IDOUtils) is really working.</p>
<pre>[1327773651] Icinga 1.5.1 starting... (PID=95448)
[1327773651] Local time is Sat Jan 28 18:00:51 UTC 2012
[1327773651] LOG VERSION: 2.0
[1327773651] idomod: IDOMOD 1.5.1 (09-09-2011) Copyright (c) 2005-2008 Ethan Galstad (nagios@nagios.org), Copyright (c) 2009-2011 Icinga Development Team (http://www.icinga.org))
[1327773651] idomod: Successfully connected to data sink.  26 queued items to flush.
[1327773651] idomod: Successfully flushed 26 queued items to data sink.
[1327773651] Event broker module '/usr/local/bin/idomod.o' initialized successfully.
[1327773651] Finished daemonizing... (New PID=95450)</pre>
<p>That&#8217;s it, you conquered the beast!</p>
]]></content:encoded>
			<wfw:commentRss>http://phaq.phunsites.net/2012/01/28/install-icinga-with-mysql-and-idoutils-on-freebsd/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Working around WordPress&#8217; wpdb limitations with MySQL User Variables</title>
		<link>http://phaq.phunsites.net/2012/01/27/working-around-wordpress-wpdb-limitations-with-mysql-user-variables/</link>
		<comments>http://phaq.phunsites.net/2012/01/27/working-around-wordpress-wpdb-limitations-with-mysql-user-variables/#comments</comments>
		<pubDate>Fri, 27 Jan 2012 12:14:04 +0000</pubDate>
		<dc:creator>gdelmatto</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://phaq.phunsites.net/?p=914</guid>
		<description><![CDATA[Think about retrieving a data set from MySQL, where you need to add distinct, auto-incremented ID to each row retrieved. Sounds easy? Well, the ID has to be generated on-the-fly and out of nowhere. Still easy? One might think about using MySQL user variables to accomplish this, sure. But what if your framework does not [...]]]></description>
			<content:encoded><![CDATA[<p>Think about retrieving a data set from MySQL, where you need to add distinct, auto-incremented ID to each row retrieved. Sounds easy?</p>
<p>Well, the ID has to be generated on-the-fly and out of nowhere. Still easy?</p>
<p>One might think about using MySQL user variables to accomplish this, sure. But what if your framework does not allow injecting chained queries because of SQL injection countermeasures?<br />
<span id="more-914"></span><br />
The framework I used, WordPress&#8217; wpdb API to be exact, has such a restriction, which caused my to find an alternate way.</p>
<p>To illustrate the problem, I start with the date retrieved, which would normally look as shown below.</p>
<pre>mysql&gt; SELECT value1, value2 FROM sample_table;
+-----------------+-----------------+
| value1          | value2          |
+-----------------+-----------------+
| sample_value_1  | sample_value_2  |
| sample_value_a  | sample_value_b  |
+-----------------+-----------------+
2 rows in set (0.00 sec)</pre>
<p>Now, I need a line number for each record. When talking abut the line number, I&#8217;m strictly talking about a representation of &#8220;this is the first line&#8221;, &#8220;this is the second line&#8221;, etc.<br />
This particular line number must therefore not be identical to the tupel ID, if that even would exist.<br />
So this is what I would expect:</p>
<pre>
+------------+-----------------+-----------------+
| line_num   | value1          | value2          |
+------------+-----------------+-----------------+
| 1          | sample_value_1  | sample_value_2  |
| 2          | sample_value_a  | sample_value_b  |
+------------+-----------------+-----------------+
</pre>
<p>To generate this by the means of a query, one would usually use a MySQL user variable, that would be dynamically increased for each data row.<br />
In SQL speech the query would then look like this:</p>
<pre>
SELECT @line:=0;
SELECT @line:=@line+1 AS line_num, value1, value2 FROM sample_table;
+------------+-----------------+-----------------+
| line_num   | value1          | value2          |
+------------+-----------------+-----------------+
| 1          | sample_value_1  | sample_value_2  |
| 2          | sample_value_a  | sample_value_b  |
+------------+-----------------+-----------------+
</pre>
<p>It&#8217;s actually easy and conventient, and you get real, dynamically calculated &#8220;line numbers&#8221;. But this technique requires to actually run two statements to be run in a series.<br />
If you&#8217;re using your own database routines, this may not be a problem at all. But if you rely on a given framework, you may trip into SQL injection counter measures which will simply throw away a query constructed like this:</p>
<pre>
$my_query = "SELECT @line:=0; SELECT @line:=@line+1 AS line_num, value1, value2 FROM sample_table;";

$my_result = $pseudo_call_to_my_db_framework-&gt;execute( $my_query );
</pre>
<p>This was ecactly what I was trying to do with WordPress&#8217; wpdb API. However, as I found, SQL injection filters kicked in. This is absolutely not to blame the WordPress folks, of course. The filters in place serve a good purpose and thus forced me in taking a different approach.</p>
<p>After some searching on the net I found that I seemed to be the only one to be using users vars with wpdb :-/<br />
Of course, while this may not be widely used, I insisted in this approach. Suggestions in adding a loop or an extra-query where inappropriate to me, because it had to fit within the existing code base. That again required me to specifically do it in one SQL query, because I simply did not want to bloat the code by adding another loop in there.</p>
<p>So, the question is: Can the procedure described above be performed within ONE single query.</p>
<p>The answer is: Yes, but you&#8217;re required to invole a sub-query to achive this.</p>
<p>At first, leave the initial variable assignment away, so you end up with this query:</p>
<pre>
SELECT @line:=@line+1 AS line_num, value1, value2 FROM sample_table;
</pre>
<p>This would of course not yet work, because the user variable @line wouldn&#8217;t yet be defined at runtime.<br />
Since you can&#8217;t prepend the declaration, you need to embed it using a sub-query. This is needed to have the variable declaration ready at the earliest stage possible, namely while parsing the query, and not during result processing.</p>
<p>Let&#8217;s look at the final query and the comments:</p>
<pre>
SELECT
        @line:=@line+1 AS line_num,                     # increase the @line user variable for each row retrieved
        sample_table.value1,                            # include column 'value1' from table 'sample_table'
        sample_table.value2                             # include column 'value2' from table 'sample_table'
FROM
        (SELECT @line:=0) AS tmp_line,                  # this will fire during parsing: initialize the user var by selecting it into a dummy table
        sample_table;                                   # now add our actual data table as well
</pre>
<p>This way, you end up getting the same result as shown earlier. And yet, this query can be performed with WordPress&#8217; wpdb API and maybe other frameworks as well.</p>
]]></content:encoded>
			<wfw:commentRss>http://phaq.phunsites.net/2012/01/27/working-around-wordpress-wpdb-limitations-with-mysql-user-variables/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Run command in background from PHP</title>
		<link>http://phaq.phunsites.net/2012/01/18/run-command-in-background-from-php/</link>
		<comments>http://phaq.phunsites.net/2012/01/18/run-command-in-background-from-php/#comments</comments>
		<pubDate>Tue, 17 Jan 2012 23:40:21 +0000</pubDate>
		<dc:creator>gdelmatto</dc:creator>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://phaq.phunsites.net/?p=904</guid>
		<description><![CDATA[While working on my newest project, a PHP- and AJAX-based network management application, I came along the need to run multiple commands on the server and track their return states (basically if they were run successful or not). While sticking together my framework, I found that forking a process into background from PHP requires some [...]]]></description>
			<content:encoded><![CDATA[<p>While working on my newest project, a PHP- and AJAX-based network management application, I came along the need to run multiple commands on the server and track their return states (basically if they were run successful or not).</p>
<p>While sticking together my framework, I found that forking a process into background from PHP requires some additional steps if you don&#8217;t want to break AJAX functionality.<br />
<span id="more-904"></span><br />
Here&#8217;s a sketch of the basic concept. It involves a Dispatcher, which creates a workqueue item in a database, and then forks a background process, which will perform various tasks. The latter will then report back the states of the tasks performed to the workqueue item in the database.<br />
On the other end, a Tracker will check the database for the running states and push progress information into the browser.</p>
<p><a href="http://phaq.phunsites.net/files/2012/01/ajax_dispatcher.png" rel="lightbox[904]"><img src="http://phaq.phunsites.net/files/2012/01/ajax_dispatcher-300x300.png" alt="" width="300" height="300" class="aligncenter size-medium wp-image-905" /></a></p>
<p>While it was working to some extent, my initial attempts at forking a background process from PHP failed terribly, because PHP always kept waiting for the command to complete.<br />
This behaviour had the side effect that the Dispatcher couldn&#8217;t immediately return the workqueue id to the AJAX client (the browser). But since the workqueue id was required by the AJAX-client to subsequently fire the Tracker, the initial request to the Dispatcher had to be synchronous instead of asynchronous.<br />
The blocking behaviour did however screw everything, so I had to find a way around.</p>
<p>Of course, I was thinking about the various methods in calling external commands from PHP, starting with simple backticks, exec(), passthru() and even popen(), despite some others as well.</p>
<p>People familiar to Unix/Linux environments would of course say, that a background task can be started easily by appending an ampersand to the end, making it look like this:</p>
<p><code><br />
exec( '/path/to/my/command &amp;' );<br />
system( '/path/to/my/command &amp;' );<br />
</code></p>
<p>But that does not work in PHP, because all calls are always waiting for the command to return.<br />
PHP effectively binds the STDERR and STDOUT I/O streams during execution, which is why a simple ampersand doesn&#8217;t work out.<br />
To get this to work, one must really detach the to-be-backgrounded program from the controlling terminal to trick PHP into returning from exec.</p>
<p>This can be done easily by redirecting STDOUT and STDERR to a logfile or /dev/null before background the program, and just return the pid.<br />
That would then look similar to this:</p>
<p><code><br />
exec( '/path/to/some/program &gt; /dev/null 2&gt;&amp;1 &amp; echo $!' );<br />
</code></p>
<p>The above example would detach the programm into background while returning control to your PHP application at once.</p>
<p>Consider the output destination being required in any case, otherwise the I/O streams won&#8217;t get detached.<br />
So this syntax, while being perfectly valid, will definitely run your command, but won&#8217;t place it into background at all:</p>
<p><code><br />
exec( '/path/to/some/program 2&gt;&amp;1 &amp; echo $!' );<br />
</code></p>
<p>That&#8217;s it <img src='http://phaq.phunsites.net/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://phaq.phunsites.net/2012/01/18/run-command-in-background-from-php/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>TimeMachine mobile backup eats up disk space if backup drive unavailable</title>
		<link>http://phaq.phunsites.net/2012/01/14/timemachine-mobile-backup-eats-up-disk-space-if-backup-drive-unavailable/</link>
		<comments>http://phaq.phunsites.net/2012/01/14/timemachine-mobile-backup-eats-up-disk-space-if-backup-drive-unavailable/#comments</comments>
		<pubDate>Sat, 14 Jan 2012 10:34:06 +0000</pubDate>
		<dc:creator>gdelmatto</dc:creator>
				<category><![CDATA[OS X]]></category>
		<category><![CDATA[Operating Systems]]></category>

		<guid isPermaLink="false">http://phaq.phunsites.net/?p=893</guid>
		<description><![CDATA[Apple introduced a new feature called &#8220;mobile backups&#8221; with OS X Lion. The idea behind that: Use a temporary part of the local hard drive to store backups until the backup drive is connected again. True, this is a good feature for most. But if you can spare some backups, because you &#8211; let&#8217;s say [...]]]></description>
			<content:encoded><![CDATA[<p>Apple introduced a new feature called &#8220;mobile backups&#8221; with OS X Lion.<br />
The idea behind that: Use a temporary part of the local hard drive to store backups until the backup drive is connected again.</p>
<p>True, this is a good feature for most. But if you can spare some backups, because you &#8211; let&#8217;s say &#8211; store your files to a dropbox folder, which is synchronized to a cloud service, then you may not need the mobile backup feature of OS X.<br />
In fact, you may notice running out of disk space, that you could use otherwise.<br />
<span id="more-893"></span><br />
So to see the difference, let&#8217;s check out the available free disk space in Termin us the &#8216;df&#8217; (disk free) utility:</p>
<pre>
gianpaolo-del-mattos-macbook-pro:~ Gianpaolo$ df -h
Filesystem                          Size   Used  Avail Capacity  Mounted on
/dev/disk0s2                        79Gi   69Gi  9.1Gi    89%    /
devfs                              129Ki  129Ki    0Bi   100%    /dev
map -hosts                           0Bi    0Bi    0Bi   100%    /net
map auto_home                        0Bi    0Bi    0Bi   100%    /home
localhost:/SkA_FxsNwtVofJZZOc308I   79Gi   79Gi    0Bi   100%    /Volumes/MobileBackups
</pre>
<p>Gosh, I&#8217;m almost out of space, having only 9 Gigs left :-/</p>
<p>So let&#8217;s get rid of the mobile backups using this command:</p>
<p><code><br />
sudo tmutil disablelocal<br />
</code></p>
<p>Now check back at the disk space:</p>
<pre>
gianpaolo-del-mattos-macbook-pro:~ Gianpaolo$ df -h
Filesystem      Size   Used  Avail Capacity  Mounted on
/dev/disk0s2    79Gi   60Gi   18Gi    77%    /
devfs          129Ki  129Ki    0Bi   100%    /dev
map -hosts       0Bi    0Bi    0Bi   100%    /net
map auto_home    0Bi    0Bi    0Bi   100%    /home
</pre>
<p>You notice, that the &#8216;/Volumes/MobileBackups&#8217; mount point is gone?<br />
I&#8217;m having 18 Gigs free now as well.</p>
<p>So, depending on how long you didn&#8217;t have your backup drive connected, the amount used may well increase to a multiple of that.</p>
<p>It may not be best choice for most people to have mobile backups disabled. But if you DO know what you&#8217;re doing, then go for it <img src='http://phaq.phunsites.net/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://phaq.phunsites.net/2012/01/14/timemachine-mobile-backup-eats-up-disk-space-if-backup-drive-unavailable/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Convert a Perl Hash of Hashes into XML with XML::Dumper</title>
		<link>http://phaq.phunsites.net/2012/01/09/convert-a-perl-hash-of-hashes-into-xml-with-xmldumper/</link>
		<comments>http://phaq.phunsites.net/2012/01/09/convert-a-perl-hash-of-hashes-into-xml-with-xmldumper/#comments</comments>
		<pubDate>Mon, 09 Jan 2012 15:01:46 +0000</pubDate>
		<dc:creator>gdelmatto</dc:creator>
				<category><![CDATA[Perl]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://phaq.phunsites.net/?p=890</guid>
		<description><![CDATA[For a project of mine, I wanted to convert a Perl data structure, a so called Hash of Hashes, into an XML. The simple solution to this is to use the XML::Dumper module. Let&#8217;s suppose your data structure looks like this: %hash_of_hashes = { item1 =&#62; { item1_1 =&#62; 'value1_1', item1_2 =&#62; 'value1_2', }, item2 [...]]]></description>
			<content:encoded><![CDATA[<p>For a project of mine, I wanted to convert a Perl data structure, a so called Hash of Hashes, into an XML.</p>
<p>The simple solution to this is to use the <a href="http://search.cpan.org/~mikewong/XML-Dumper-0.81/Dumper.pm" target="_blank">XML::Dumper</a> module.<br />
<span id="more-890"></span><br />
Let&#8217;s suppose your data structure looks like this:</p>
<pre>%hash_of_hashes = {
    item1 =&gt; {
                item1_1       =&gt; 'value1_1',
                item1_2       =&gt; 'value1_2',
    },
    item2 =&gt; {
                item2_1       =&gt; 'value2_1',
                item2_2       =&gt; 'value2_2',
    },
  };</pre>
<p>You can easily convert this into an XML representation using this command:</p>
<p><code><br />
my $xml_output  = XML::Dumper::pl2xml( \%hash_of_hashes );<br />
</code></p>
<p>So you&#8217;ll end up with this output:</p>
<pre>&lt;perldata&gt;
 &lt;hashref memory_address="0x878e784"&gt;
 &lt;item key="item1"&gt;
 &lt;hashref memory_address="0x87a8c58"&gt;
 &lt;item key="item1_1"&gt;value1_1&lt;/item&gt;
 &lt;item key="item1_2"&gt;value1_2&lt;/item&gt;
 &lt;/hashref&gt;
 &lt;/item&gt;
 &lt;item key="item2"&gt;
 &lt;hashref memory_address="0x87a8c61"&gt;
 &lt;item key="item2_1"&gt;value2_1&lt;/item&gt;
 &lt;item key="item2_2"&gt;value2_2&lt;/item&gt;
 &lt;/hashref&gt;
 &lt;/item&gt;
 &lt;/hashref&gt;
&lt;/perldata&gt;</pre>
<p>But be aware: You need to pass the hash by reference, imposing the <strong>\%hash_of_hashes</strong> notation, otherwise you end up with something like this:</p>
<pre>&lt;perldata&gt;
 &lt;scalar&gt;item_1&lt;/scalar&gt;
 &lt;scalar&gt;item_2&lt;/scalar&gt;
&lt;/perldata&gt;</pre>
<p>It&#8217;s so obvious, but I had overlooked that as well in the first attempts <img src='http://phaq.phunsites.net/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://phaq.phunsites.net/2012/01/09/convert-a-perl-hash-of-hashes-into-xml-with-xmldumper/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Win32 GuiDbEdit for Check Point Firewall</title>
		<link>http://phaq.phunsites.net/2012/01/04/win32-guidbedit-for-check-point-firewal/</link>
		<comments>http://phaq.phunsites.net/2012/01/04/win32-guidbedit-for-check-point-firewal/#comments</comments>
		<pubDate>Wed, 04 Jan 2012 13:36:07 +0000</pubDate>
		<dc:creator>gdelmatto</dc:creator>
				<category><![CDATA[Memos]]></category>

		<guid isPermaLink="false">http://phaq.phunsites.net/?p=886</guid>
		<description><![CDATA[As seen in Check Point SupportCenter, there&#8217;s also a (win32) GUI Version of the DBEdit CLI tool, located at C:\Program Files\CheckPoint\SmartConsole\PROGRAM\GuiDbEdit.exe. Great visual debugging aid if you&#8217;re doing automation stuff with CLI dbedit.]]></description>
			<content:encoded><![CDATA[<p>As seen in <a href="https://supportcenter.checkpoint.com/supportcenter/portal?eventSubmit_doGoviewsolutiondetails=&amp;solutionid=sk13009" target="_blank">Check Point SupportCenter</a>, there&#8217;s also a (win32) GUI Version of the DBEdit CLI tool, located at <strong>C:\Program Files\CheckPoint\SmartConsole\PROGRAM\GuiDbEdit.exe</strong>.</p>
<p>Great visual debugging aid if you&#8217;re doing automation stuff with CLI dbedit.</p>
]]></content:encoded>
			<wfw:commentRss>http://phaq.phunsites.net/2012/01/04/win32-guidbedit-for-check-point-firewal/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Configuring GUI Clients for CheckPoint Firewall on the CLI</title>
		<link>http://phaq.phunsites.net/2012/01/04/configuring-gui-clients-for-checkpoint-firewall-on-the-cli/</link>
		<comments>http://phaq.phunsites.net/2012/01/04/configuring-gui-clients-for-checkpoint-firewall-on-the-cli/#comments</comments>
		<pubDate>Wed, 04 Jan 2012 13:27:29 +0000</pubDate>
		<dc:creator>gdelmatto</dc:creator>
				<category><![CDATA[Memos]]></category>

		<guid isPermaLink="false">http://phaq.phunsites.net/?p=883</guid>
		<description><![CDATA[As seen over there at CheckPoint SupportCenter Use &#8216;cpconfig&#8217; on the CLI (may need &#8216;expert&#8217; mode)]]></description>
			<content:encoded><![CDATA[<p>As seen over there at <a href="https://supportcenter.checkpoint.com/supportcenter/portal?eventSubmit_doGoviewsolutiondetails=&amp;solutionid=sk12120" target="_blank">CheckPoint SupportCenter</a></p>
<p>Use &#8216;cpconfig&#8217; on the CLI (may need &#8216;expert&#8217; mode)</p>
]]></content:encoded>
			<wfw:commentRss>http://phaq.phunsites.net/2012/01/04/configuring-gui-clients-for-checkpoint-firewall-on-the-cli/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>VpnInit AppleScript: Override and Restore Default VPN-Routes on OS X</title>
		<link>http://phaq.phunsites.net/2011/12/29/vpninit-applescript-override-and-restore-default-vpn-routes-on-os-x/</link>
		<comments>http://phaq.phunsites.net/2011/12/29/vpninit-applescript-override-and-restore-default-vpn-routes-on-os-x/#comments</comments>
		<pubDate>Thu, 29 Dec 2011 17:37:04 +0000</pubDate>
		<dc:creator>gdelmatto</dc:creator>
				<category><![CDATA[Networking]]></category>
		<category><![CDATA[OS X]]></category>
		<category><![CDATA[Operating Systems]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Scripting]]></category>
		<category><![CDATA[Utilities]]></category>

		<guid isPermaLink="false">http://phaq.phunsites.net/?p=876</guid>
		<description><![CDATA[Years ago I wrote a small script to restore local default route after connecting the RAS VPN on Windows. Now, I made up a similar script to do the same on OS X. The basic idea, now and then, was that I would not want to send all traffic through the VPN. Thus the script [...]]]></description>
			<content:encoded><![CDATA[<p>Years ago I wrote a small script <a href="/2007/06/06/ras_initvbs-override-and-restore-routes-with-windows-ras/">to restore local default route after connecting the RAS VPN on Windows</a>.</p>
<p>Now, I made up a similar script to do the same on OS X.<br />
<span id="more-876"></span><br />
The basic idea, now and then, was that I would not want to send all traffic through the VPN.<br />
Thus the script will assist in restoring your local default route after the VPN connection is established.<br />
Furthermore, it&#8217;ll add some specific routes directed to the VPN.</p>
<p>This way, all your usual traffic (internet, surfing, skype, whatever) is sent through your default gateway, while more specific routes (your business stuff) is sent through the VPN.</p>
<p>Below&#8217;s the code for the initial release. It may lack some details yet, like auto-detecting the tunnel device name, but it does the job already.</p>
<p>Just copy the code into Apple Script Editor and save it to a convenient location. Make sure you save it as &#8220;Application&#8221; and not as &#8220;Script&#8221; (which is the default). You you don&#8217;t, double-clicking the script will open the Script Editor instead of executing the script. Surely, not what you want.</p>
<p>Pay attention to the variables on the top, which need to be edited before you save the Script: _vpn_name, _default_gw, _networks, and _sudo_password (optional).<br />
I hope directions are clear enough from the comments sections.</p>
<pre>
# VpnInit
# ---
# an AppleScript utility to connect your vpn,
# restore local default route and add selected
# routes directed to the VPN only
# thus you'll end up sending only selected
# traffic through the VPN, while the rest
# goes through your local default gateway
# as usual
# ---
# released "as is" under the terms of GPL v2.
# Copyright © 2011 Gianpaolo Del Matto
# 
# r0.1 initial release 2011/12/29
#
# ToDo:
# - hardcoding the "sudo" password is a bad idea, maybe
#	need a better way to get away with it
# - vpn tunnel (utun0) is still hardcoded,
#	should be auto-detected
#

# the name of your vpn connection
#
set _vpn_name to "My VPN"

# your local default gateway
#
set _default_gw to "192.168.1.1"

# your remote networks to pass via VPN, separate multiple with comma
# like so: {"1.2.3.4/30", "5.6.7.8/30"}
#
set _networks to {"192.168.2.1/24"}

# your super-user (root) password
# actually needed to bypass the prompts
# leave empty to get prompted
#
set _sudo_password to ""

# ##################################################################
# DO NOT CHANGE ANYTHING BELOW
# ##################################################################

# kindly borrowed from
# http://www.macosxautomation.com/applescript/uiscripting/index.html
# make sure that support for assistive devices is enabled
#
tell application "System Events"
	if UI elements enabled is false then
		tell application "System Preferences"
			activate
			set current pane to pane id "com.apple.preference.universalaccess"
			display dialog "This script requires access for assistive devices be enabled." &amp; return &amp; return &amp; "To continue, click the OK button and enter an administrative password in the forthcoming security dialog." with icon 1
		end tell
		set UI elements enabled to true
		if UI elements enabled is false then
			display dialog "This script cannot run while access for assistive devices is disabled." &amp; return &amp; "Exiting now." buttons {"OK"} with icon 2
			return "user cancelled"
		end if
	end if
end tell

# now dive into the VPN setup part
#
tell application "System Events"
	set _if_tunnel to "utun0" #	do not change, will be auto-detected, just giving a reasonable default
	tell current location of network preferences
		if exists service _vpn_name then
			# try to connect the VPN service if it's disconnected
			#
			if current configuration of service _vpn_name is not connected then
				connect service _vpn_name
			end if

			# give it some time to settle
			#
			set _retval to false
			repeat until (_retval) is true
				set counter to 0
				repeat while counter is less than 16
					# exit if we get connected
					#
					if current configuration of service _vpn_name is connected then
						set _retval to true
						exit repeat
					end if

					# opt for exit if still not connected after 15 seconds
					#
					if counter is equal to 15 then
						display dialog "VPN '" &amp; _vpn_name &amp; "' is still not connected after 15 seconds. Do you want to keep waiting?" with title "VPN still not connected" buttons {"Yes", "No"}
						if button returned of result is "No" then
							# bail out if user decided not to wait any longer
							#
							set _retval to true
							return
						else
							# otherwise reset the counter so we can trigger again
							#
							set counter to 0
						end if
					end if

					set counter to counter + 1
					delay 1
				end repeat
			end repeat

			# now go to post processing and to the following:
			# - delete default route via vpn
			# - restore original default route
			# - add specific routes to vpn
			#
			if current configuration of service _vpn_name is connected then
				# restore local default route
				#
				do shell script "route delete default" password _sudo_password with administrator privileges
				do shell script "route add default " &amp; _default_gw password _sudo_password with administrator privileges

				# inject custom routes via VPN
				#
				repeat with _network in _networks
					do shell script "route add -interface " &amp; _network &amp; " utun0" password _sudo_password with administrator privileges
				end repeat
			end if
		else
			# bail out if the VPN service does not exist
			#
			display dialog "Given VPN '" &amp; _vpn_name &amp; "' does not exist. Please check the name"
		end if
	end tell
end tell
</pre>
]]></content:encoded>
			<wfw:commentRss>http://phaq.phunsites.net/2011/12/29/vpninit-applescript-override-and-restore-default-vpn-routes-on-os-x/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Automating MakeMKV with AppleScript</title>
		<link>http://phaq.phunsites.net/2011/12/15/automating-makemkv-with-applescript/</link>
		<comments>http://phaq.phunsites.net/2011/12/15/automating-makemkv-with-applescript/#comments</comments>
		<pubDate>Thu, 15 Dec 2011 21:56:14 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[OS X]]></category>
		<category><![CDATA[Operating Systems]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Scripting]]></category>

		<guid isPermaLink="false">http://phaq.phunsites.net/?p=858</guid>
		<description><![CDATA[It&#8217;s only days since I wrote about a custom script action upon inserting a DVD in OS X, allowing me have either run the DVD Player or MakeMKV to rip the DVDs. Now I was digging around if I could do some automation on the GUI part, which indeed turned out to work &#8230; at [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s only days since I wrote about <a href="/make-os-x-run-custom-actions-upon-dvd-insert">a custom script action upon inserting a DVD</a> in OS X, allowing me have either run the DVD Player or MakeMKV to rip the DVDs.</p>
<p>Now I was digging around if I could do some automation on the GUI part, which indeed turned out to work &#8230; at least to a certain degree.<br />
<span id="more-858"></span><br />
Let&#8217;s face it: Ripping DVDs with MakeMKV is simple and easy, however its scripting abilities s*** <img src='http://phaq.phunsites.net/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p>There is actually some limited CLI support available. If you dive into the application package, you&#8217;ll find the <b>/Applications/MakeMKV.app/Contents/MacOS/makemkvcon</b> program, which can be scripted somehow.</p>
<p>In the first place, I was perfectly able to rip off a complete DVD using the CLI command. But that was not what I had in mind, because I wanted to select only the main movies, and there only a limited set of audio streams and subtitles.<br />
As I seemed to be unable to figure out, how that would be possible (some rare comments on the <a href="http://www.makemkv.com/forum2/" target="_blank">MakeMKV forums</a> mentioned, that it would NOT be possible), I ended up using the GUI.</p>
<p>Well, after I wrote the auto-selector script, I started thinking on how to make this a bit more practical.<br />
I know Apple released support for GUI (graphical user interface) scripting already years ago, but I had never really looked into until today <img src='http://phaq.phunsites.net/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p>After some reading over there at <a href="http://www.macosxautomation.com/applescript/uiscripting/index.html" target="_blank">macosxautomation.com</a> I started on extending my script.<br />
Please consider that you need to enable support for assistive devices, as mentioned on macosxautomation.com &#8212; otherwise the script will simply fail.</p>
<p>With help of <a href="http://pfiddlesoft.com/uibrowser" target="_blank">UI Browser</a>, a utility to explore GUI elements of any application, I was able to identify the relevant items.</p>
<p>So with the latest additions, the script does the following:</p>
<ul>
<li>Runs whenever a DVD is inserted</li>
<li>Automatically run DVD Player if no action is taken &#8211; or -</li>
<li>run MakeMKV if requested to do so</li>
<li>Wait for the DVD TOC (table of contents) to be read initially</li>
<li>As soon as the TOC is read, open the DVD in MakeMKV</li>
<li>Wait until the tracks selected were ripped and try to eject the DVD afterwards</li>
</ul>
<p>And here&#8217;s the code:</p>
<pre>
# dvd-action
# ---
# an AppleScript utility to select DVD Player or MakeMKV
# upon inserting a DVD
# ---
# released "as is" under the terms of GPL v2.
# Copyright © 2011 Gianpaolo Del Matto <www.phunsites.net>
# 
# r0.1 initial release 2011/12/09
# - simple selector with default action after timeout
#
# r0.2 2011/12/15
# - added limited GUI scripting functionality for MakeMKV
#
# r0.3 2011/12/16
# - added support to check for assistive device access
#	(code borrowed from http://www.macosxautomation.com)
# - added simple progress indicator while waiting for drive
#	do become available for access
#

# initialization
#
# true : show progress dialogs, false: hide progress dialogs
set verbose to true

# kindly borrowed from
# http://www.macosxautomation.com/applescript/uiscripting/index.html
# make sure that support for assistive devices is enabled
#
tell application "System Events"
	if UI elements enabled is false then
		tell application "System Preferences"
			activate
			set current pane to pane id "com.apple.preference.universalaccess"
			display dialog "This script requires access for assistive devices be enabled." &#038; return &#038; return &#038; "To continue, click the OK button and enter an administrative password in the forthcoming security dialog." with icon 1
		end tell
		set UI elements enabled to true
		if UI elements enabled is false then
			display dialog "This script cannot run while access for assistive devices is disabled." &#038; return &#038; "Exiting now." buttons {"OK"} with icon 2
			return "user cancelled"
		end if
	end if
end tell

# check if DVD Player or MakeMKV are already running
# if not, present a little menu, that allows to select
# which application should be run
#
if not appIsRunning("DVD Player") and not appIsRunning("MakeMKV") then

	with timeout of 3600 seconds
		display dialog "Please choose your desired action:" with title "Action for DVD" buttons {"Cancel", "play DVD", "rip DVD"} cancel button "Cancel" giving up after (5)
	end timeout
	if button returned of result is "rip DVD" then
		if verbose then display dialog "Starting MakeMKV" buttons {"OK"} giving up after 2
		tell application "MakeMKV" to activate
		repeat
			if application "MakeMKV" is running then exit repeat
			delay 5
		end repeat

	else if button returned of result is "Cancel" then
		return
	else
		if verbose then display dialog "Starting DVD Player" buttons {"OK"} giving up after 2
		tell application "DVD Player" to activate
		return
	end if

end if

# check again if MakeMKV is running
# this time, attempt to automate these steps:
# - automatically open the DVD as soon as the drive is ready for access
#
if appIsRunning("MakeMKV") then
	# now tell MakeMKV what to do
	tell application "System Events"
		tell process "MakeMKV"
			# in some rare cases, the menu bar items will stay "greyed out"
			# even if a DVD was inserted
			# the culprit: "AXEnabled" property of the menu will be TRUE even then,
			# although the menu items are not clickable
			# There seems to be no way to check, if they're actually active or inactive
			# However, as a workaround, sending CMD+O to fire up the "File - Open" dialog
			# seems to work, and yet: just opening and closing it will enable the menu bar
			#
			set _retval to false
			repeat until (_retval) is true
				try
					tell application "MakeMKV" to activate
					keystroke "o" using {command down}
					delay 1

					if (exists window 1) and (exists window 2) and (value of attribute "AXRoleDescription" of window 1) = "dialog" then
						click button "Cancel" of window 1
						set _retval to true
					end if
				end try
				delay 1
			end repeat

			# note on the dvd drive selection and menu handling:
			#
			# because we don't know the name of the DVD device,
			# we simply address it by the id of 'menu item 1'
			# so we're just selecting the first device found there.
			# we might have more than one DVD drive, but this is out of scope for now
			#
			# this script was initially triggered by inserting a new disc
			# thus we need to wait until the disc is initially read
			# while this is in progress, our 'Open disc' menu item will be disabled
			#
			set _retval to false
			repeat until (_retval) is true
				try
					repeat while (value of attribute "AXEnabled" of menu "Open disc" of menu item "Open disc" of menu "File" of menu bar item "File" of menu bar 1) is false
						get value of attribute "AXEnabled" of menu "Open disc" of menu item "Open disc" of menu "File" of menu bar item "File" of menu bar 1
						set counter to 5
						repeat while counter is greater than 0
							if verbose then display dialog "Waiting for dvd drive to become ready for use ..." with title "Please wait …" buttons {"" &#038; counter &#038; ""} giving up after 1
							set counter to counter - 1
						end repeat
					end repeat
					set _retval to true
				on error
					display dialog "error"
				end try
				delay 1
			end repeat

			# seems that the dvd drive is now ready for use, now try to load the disc
			#
			if verbose then display dialog "Trying to load DVD in MakeMKV now …" giving up after 1

			# now load the drive
			#
			tell application "MakeMKV" to activate
			click menu item 1 of menu 1 of menu item "Open disc" of menu 1 of menu bar item "File" of menu bar 1

			# now stay and wait until another window appears
			# this should be "completed" dialog at the end
			#
			repeat until ((exists window 1) and (exists window 2))
				delay 15
			end repeat

			# check the type of window 1, which should be a dialog
			# if so, let's close it and try to eject the disk
			#
			if (exists window 1) and (exists window 2) and ((value of attribute "AXRoleDescription" of window 1) = "dialog" or (value of attribute "AXRoleDescription" of window 1) = "standard window") then
				click button 1 of window 1

				click menu item "Eject disc" of menu 1 of menu bar item "File" of menu bar 1
			end if

		end tell
	end tell
end if

# func:appIsRunning
#	appName	: string : name of application (e.g. "DVD Player")
#
# helper to check if application is running or not
#
on appIsRunning(appName)
	tell application "System Events" to (name of processes) contains appName
end appIsRunning
</pre>
<p>This, as far as it goes, saves at least the additional button click to load the DVD in MakeMKV.<br />
However, there is one drawback after all &#8230;</p>
<p>While examining the MakeMKV GUI, I figured that the main panel was not recognized by UI Browser. It was just reported as <b>unknown (UI element #4)</b>. Unfortunately there was no obvious way to get access to the elements within that panel.<br />
This &#8211; as of today &#8211; effectively limits the use of GUI scripting, as it is not possible to interact with the elements within that panel.<br />
Otherwise, I&#8217;d be happy to sit down and write the part, which does auto-selection of the track elements according to some given criteria.</p>
]]></content:encoded>
			<wfw:commentRss>http://phaq.phunsites.net/2011/12/15/automating-makemkv-with-applescript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Interface-Statistiken in Cacti für Swisscom CentroGrande erstellen</title>
		<link>http://phaq.phunsites.net/2011/12/13/interface-statistiken-in-cacti-fur-swisscom-centrogrande-erstellen/</link>
		<comments>http://phaq.phunsites.net/2011/12/13/interface-statistiken-in-cacti-fur-swisscom-centrogrande-erstellen/#comments</comments>
		<pubDate>Tue, 13 Dec 2011 22:31:53 +0000</pubDate>
		<dc:creator>gdelmatto</dc:creator>
				<category><![CDATA[HowTo's]]></category>
		<category><![CDATA[Networking]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://phaq.phunsites.net/?p=806</guid>
		<description><![CDATA[Als Follow-Up zu meinem letzten Post über den Swisscom CentroGrande Router, widme ich mich nun erneut diesem Gerät. Heute geht es darum, Interface-Statistiken in Cacti zu erzeugen &#8212; und das obwohl der CentroGrande den hierfür nötigen SNMP-Support schmerzlich vermissen lässt. Auch wenn der CentroGrande als Consumer-Gerät positioniert ist, wäre für mich &#8211; und wohl auch [...]]]></description>
			<content:encoded><![CDATA[<p>Als Follow-Up zu meinem letzten Post über den <a href="/2011/12/03/swisscom-centro-grande-aufbohren/">Swisscom CentroGrande</a> Router, widme ich mich nun erneut diesem Gerät. Heute geht es darum, Interface-Statistiken in Cacti zu erzeugen &#8212; und das obwohl der CentroGrande den hierfür nötigen SNMP-Support schmerzlich vermissen lässt.</p>
<p><span id="more-806"></span><br />
Auch wenn der CentroGrande als Consumer-Gerät positioniert ist, wäre für mich &#8211; und wohl auch einige andere &#8211; SNMP das Mittel der Wahl zur Überwachung des Geräts wie auch des Netzwerks.</p>
<p>Wenn man die normalerweise deaktivierte Pirelli Management Console auf dem Router aktiviert, gelangt man zwar an einige offiziel nicht zugängliche Funktionen, SNMP ist da aber definitiv nicht dabei. Zwar kann man über die Pirelli Console die Konfigurationsdatei einsehen &#8211; und findet dort auch Hinweise auf SNMP &#8211; doch selbst wer des SNMP-Feature in der Konfiguration manuell aktiviert, wird nach einem Neustart bitter enttäuscht: Weit und breit kein SNMP aktiv <img src='http://phaq.phunsites.net/wp-includes/images/smilies/icon_sad.gif' alt=':-(' class='wp-smiley' /> </p>
<p>Glücklicherweise kann man aber auch für den CentroGrande Interface-Statistiken erzeugen, auch wenn man dafür gewissermassen mit der Kirche ums Dorf herum gehen muss.</p>
<p>Der Trick liegt im Command Line Interface, welches per Telnet und SSH erreichbar ist. Hier kann mit dem Befehl &#8220;net ifcnt all&#8221; für jede Schnittstelle des Routers eine Statistik ausgegeben werden.<br />
Ersetzt man das Schlüsselwort &#8220;all&#8221; durch die Interface-Bezeichnung, bspw. &#8220;wl0&#8243;, erhält man die jeweiligen Einzelstatistiken.</p>
<p>Im folgenden Beispiel werden die Statistiken zur WAN-Schnittstelle angezeigt:</p>
<p><code><br />
[~] # ssh admin@192.168.100.254<br />
OpenRG> net ifcnt eth5.10<br />
---- Driver statistics: port "LAN Fiber VLAN 10" ----<br />
	Device name: eth5.10 - Type: 48, Ethernet<br />
	Network = WAN<br />
	Port status = Connected<br />
	Counters<br />
	  Rx Packets:        2006090<br />
	  Tx Packets:        2477100<br />
	  Rx Bytes:          835058499<br />
	  Tx Bytes:          2356068887<br />
	  Rx Pkts Errors:    0<br />
	  Tx Pkts Problems:  0<br />
	  Rx Dropped Pkts:   0<br />
	  Tx Dropped Pkts:   0<br />
	  Rx Multicast Pkts: NA<br />
	  Tx Multicast Pkts: NA<br />
	  Rx Broadcast Pkts: NA<br />
	  Tx Broadcast Pkts: NA<br />
	  Collisions:        NA</p>
<p>Returned 0<br />
OpenRG><br />
</code></p>
<p>Wer sich in der Pirelli Console schon umgesehen hat, ist vielleicht angesichts der vielen Schnittstellen etwas überfordert.<br />
Die gute Nachricht: Die meisten davon braucht&#8217;s nur für interne Zwecke und sind für die Überwachung kaum relevant. Daher hier eine Auflistung der notwendigen Schnittstellen und deren Funktion:</p>
<pre>
eth0         Switchport 1
eth1         Switchport 2
eth2         Switchport 3
eth3         Switchport 4
wl0          WLAN Access Point
eth5.10      WAN Schnittstelle (Fiber oder DSL)
</pre>
<p>Damit diese Daten nun für Cacti nutzbar werden, bedarf es eines Hilfsprogramms, welches folgende Schritte durchführt:</p>
<ul>
<li>Login auf den Router</li>
<li>Abrufen der Interface-Ststistiken</li>
<li>Ausgabe der bereinigten Informationen</li>
</ul>
<p>Gerade letzterem kommt eine grosse Bedeutung zu, da die Ausgabe wiederum scriptbasiert verarbeitet werden soll und somit normalisiert werden muss.<br />
Wie dies im Detail aussieht, beschreibt die <a href="http://www.cacti.net/downloads/docs/html/making_scripts_work_with_cacti.html" target="_blank">Cacti-Dokumentation</a>.</p>
<p>Basierend auf einem Beispiel-Script aus dem py-expect Package habe ich eine stark abgewandelte Version erstellt, welche allein dem Auslesen des CentroGrande dient und vollständig parametrisierbar ist.<br />
Damit das Script ausführbar wird, sind zum Beispiel unter Debian die Packages python2.5 und python-pexpect erforderlich.</p>
<p>Das ganze sieht beim Ausführen dann wie folgt aus:</p>
<pre>
[~] # /opt/sbin/cg_ifstats.py -u admin -p password -h 192.168.100.254 -i wl0
RxBytes:4230422745 TxBytes:3249795610
</pre>
<p>Damit steht bereits der erste Baustein bereit. Nun muss Cacti noch entsprechend eingerichtet werden, damit die Script-Ausgabe zur Erstellung von Statistiken verwendet werden.</p>
<p>Anweisungen dazu finden sich ebenfalls in der <a href="http://www.cacti.net/downloads/docs/html/how_to.html" target="_blank">Cacti-Dokumentation</a>.</p>
<p>Die nachfolgenden Schritte verdeutlichen dies anhand einiger Screenshoots.<br />
Man kann &#8211; und darf <img src='http://phaq.phunsites.net/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' />  &#8211; es sich aber auch ein bisschen einfacher machen und einfach das Data Template mit den Abhängigkeiten direkt importieren.<br />
Das Data Template kann zusammen mit dem Python Script <a href='http://phaq.phunsites.net/files/2011/12/cg_ifstats.zip'>hier heruntergeladen</a> werden.</p>
<p>Wer die erforderlichen Schritte selbst durchführen möchte, erstellt zuerst eine sogenannte Date Input Method nach dem gezeigten Vorbild.<br />
Dabei müssen insbesonders die Input wie auch die Output Fields erfasst werden (auf Schreibweise achten).<br />
Die Data Input Method wird unter der Bezeichnung &#8220;CentroGrande &#8211; IFSTATS&#8221; gespeichert.</p>
<p><a href="http://phaq.phunsites.net/files/2011/12/data_input1.png" rel="lightbox[806]"><img src="http://phaq.phunsites.net/files/2011/12/data_input1-300x100.png" alt="" width="300" height="100" class="aligncenter size-medium wp-image-813" /></a></p>
<p>Anschliessend wird ein neues Data Template mit der Bezeichnung &#8220;CentroGrande &#8211; Traffic&#8221; erzeugt.<br />
Unter Data Input Method wird die zuvor erstellte Datenquelle &#8220;CentroGrande &#8211; IFSTATS&#8221; verwendet.</p>
<p><a href="http://phaq.phunsites.net/files/2011/12/data_template1.png" rel="lightbox[806]"><img src="http://phaq.phunsites.net/files/2011/12/data_template1-300x76.png" alt="" width="300" height="76" class="aligncenter size-medium wp-image-814" /></a></p>
<p>Weiterhin benötigt das Data Template die Quelldatensätze, &#8220;traffic_in&#8221; und &#8220;traffic_out&#8221;. Diese werden mit den einzelnen Zählern der Data Input Method &#8220;CentroGrande &#8211; IFSTATS&#8221; verbunden, also &#8220;traffic_in&#8221; mit &#8220;RxBytes&#8221; und &#8220;traffic_out&#8221; mit &#8220;TxBytes&#8221;.<br />
Wichtig ist, dass als &#8220;Data Source Type&#8221; der Typ &#8220;COUNTER&#8221; verwendet wird.</p>
<p><a href="http://phaq.phunsites.net/files/2011/12/data_template2.png" rel="lightbox[806]"><img src="http://phaq.phunsites.net/files/2011/12/data_template2-300x68.png" alt="" width="300" height="68" class="aligncenter size-medium wp-image-815" /></a></p>
<p><a href="http://phaq.phunsites.net/files/2011/12/data_template3.png" rel="lightbox[806]"><img src="http://phaq.phunsites.net/files/2011/12/data_template3-300x68.png" alt="" width="300" height="68" class="aligncenter size-medium wp-image-816" /></a></p>
<p>Unter &#8220;Custom Data&#8221; wird bei allen Feldern die Checkbox &#8220;User Per-Data Source Value&#8221; markiert.<br />
Dies ist erforderlich, damit beim folgenden Erzeugen der Graphen die Werte pro Host und Datenquelle einzeln definiert werden können.</p>
<p><a href="http://phaq.phunsites.net/files/2011/12/data_template4.png" rel="lightbox[806]"><img src="http://phaq.phunsites.net/files/2011/12/data_template4-300x45.png" alt="" width="300" height="45" class="aligncenter size-medium wp-image-817" /></a></p>
<p>Nun fehlt das Graph Template. Hierfür klont man am einfachsten eines der bestehenden Graph Templates, beispielsweise &#8220;Interface &#8211; Traffic (bits/sec, Total Bandwidth)&#8221;.<br />
Das geklonte Graph Template bedarf noch einiger Anpassungen, insbesonders bei den Graph Template Items und Graph Item Inputs.<br />
Als Letztere dienen die bereits zuvor definierten Datenquellen &#8220;traffic_in&#8221; und &#8220;traffic_out&#8221;.</p>
<p><a href="http://phaq.phunsites.net/files/2011/12/graph_template1.png" rel="lightbox[806]"><img src="http://phaq.phunsites.net/files/2011/12/graph_template1-300x100.png" alt="" width="300" height="100" class="aligncenter size-medium wp-image-819" /></a></p>
<p>Die Datenquell muss auch bei den Graph Template Items noch entsprechend zu &#8220;traffic_in&#8221; und &#8220;traffic_out&#8221; angepasst werden. </p>
<p><a href="http://phaq.phunsites.net/files/2011/12/graph_template2.png" rel="lightbox[806]"><img src="http://phaq.phunsites.net/files/2011/12/graph_template2-300x95.png" alt="" width="300" height="95" class="aligncenter size-medium wp-image-820" /></a></p>
<p>Damit wäre soweit alles vorbereit, dass nun ein Host-Objekt für den Centro Grande erfasst werden kann.<br />
Anschliessend werden dem Host-Objekt neue Graphs hinzugefügt.</p>
<p><a href="http://phaq.phunsites.net/files/2011/12/create_graph1.png" rel="lightbox[806]"><img src="http://phaq.phunsites.net/files/2011/12/create_graph1-300x36.png" alt="" width="300" height="36" class="aligncenter size-medium wp-image-811" /></a></p>
<p>Je nach Bedarf werden für einzelne oder alle Schnittstelle (wl0, eth5.10, eth0, usw) die Graphen erzeugt.<br />
Dazu muss man zur besseren Unterscheidung unter Title auch die jeweilige Schnittstellenbezeichnung ergänzt werden.<br />
Ferner sind in den Feldern für Username, Passwort, Hostname und Interface die erforderlichen Daten einzutragen.</p>
<p><a href="http://phaq.phunsites.net/files/2011/12/create_graph2.png" rel="lightbox[806]"><img src="http://phaq.phunsites.net/files/2011/12/create_graph2-300x78.png" alt="" width="300" height="78" class="aligncenter size-medium wp-image-812" /></a></p>
<p><a href="http://phaq.phunsites.net/files/2011/12/graph_list.png" rel="lightbox[806]"><img src="http://phaq.phunsites.net/files/2011/12/graph_list-300x69.png" alt="" width="300" height="69" class="aligncenter size-medium wp-image-818" /></a></p>
<p>Nach Abschluss aller Schritte lassen sich fortan die erzeugten Graphs in Cacti bewundern.</p>
<p><a href="http://phaq.phunsites.net/files/2011/12/graphs.png" rel="lightbox[806]"><img src="http://phaq.phunsites.net/files/2011/12/graphs-300x150.png" alt="" width="300" height="150" class="aligncenter size-medium wp-image-821" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://phaq.phunsites.net/2011/12/13/interface-statistiken-in-cacti-fur-swisscom-centrogrande-erstellen/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

