<?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>automation &#8211; Fredrik Holmberg</title>
	<atom:link href="/category/automation/feed/" rel="self" type="application/rss+xml" />
	<link>/</link>
	<description>Network Consultant</description>
	<lastBuildDate>Thu, 10 Nov 2016 19:39:24 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=4.7.3</generator>

<image>
	<url>/wp-content/uploads/2016/04/cropped-2601-32x32.png</url>
	<title>automation &#8211; Fredrik Holmberg</title>
	<link>/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Network Automation Day</title>
		<link>/2016/09/network-automation-day/</link>
		<comments>/2016/09/network-automation-day/#respond</comments>
		<pubDate>Wed, 14 Sep 2016 12:23:52 +0000</pubDate>
		<dc:creator><![CDATA[Fredrik Holmberg]]></dc:creator>
				<category><![CDATA[ansible]]></category>
		<category><![CDATA[automation]]></category>
		<category><![CDATA[juniper]]></category>
		<category><![CDATA[workshop]]></category>

		<guid isPermaLink="false">/?p=475</guid>
		<description><![CDATA[On September 1st the Norwegian Juniper Elite partner nLogic AS hosted an event called &#8220;Ansible i praksis&#8220;, entirely focused on network automation using Ansible. Lots of interesting presentations and discussions from the Norwegian automation scene. A whole day of Juniper, automation and Ansible! Does it get any better? I had the pleasure of leading a technical workshop at the [&#8230;]]]></description>
				<content:encoded><![CDATA[<h1 style="text-align: center;"><img class="alignnone wp-image-511 " src="/wp-content/uploads/2016/09/ansible_logo_black-1024x138.png" alt="ansible_logo_black" width="580" height="78" srcset="/wp-content/uploads/2016/09/ansible_logo_black-1024x138.png 1024w, /wp-content/uploads/2016/09/ansible_logo_black-300x41.png 300w, /wp-content/uploads/2016/09/ansible_logo_black-768x104.png 768w, /wp-content/uploads/2016/09/ansible_logo_black-676x91.png 676w, /wp-content/uploads/2016/09/ansible_logo_black.png 1125w" sizes="(max-width: 580px) 100vw, 580px" /></h1>
<p>On September 1st the Norwegian Juniper Elite partner <a href="http://www.nlogic.no/">nLogic AS</a> hosted an event called &#8220;<a href="http://nlogic.no/kursogseminarer/367-nlogic-workshop-ansible-i-praksis">Ansible i praksis</a>&#8220;, entirely focused on network automation using Ansible. Lots of interesting presentations and discussions from the Norwegian automation scene. A whole day of Juniper, automation and Ansible! Does it get any better?</p>
<p>I had the pleasure of leading a technical workshop at the end of the event where the attendees were challenged with common operations tasks worthy of automating.</p>
<p>A fun experience and all-in-all a great day!</p>
<p><span id="more-475"></span></p>
<h3>Presentations</h3>
<p><a href="http://www.juniper.net/">Juniper Networks</a> had the first presentation talking about their current automation portfolio and how they are embracing Ansible. Leading by example Juniper publishes fully working playbooks on Github &#8211; <a href="http://github.com/JNPRAutomate">github.com/JNPRAutomate</a>.</p>
<p>Next up was the <a href="http://www.met.no/">Norwegian Meteorological Institute (MET)</a> talking about their Ansible implementation and showcasing everything in a live demo how they modify their Leaf-and-Spine DC fabric including firewall rulesets, on the fly, of course.</p>
<p>Then <a href="http://www.uninett.no/">Uninett</a> showed how they are planning to roll out their new core network using Ansible and how they are saving loads of time by automating the initial preparation of routers, before shipping them out to their educational and research institution partners.</p>
<h3>Workshop</h3>
<p>The last part of the event was the two-hour workshop. The attendees got access to a nine-node Juniper QFX topology which they were challenged to interact with using only Ansible:</p>
<p><img class="wp-image-492 size-full aligncenter" src="/wp-content/uploads/2016/09/junosansibleworkshop.png" alt="junosansibleworkshop" width="519" height="215" srcset="/wp-content/uploads/2016/09/junosansibleworkshop.png 519w, /wp-content/uploads/2016/09/junosansibleworkshop-300x124.png 300w" sizes="(max-width: 519px) 100vw, 519px" /></p>
<p>With the limited amount of time our main focus was:</p>
<ul>
<li>Configure the network infrastructure using abstraction and templates.</li>
<li>Perform an action on a device, then send that information to an external web service.</li>
<li>Export information from your infrastructure for inventory or compliance purposes.</li>
</ul>
<p>Often it&#8217;s the small and simple tasks that yields the greatest automation value.</p>
<p>If you want to try some similar scenarios, Juniper have published great examples on Github &#8211; <a href="http://github.com/JNPRAutomate/ansible-junos-examples">github.com/JNPRAutomate/ansible-junos-examples</a> . You can spin up a two-node topology using <a href="/2016/04/on-demand-juniper-labs-using-vagrant/">Vagrant</a> in minutes and start testing.</p>
<h3>So, what will YOU automate this week?</h3>
<p>Verifying NTP settings in your infrastructure? The planned cloud deployment? The upcoming security compliance check? That single configuration change, that needs to be typed in on 100 nodes?</p>
<p>Start small and scale up later. The important key is that you start automating something.</p>
<p>Unsure if your infrastructure is automation friendly? Need help finding some proper automation candidates? Fear not &#8211; check out my <a href="/consulting/">consulting services</a>.</p>
<p>Have a great day! <img src="https://s.w.org/images/core/emoji/2.2.1/72x72/1f31f.png" alt="🌟" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
]]></content:encoded>
			<wfw:commentRss>/2016/09/network-automation-day/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Measuring wireless performance using Ansible, Elastic Stack and MikroTik</title>
		<link>/2016/03/measuring-wireless-performance-using-ansible-elastic-stack-and-mikrotik/</link>
		<comments>/2016/03/measuring-wireless-performance-using-ansible-elastic-stack-and-mikrotik/#respond</comments>
		<pubDate>Tue, 29 Mar 2016 20:38:00 +0000</pubDate>
		<dc:creator><![CDATA[Fredrik Holmberg]]></dc:creator>
				<category><![CDATA[ansible]]></category>
		<category><![CDATA[automation]]></category>
		<category><![CDATA[elastic stack]]></category>
		<category><![CDATA[mikrotik]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Recently I got a fun challenge handed to me where the scenario was to use 20 MikroTik access points to continuously measure wireless throughput for clients in a large arena. The collected metrics could then be used as a baseline component and indicator of a good or bad wireless user experience. The MikroTik model chosen was [&#8230;]]]></description>
				<content:encoded><![CDATA[<p style="text-align: left;">Recently I got a fun challenge handed to me where the scenario was to use 20 MikroTik access points to continuously measure wireless throughput for clients in a large arena. The collected metrics could then be used as a baseline component and indicator of a good or bad wireless user experience.</p>
<p style="text-align: left;">The MikroTik model chosen was the &#8220;hAP ac lite&#8221; or <a href="http://routerboard.com/RB952Ui-5ac2nD" target="_blank">RB952Ui-5ac2nD</a> which supports 2.4Ghz and 5GHz (802.11 a/b/g/n/ac). Their OS, RouterOS, supports lots of security, wireless and routing <a href="http://wiki.mikrotik.com/wiki/Manual:RouterOS_features" target="_blank">features</a> to play with. All this for a price tag of around 50 USD. Sweet!</p>
<p style="text-align: left;">To solve this challenge we need some way to execute actions on the MikroTik, then extract that output data into some useful format which we then can analyze and store. Then scale this up to <i>n</i> devices and repeat indefinitely.</p>
<p style="text-align: left;"><span id="more-6"></span></p>
<p style="text-align: left;">Since I&#8217;m not a hard-core programmer able to hack out a solution in <a href="https://golang.org/" target="_blank">golang</a> during breakfast, I&#8217;ll go with using the tools I&#8217;m familiar with, namely <a href="https://www.ansible.com/" target="_blank">Ansible</a> and <a href="https://www.elastic.co/" target="_blank">Elastic Stack</a>. Ansible is a tool to perform system/server/network automation using a set of tasks then executing these on a group of hosts. Elastic Stack is a collection of tools allowing you to retrieve, store and visualize data.</p>
<p style="text-align: left;">Here is a visual representation of how these components would work together:</p>
<div style="text-align: left;"></div>
<div style="text-align: left;">
<div id="attachment_30" style="width: 412px" class="wp-caption aligncenter"><img class="wp-image-30 size-full" src="http://104.196.36.32/wp-content/uploads/2016/03/Ansible_MikroTik-2.png" alt="Flow" width="402" height="435" srcset="/wp-content/uploads/2016/03/Ansible_MikroTik-2.png 402w, /wp-content/uploads/2016/03/Ansible_MikroTik-2-277x300.png 277w" sizes="(max-width: 402px) 100vw, 402px" /><p class="wp-caption-text">Splunk was already being used for data storage, so why not have Ansible spread the love and send JSON to both services simultaneously. The more the merrier!</p></div>
</div>
<p style="text-align: left;">First we need to have all of the nodes at a certain configuration level.</p>
<p style="clear: both; text-align: left;"><b>Setup.yml:</b><!-- HTML generated using hilite.me --></p>
<div style="background: #f8f8f8; overflow: auto; width: auto; border: solid gray; border-width: .1em .1em .1em .8em; padding: .2em .6em;">
<pre style="margin: 0; line-height: 125%;"> - hosts: mt-setup
   gather_facts: no
   connection: paramiko

   tasks:
     - name: Create the bwtest user allowing access from Ansible
       raw: <span style="color: #bb4444;">"/user</span> <span style="color: #bb4444;">add</span> <span style="color: #bb4444;">name=bwtest</span> <span style="color: #bb4444;">group=full</span> <span style="color: #bb4444;">password=\"bwpass\"</span> <span style="color: #bb4444;">address=11.22.33.44/32"</span>

     - name: Temporary static route for bandwidth-server if needed
       raw: <span style="color: #bb4444;">":if</span> <span style="color: #bb4444;">(([:len</span> <span style="color: #bb4444;">[/ip</span> <span style="color: #bb4444;">route</span> <span style="color: #bb4444;">find</span> <span style="color: #bb4444;">where</span> <span style="color: #bb4444;">comment=bwtest]])</span> <span style="color: #bb4444;">&lt;</span> <span style="color: #bb4444;">1)</span> <span style="color: #bb4444;">do={/ip</span> <span style="color: #bb4444;">route</span> <span style="color: #bb4444;">add</span> <span style="color: #bb4444;">dst-address=55.66.77.88/32</span> <span style="color: #bb4444;">gateway=1.1.1.1</span> <span style="color: #bb4444;">comment=bwtest}"</span>

     - name: Wireless 2.4Ghz setup
       raw: <span style="color: #bb4444;">"/interface</span> <span style="color: #bb4444;">wireless</span> <span style="color: #bb4444;">set</span> <span style="color: #bb4444;">[</span> <span style="color: #bb4444;">find</span> <span style="color: #bb4444;">default-name=wlan1</span> <span style="color: #bb4444;">]</span> <span style="color: #bb4444;">disabled=no</span> <span style="color: #bb4444;">distance=indoors</span> <span style="color: #bb4444;">frequency=auto</span> <span style="color: #bb4444;">ssid=\"2GHz</span> <span style="color: #bb4444;">SSID\"</span> <span style="color: #bb4444;">wireless-protocol=802.11</span> <span style="color: #bb4444;">bridge-mode=disabled</span> <span style="color: #bb4444;">mode=station"</span>

     - name: Wireless 5GHz setup
       raw: <span style="color: #bb4444;">"/interface</span> <span style="color: #bb4444;">wireless</span> <span style="color: #bb4444;">set</span> <span style="color: #bb4444;">[</span> <span style="color: #bb4444;">find</span> <span style="color: #bb4444;">default-name=wlan2</span> <span style="color: #bb4444;">]</span> <span style="color: #bb4444;">band=5ghz-a/n</span> <span style="color: #bb4444;">disabled=no</span> <span style="color: #bb4444;">distance=indoors</span> <span style="color: #bb4444;">frequency=auto</span> <span style="color: #bb4444;">ssid=\"5GHz</span> <span style="color: #bb4444;">SSID\"</span> <span style="color: #bb4444;">wireless-protocol=802.11</span> <span style="color: #bb4444;">bridge-mode=disabled</span> <span style="color: #bb4444;">mode=station"</span>

     - name: Disable 2.4 GHz wlan bridge interface
       raw: <span style="color: #bb4444;">"/interface</span> <span style="color: #bb4444;">bridge</span> <span style="color: #bb4444;">port</span> <span style="color: #bb4444;">disable</span> <span style="color: #bb4444;">[/interface</span> <span style="color: #bb4444;">bridge</span> <span style="color: #bb4444;">port</span> <span style="color: #bb4444;">find</span> <span style="color: #bb4444;">where</span> <span style="color: #bb4444;">interface=wlan1]"</span>

     - name: Disable 5GHz wlan bridge interface
       raw: <span style="color: #bb4444;">"/interface</span> <span style="color: #bb4444;">bridge</span> <span style="color: #bb4444;">port</span> <span style="color: #bb4444;">disable</span> <span style="color: #bb4444;">[/interface</span> <span style="color: #bb4444;">bridge</span> <span style="color: #bb4444;">port</span> <span style="color: #bb4444;">find</span> <span style="color: #bb4444;">where</span> <span style="color: #bb4444;">interface=wlan2]"</span>

     - name: DHCP client settings 2.4GHz
       raw: <span style="color: #bb4444;">":if</span> <span style="color: #bb4444;">(([:len</span> <span style="color: #bb4444;">[/ip</span> <span style="color: #bb4444;">dhcp-client</span> <span style="color: #bb4444;">find</span> <span style="color: #bb4444;">where</span> <span style="color: #bb4444;">interface=wlan1]])</span> <span style="color: #bb4444;">&lt;</span> <span style="color: #bb4444;">1)</span> <span style="color: #bb4444;">do={/ip</span> <span style="color: #bb4444;">dhcp-client</span> <span style="color: #bb4444;">add</span> <span style="color: #bb4444;">add-default-route=no</span> <span style="color: #bb4444;">dhcp-options=hostname,clientid</span> <span style="color: #bb4444;">disabled=no</span> <span style="color: #bb4444;">interface=wlan1}"</span>

     - name: DHCP client settings 5GHz
       raw: <span style="color: #bb4444;">":if</span> <span style="color: #bb4444;">(([:len</span> <span style="color: #bb4444;">[/ip</span> <span style="color: #bb4444;">dhcp-client</span> <span style="color: #bb4444;">find</span> <span style="color: #bb4444;">where</span> <span style="color: #bb4444;">interface=wlan2]])</span> <span style="color: #bb4444;">&lt;</span> <span style="color: #bb4444;">1)</span> <span style="color: #bb4444;">do={/ip</span> <span style="color: #bb4444;">dhcp-client</span> <span style="color: #bb4444;">add</span> <span style="color: #bb4444;">add-default-route=no</span> <span style="color: #bb4444;">dhcp-options=hostname,clientid</span> <span style="color: #bb4444;">disabled=no</span> <span style="color: #bb4444;">interface=wlan2}"</span>
</pre>
</div>
<div style="clear: both; text-align: left;"></div>
<div style="clear: both; text-align: left;"></div>
<p><!-- HTML generated using hilite.me --></p>
<p>We now have all the MikroTiks configured with two active wireless interfaces, DHCP client running on both interfaces and a user for Ansible to continue its work.</p>
<p>Then it&#8217;s time to perform the actual performance testing and data collection.</p>
<p><b>Benchmark.yml:</b><br />
<!-- HTML generated using hilite.me --></p>
<div style="background: #f8f8f8; overflow: auto; width: auto; border: solid gray; border-width: .1em .1em .1em .8em; padding: .2em .6em;">
<pre style="margin: 0; line-height: 125%;"> - hosts: mt-prod
   gather_facts: no
   connection: paramiko

   vars:
     tikhost: <span style="color: #bb4444;">"{{</span> <span style="color: #bb4444;">ansible_host</span> <span style="color: #bb4444;">}}"</span>
     tikuser: <span style="color: #bb4444;">"bwtest"</span>
     tikpw: <span style="color: #bb4444;">"bwpass"</span>
     tikbwhost: <span style="color: #bb4444;">"55.66.77.88"</span>
     tikduration: <span style="color: #bb4444;">"10"</span>
     tiktx: <span style="color: #bb4444;">"100M"</span>
     tikrx: <span style="color: #bb4444;">"100M"</span>
     tikdirection: <span style="color: #bb4444;">"both"</span>
     colon: <span style="color: #bb4444;">":"</span>

   tasks:
     - name: Disable 5GHz wlan interface
       raw: <span style="color: #bb4444;">"/interface</span> <span style="color: #bb4444;">wireless</span> <span style="color: #bb4444;">set</span> <span style="color: #bb4444;">[</span> <span style="color: #bb4444;">find</span> <span style="color: #bb4444;">default-name=wlan2</span> <span style="color: #bb4444;">]</span> <span style="color: #bb4444;">disabled=yes"</span>

     - name: Waiting for wireless connection to complete
       pause: seconds=5

     - name: Set static route for 2.4GHz testing
       raw: <span style="color: #bb4444;">"ip</span> <span style="color: #bb4444;">route</span> <span style="color: #bb4444;">set</span> <span style="color: #bb4444;">[/ip</span> <span style="color: #bb4444;">route</span> <span style="color: #bb4444;">find</span> <span style="color: #bb4444;">where</span> <span style="color: #bb4444;">comment=bwtest]</span> <span style="color: #bb4444;">gateway=[/ip</span> <span style="color: #bb4444;">dhcp-client</span> <span style="color: #bb4444;">get</span> <span style="color: #bb4444;">[find</span> <span style="color: #bb4444;">interface=wlan1]</span> <span style="color: #bb4444;">gateway]"</span>

     - name: Include TCP test instructions
       include: include/bwtest.yml tikproto="tcp" tikfreq="2.4GHz"

     - name: Include UDP test instructions
       include: include/bwtest.yml tikproto="udp" tikfreq="2.4GHz"

     - name: Disable 2.4GHz wlan interface
       raw: <span style="color: #bb4444;">"/interface</span> <span style="color: #bb4444;">wireless</span> <span style="color: #bb4444;">set</span> <span style="color: #bb4444;">[</span> <span style="color: #bb4444;">find</span> <span style="color: #bb4444;">default-name=wlan1</span> <span style="color: #bb4444;">]</span> <span style="color: #bb4444;">disabled=yes"</span>

     - name: Enable 5GHz wlan interface
       raw: <span style="color: #bb4444;">"/interface</span> <span style="color: #bb4444;">wireless</span> <span style="color: #bb4444;">set</span> <span style="color: #bb4444;">[</span> <span style="color: #bb4444;">find</span> <span style="color: #bb4444;">default-name=wlan2</span> <span style="color: #bb4444;">]</span> <span style="color: #bb4444;">disabled=no"</span>

     - name: Waiting for wireless connection to complete
       pause: seconds=5

     - name: Set static route for 5GHz testing
       raw: <span style="color: #bb4444;">"ip</span> <span style="color: #bb4444;">route</span> <span style="color: #bb4444;">set</span> <span style="color: #bb4444;">[/ip</span> <span style="color: #bb4444;">route</span> <span style="color: #bb4444;">find</span> <span style="color: #bb4444;">where</span> <span style="color: #bb4444;">comment=bwtest]</span> <span style="color: #bb4444;">gateway=[/ip</span> <span style="color: #bb4444;">dhcp-client</span> <span style="color: #bb4444;">get</span> <span style="color: #bb4444;">[find</span> <span style="color: #bb4444;">interface=wlan2]</span> <span style="color: #bb4444;">gateway]"</span>

     - name: Include TCP test instructions
       include: include/bwtest.yml tikproto="tcp" tikfreq="5GHz"

     - name: Include UDP test instructions
       include: include/bwtest.yml tikproto="udp" tikfreq="5GHz"

     - name: Enable 2.4GHz wlan interface
       raw: <span style="color: #bb4444;">"/interface</span> <span style="color: #bb4444;">wireless</span> <span style="color: #bb4444;">set</span> <span style="color: #bb4444;">[</span> <span style="color: #bb4444;">find</span> <span style="color: #bb4444;">default-name=wlan1</span> <span style="color: #bb4444;">]</span> <span style="color: #bb4444;">disabled=no"</span>
</pre>
</div>
<p>We run the bandwidth tests over TCP and UDP using 2.4GHz and 5Ghz. We move the static route around to select our benchmarking interface.</p>
<p>As shown in <b>Benchmark.yml</b> we also include a file called <b>bwtest.yml</b> that executes the actual testing command and formats the output. Including allow us to reuse code instead duplicating it in our playbook.</p>
<p><b>Bwtest.yml:</b><!-- HTML generated using hilite.me --></p>
<div style="background: #f8f8f8; overflow: auto; width: auto; border: solid gray; border-width: .1em .1em .1em .8em; padding: .2em .6em;">
<pre style="margin: 0; line-height: 125%;">- name: Random sleep so we don't DDoS the server
  local_action: shell sleep {{ item }}
  with_random_choice:
    - <span style="color: #bb4444;">"0s"</span>
    - <span style="color: #bb4444;">"5s"</span>
    - <span style="color: #bb4444;">"10s"</span>

- name: Connect to MT and run {{ tikproto }} bandwidth test over {{ tikfreq }}
  local_action: shell ./tikjson.rb {{ tikhost }} {{ tikuser }} {{ tikpw }} /tool/bandwidth-test =address={{ tikbwhost }} =duration={{ tikduration }} =direction={{ tikdirection }} =protocol={{ tikproto }} =local-tx-speed={{ tiktx }} =remote-tx-speed={{ tikrx }} | jq -c '.[][] | .' | sed 'x;$!d'
  register: cmd

- name: Copy JSON output to file
  local_action: copy content="{{ cmd.stdout }}" dest="output/bwtest_{{ tikproto }}_{{ tikhost }}.json"

- name: Rewrite tags in JSON 
  local_action: replace backup=no dest=output/bwtest_{{ tikproto }}_{{ tikhost }}.json regexp='.section' replace='section'
- name: Rewrite tags in JSON 
  local_action: replace backup=no dest=output/bwtest_{{ tikproto }}_{{ tikhost }}.json regexp='.tag' replace='tag'
- name: Rewrite tags in JSON 
  local_action: replace backup=no dest=output/bwtest_{{ tikproto }}_{{ tikhost }}.json regexp='!re' replace='proto'
- name: Rewrite tags in JSON
  local_action: replace backup=no dest=output/bwtest_{{ tikproto }}_{{ tikhost }}.json regexp='null' replace='"{{ tikproto }}"'
- name: Rewrite tags in JSON
  local_action: replace backup=no dest=output/bwtest_{{ tikproto }}_{{ tikhost }}.json regexp='}' replace=', "host"{{ colon }} "{{ tikhost }}", "freq"{{ colon }} "{{ tikfreq }}" }'

- name: Send JSON to log analyzer (Logstash)
  local_action: shell /bin/nc -q1 -w2 logstash.com 23777 &lt; output/bwtest_{{ tikproto }}_{{ tikhost }}.json
  ignore_errors: yes

- name: Send JSON to log analyzer (Splunk)
  local_action: shell /bin/nc -q1 -w2 splunk.com 23777 &lt; output/bwtest_{{ tikproto }}_{{ tikhost }}.json
  ignore_errors: yes</pre>
</div>
<p style="clear: both; text-align: left;">Here we invoke a MikroTik RouterOS API client written in Ruby (<a href="http://github.com/astounding/mtik">http://github.com/astounding/mtik</a>).</p>
<p style="clear: both; text-align: left;">These three YAML files put together produce the following JSON output:</p>
<div style="clear: both; text-align: left;"><!-- HTML generated using hilite.me --></div>
<div style="background: #f8f8f8; border-width: 0.1em 0.1em 0.1em 0.8em; border: solid gray; overflow: auto; padding: 0.2em 0.6em; width: auto;">
<pre style="line-height: 125%; margin: 0;">{
 <span style="color: green; font-weight: bold;">"status"</span>: <span style="color: #bb4444;">"done testing"</span>,
 <span style="color: green; font-weight: bold;">"tx-10-second-average"</span>: <span style="color: #bb4444;">"1680920"</span>,
 <span style="color: green; font-weight: bold;">"direction"</span>: <span style="color: #bb4444;">"both"</span>,
 <span style="color: green; font-weight: bold;">"tx-total-average"</span>: <span style="color: #bb4444;">"1680920"</span>,
 <span style="color: green; font-weight: bold;">"rx-10-second-average"</span>: <span style="color: #bb4444;">"501408"</span>,
 <span style="color: green; font-weight: bold;">"rx-total-average"</span>: <span style="color: #bb4444;">"501408"</span>,
 <span style="color: green; font-weight: bold;">"proto"</span>: <span style="color: #bb4444;">"tcp"</span>,
 <span style="color: green; font-weight: bold;">"duration"</span>: <span style="color: #bb4444;">"11s"</span>,
 <span style="color: green; font-weight: bold;">"tx-current"</span>: <span style="color: #bb4444;">"684832"</span>,
 <span style="color: green; font-weight: bold;">"random-data"</span>: <span style="color: #bb4444;">"false"</span>,
 <span style="color: green; font-weight: bold;">"section"</span>: <span style="color: #bb4444;">"11"</span>,
 <span style="color: green; font-weight: bold;">"tag"</span>: <span style="color: #bb4444;">"3"</span>,
 <span style="color: green; font-weight: bold;">"rx-current"</span>: <span style="color: #bb4444;">"341304"</span>,
 <span style="color: green; font-weight: bold;">"host"</span>: <span style="color: #bb4444;">"14.52.63.41"</span>,
 <span style="color: green; font-weight: bold;">"freq"</span>: <span style="color: #bb4444;">"5GHz"</span>
}</pre>
</div>
<p style="clear: both; text-align: left;">Now what?</p>
<p style="clear: both; text-align: left;">With this data sent to Logstash and Splunk we can finally produce some pretty graphs and gain some insights:</p>
<p style="clear: both; text-align: left;">Top performing wireless zone per protocol:</p>
<p style="clear: both; text-align: left;"><img class="alignnone wp-image-31 size-full" src="/wp-content/uploads/2016/03/tx_tot_avg_per_host_split_proto_2-1.png" alt="tx_tot_avg_per_host_split_proto_2" width="1188" height="463" srcset="/wp-content/uploads/2016/03/tx_tot_avg_per_host_split_proto_2-1.png 1188w, /wp-content/uploads/2016/03/tx_tot_avg_per_host_split_proto_2-1-300x117.png 300w, /wp-content/uploads/2016/03/tx_tot_avg_per_host_split_proto_2-1-768x299.png 768w, /wp-content/uploads/2016/03/tx_tot_avg_per_host_split_proto_2-1-1024x399.png 1024w, /wp-content/uploads/2016/03/tx_tot_avg_per_host_split_proto_2-1-676x263.png 676w" sizes="(max-width: 1188px) 100vw, 1188px" /></p>
<p style="clear: both; text-align: left;">Performance distribution per zone over time:</p>
<p style="clear: both; text-align: left;"><img class="alignnone wp-image-32 size-full" src="/wp-content/uploads/2016/03/tx_tot_distrib_2-1.png" alt="tx_tot_distrib_2" width="741" height="451" srcset="/wp-content/uploads/2016/03/tx_tot_distrib_2-1.png 741w, /wp-content/uploads/2016/03/tx_tot_distrib_2-1-300x183.png 300w, /wp-content/uploads/2016/03/tx_tot_distrib_2-1-676x411.png 676w" sizes="(max-width: 741px) 100vw, 741px" /></p>
<p style="clear: both; text-align: left;">Total Rx/Tx performance over time:</p>
<p style="clear: both; text-align: left;"><img class="alignnone wp-image-33 size-full" src="/wp-content/uploads/2016/03/rx_tx_tot_avg-1.png" alt="rx_tx_tot_avg" width="654" height="251" srcset="/wp-content/uploads/2016/03/rx_tx_tot_avg-1.png 654w, /wp-content/uploads/2016/03/rx_tx_tot_avg-1-300x115.png 300w" sizes="(max-width: 654px) 100vw, 654px" /></p>
<p style="clear: both; text-align: left;">We&#8217;ve only scratched the surface here, but you get the idea. Ansible allows you to automate just about anything and Kibana makes it look great <img src="https://s.w.org/images/core/emoji/2.2.1/72x72/1f4aa.png" alt="💪" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
<p style="clear: both; text-align: left;">Check out my <a href="/consulting/">Consulting Services</a> if you&#8217;re interested in implementing something similar for your organization.</p>
]]></content:encoded>
			<wfw:commentRss>/2016/03/measuring-wireless-performance-using-ansible-elastic-stack-and-mikrotik/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GNSparser, now on Bitbucket</title>
		<link>/2014/04/gnsparser-now-on-bitbucket/</link>
		<comments>/2014/04/gnsparser-now-on-bitbucket/#respond</comments>
		<pubDate>Sat, 12 Apr 2014 11:47:00 +0000</pubDate>
		<dc:creator><![CDATA[Fredrik Holmberg]]></dc:creator>
				<category><![CDATA[automation]]></category>
		<category><![CDATA[gns3]]></category>
		<category><![CDATA[gnsparser]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[I&#8217;ve decided to make GNSparser available on Bitbucket. With the source code open to the public you can now run it on your own web server or laptop. Got ideas for new features? Issue a pull request! Fetch it here: http://bitbucket.org/holmahenkel/gnsparser/ Enjoy!]]></description>
				<content:encoded><![CDATA[<div style="clear: both; text-align: left;"></div>
<div>
<div style="width: 197px" class="wp-caption alignleft"><img class="" src="https://cdn1.iconfinder.com/data/icons/simple-icons/1024/bitbucket-1024-black.png" alt="" width="187" height="187" /><p class="wp-caption-text">Bitbucket</p></div>
<p>I&#8217;ve decided to make GNSparser available on Bitbucket. With the source code open to the public you can now run it on your own web server or laptop. Got ideas for new features? Issue a pull request!</p>
<p>Fetch it here:<br />
<a href="http://bitbucket.org/holmahenkel/gnsparser/">http://bitbucket.org/holmahenkel/gnsparser/</a></p>
<p>Enjoy!</p>
</div>
]]></content:encoded>
			<wfw:commentRss>/2014/04/gnsparser-now-on-bitbucket/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Introducing GNSparser</title>
		<link>/2013/11/introducing-gnsparser/</link>
		<comments>/2013/11/introducing-gnsparser/#respond</comments>
		<pubDate>Thu, 21 Nov 2013 07:32:00 +0000</pubDate>
		<dc:creator><![CDATA[Fredrik Holmberg]]></dc:creator>
				<category><![CDATA[automation]]></category>
		<category><![CDATA[dynagen]]></category>
		<category><![CDATA[gns3]]></category>
		<category><![CDATA[gnsparser]]></category>
		<category><![CDATA[network lab]]></category>
		<category><![CDATA[scripting]]></category>
		<category><![CDATA[lab]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[I have used Dynagen/GNS3 for some years now and recently it started to annoy me how much time I had to spend every time on the initial lab setup before I could start with the actual lab or proof of concept scenario. Usually I start off a lab by building the topology itself &#8211; adding [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>I have used Dynagen/GNS3 for some years now and recently it started to annoy me how much time I had to spend every time on the initial lab setup before I could start with the actual lab or proof of concept scenario.</p>
<p><span id="more-8"></span></p>
<p>Usually I start off a lab by building the topology itself &#8211; adding all the nodes, adding the network modules to each node and then connecting them all together. When that&#8217;s done I boot the topology <a href="/2013/08/gns3dynamips-labs-with-a-twist-using-digitalocean/">in the cloud</a>, figure out a proper addressing scheme, open a console session to each device, configure the Ethernet interfaces according to the scheme, configure loopback interfaces for router IDs and LAN simulation, configure global settings for lines, IPv6, logging etc. and then finally enable one or more routing protocols on all nodes for end-to-end connectivity.</p>
<p>What if I could outsource these initial router configuration steps? Just create a topology and off I go?</p>
<p>Unable to find a proper *aaS provider or Facebook app for this particular need, I built <a href="http://bitbucket.org/holmahenkel/gnsparser" target="_blank">something</a> that solves just that:</p>
<p><img class="size-full wp-image-40 aligncenter" src="http://104.196.36.32/wp-content/uploads/2013/11/gnsparser.png" alt="gnsparser" width="640" height="485" srcset="/wp-content/uploads/2013/11/gnsparser.png 640w, /wp-content/uploads/2013/11/gnsparser-300x227.png 300w" sizes="(max-width: 640px) 100vw, 640px" /></p>
<div style="clear: both; text-align: center;"></div>
]]></content:encoded>
			<wfw:commentRss>/2013/11/introducing-gnsparser/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GNS3/Dynamips labs with a twist using DigitalOcean</title>
		<link>/2013/08/gns3dynamips-labs-with-a-twist-using-digitalocean/</link>
		<comments>/2013/08/gns3dynamips-labs-with-a-twist-using-digitalocean/#respond</comments>
		<pubDate>Wed, 07 Aug 2013 22:03:00 +0000</pubDate>
		<dc:creator><![CDATA[Fredrik Holmberg]]></dc:creator>
				<category><![CDATA[automation]]></category>
		<category><![CDATA[digital ocean]]></category>
		<category><![CDATA[dynagen]]></category>
		<category><![CDATA[gns3]]></category>
		<category><![CDATA[network lab]]></category>
		<category><![CDATA[lab]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Inspired by +Mikhail Schedrin and his cloud-only GNS3/Dynamips labs, I decided to configure one myself. Thanks to the awesome hosting provider DigitalOcean (http://www.digitalocean.com) you/ can have a proper Cisco CCNA/CCNP/CCIE lab running for 0.060 USD per hour (4GB Memory, 2 CPU Cores). Lab configuration Copy Dynamips (http://www.gns3.net/dynamips/) and a Cisco IOS image to your VM. Then configure the [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Inspired by <a href="http://plus.google.com/109548533862883698112" target="_blank">+Mikhail Schedrin</a> and his cloud-only GNS3/Dynamips labs, I decided to configure one myself. Thanks to the awesome hosting provider DigitalOcean (<a href="http://www.digitalocean.com/">http://www.digitalocean.com/</a>) you can have a proper Cisco CCNA/CCNP/CCIE lab running for 0.060 USD per hour (4GB Memory, 2 CPU Cores).</p>
<p><span id="more-9"></span></p>
<p><b>Lab configuration</b><br />
Copy Dynamips (<a href="http://www.gns3.net/dynamips/">http://www.gns3.net/dynamips/</a>) and a Cisco IOS image to your VM. Then configure the Dynamips processes to launch at startup and prepare a timestamp log file for later:</p>
<table>
<tbody>
<tr>
<td bgcolor="lightgrey">
<pre>/etc/rc.local:
==============
/root/net/dynamips/dynamips-0.2.8-RC3-community-x86.bin -H 7200 &amp;
/root/net/dynamips/dynamips-0.2.8-RC3-community-x86.bin -H 7201 &amp;
/root/net/dynamips/dynamips-0.2.8-RC3-community-x86.bin -H 7202 &amp;

touch /tmp/do_timestamp.log
date +%s &gt; /tmp/do_timestamp.log</pre>
</td>
</tr>
</tbody>
</table>
<p>Run as many instances of Dynamips as you want. Two or more allows for load balancing from GNS3 by distributing the virtual routers across multiple processes.</p>
<p>Then configure GNS3 to use your VM as an &#8220;External Hypervisor&#8221;:</p>
<p><img class="alignnone size-full wp-image-84" src="http://104.196.36.32/wp-content/uploads/2013/08/ext_hypervisors-1.png" alt="ext_hypervisors" width="763" height="587" srcset="/wp-content/uploads/2013/08/ext_hypervisors-1.png 763w, /wp-content/uploads/2013/08/ext_hypervisors-1-300x231.png 300w, /wp-content/uploads/2013/08/ext_hypervisors-1-676x520.png 676w" sizes="(max-width: 763px) 100vw, 763px" /></p>
<p><img class="alignnone size-full wp-image-85" src="http://104.196.36.32/wp-content/uploads/2013/08/ios_images-1.png" alt="ios_images" width="909" height="589" srcset="/wp-content/uploads/2013/08/ios_images-1.png 909w, /wp-content/uploads/2013/08/ios_images-1-300x194.png 300w, /wp-content/uploads/2013/08/ios_images-1-768x498.png 768w, /wp-content/uploads/2013/08/ios_images-1-676x438.png 676w" sizes="(max-width: 909px) 100vw, 909px" /></p>
<p>Create a topology, <a href="http://bitbucket.org/holmahenkel/gnsparser">run it through GNSparser</a> and off you go.</p>
<div id="attachment_86" style="width: 410px" class="wp-caption alignnone"><img class="size-full wp-image-86" src="http://104.196.36.32/wp-content/uploads/2013/08/arpanet-5-1.jpg" alt="Even Michael Caine enjoy Cisco labs." width="400" height="274" srcset="/wp-content/uploads/2013/08/arpanet-5-1.jpg 400w, /wp-content/uploads/2013/08/arpanet-5-1-300x206.jpg 300w" sizes="(max-width: 400px) 100vw, 400px" /><p class="wp-caption-text">Even Michael Caine enjoy Cisco labs.</p></div>
<div style="clear: both; text-align: left;"></div>
<p style="clear: both; text-align: left;"><b>That awkward feeling</b></p>
<p style="clear: both; text-align: left;">Two hours later and you&#8217;re done for the day. You shutdown your laptop but <b>forget to destroy the VM!!</b> The meter keeps on running. Leave it running idle for another two weeks and you&#8217;ve used 20 USD on cloud air. There&#8217;s no market for cloud air, so that money is lost. There are lots of better things to invest in <a href="http://www.thinkgeek.com/interests/giftsunder20/">http://www.thinkgeek.com/interests/giftsunder20/</a>.</p>
<p style="clear: both; text-align: left;">Here&#8217;s one way to avoid those situations.</p>
<p style="clear: both; text-align: left;">We will create a script that checks if there are any active TCP sessions towards the Dynamips processes. Here&#8217;s an example of ten processes ready and listening:</p>
<table>
<tbody>
<tr>
<td bgcolor="lightgrey">
<pre>root@gns:~# netstat -na4
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State      
tcp        0      0 0.0.0.0:7200            0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:7201            0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:7202            0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:7203            0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:7204            0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:7205            0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:7206            0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:7207            0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:7208            0.0.0.0:*               LISTEN     
tcp        0      0 0.0.0.0:7209            0.0.0.0:*               LISTEN</pre>
</td>
</tr>
</tbody>
</table>
<p>Should the script find TCP sessions against ports 7200-7209 in an ESTABLISHED state, it will set an initial counter with the current UNIX timestamp.</p>
<p>After you&#8217;ve logged out and your TCP sessions are torn down, the script will figure out that there are no ESTABLISHED sessions left. It will then start to count down for one hour.</p>
<p>If you haven&#8217;t reconnected to the VM (resetting the counter) within that time frame, the VM will go kamikaze on itself and issue a destroy request using the DigitalOcean API (<a href="https://www.digitalocean.com/api">https://www.digitalocean.com/api</a>).</p>
<p><b>Meet the self-destructing VM</b><br />
First, install the PHP5 CLI interpreter package to run PHP scripts on your server. Here&#8217;s how on Ubuntu etc.:</p>
<table>
<tbody>
<tr>
<td bgcolor="lightgrey">
<pre>$ apt-get install php5-cli</pre>
</td>
</tr>
</tbody>
</table>
<p>Copy the following script to a suitable location:</p>
<blockquote>
<pre>do_destroy.php
==============
&lt;?php

$api_key = "secret_API_key";
$api_cid = "secret_API_cid";

$file = '/tmp/do_timestamp.log';
$ts_log = file_get_contents($file);
$ts_diff = time() - $ts_log;

$vm = "gns"; // NAME OF VIRTUAL MACHINE AT DO

function destroy($vm) {
        global $api_key, $api_cid;

        $do_status = file_get_contents('https://api.digitalocean.com/droplets/?client_id=' . $api_cid . '&amp;api_key=' . $api_key);

        $ar_status = json_decode("$do_status", true);

        foreach($ar_status['droplets'] as $droplet) {
                if($droplet['name'] == $vm) {
#                       file_get_contents('https://api.digitalocean.com/droplets/' . $droplet['id'] . '/destroy/?client_id=' . $api_cid . '&amp;api_key=' . $api_key);
                } else {
                        continue;
                }
        }
}

function acon() {
        $netstat = exec("netstat -na4 | grep -E ':720' | grep -E 'ESTABLISHED' | wc -l");
        if($netstat &gt; 0) {
                return 1;
        } else {
                return 0;
        }
}

if(acon() == 1) {
        $curtime = time() . "n";
        file_put_contents($file, $curtime);
} elseif(acon() == 0 &amp;&amp; $ts_diff &gt; 3600) {
        destroy($vm);
} else {
        return 0;
}

?&gt;</pre>
</blockquote>
<p>Configure a cron job to run every 15 minutes:</p>
<table>
<tbody>
<tr>
<td bgcolor="lightgrey">
<pre>crontab -e:
===========
*/15 * * * * php /root/sh/do_destroy.php &gt; /dev/null 2&gt;&amp;1</pre>
</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
<p>With all this configured and working, create a snapshot of your VM. This way you can setup a network lab whenever you feel like it. One way is by using the Android application Basin (<a href="http://basinapp.com/">http://basinapp.com/</a>) on your phone. Best of all, no need to worry about leaving the VM running. Automation will take care of the cleaning &lt;3</p>
<p>Good luck!</p>
]]></content:encoded>
			<wfw:commentRss>/2013/08/gns3dynamips-labs-with-a-twist-using-digitalocean/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>More on Tcl and loopback interfaces</title>
		<link>/2012/07/more-on-tcl-and-loopback-interfaces/</link>
		<comments>/2012/07/more-on-tcl-and-loopback-interfaces/#respond</comments>
		<pubDate>Wed, 18 Jul 2012 03:00:00 +0000</pubDate>
		<dc:creator><![CDATA[Fredrik Holmberg]]></dc:creator>
				<category><![CDATA[automation]]></category>
		<category><![CDATA[loopback]]></category>
		<category><![CDATA[tcl]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[Here&#8217;s yet another way to generate loopback interfaces using Tcl. This time we add interfaces from a custom list of subnet IDs. We will use the following Tcl script: set i "0" foreach subnet { 48 50 52 54 } { puts "interface loopback $i" puts " ip address 192.168.$subnet.1 255.255.255.0" incr i 1 } [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Here&#8217;s yet another way to <a href="/2012/03/generating-loopback-interfaces-using-tcl/">generate loopback interfaces</a> using Tcl. This time we add interfaces from a custom list of subnet IDs.</p>
<p><span id="more-10"></span></p>
<p>We will use the following Tcl script:</p>
<blockquote>
<pre>set i "0"

foreach subnet {
 48
 50
 52
 54
} {
 puts "interface loopback $i"
 puts " ip address 192.168.$subnet.1 255.255.255.0"
 incr i 1
}</pre>
</blockquote>
<p>Using this script we can do the following:</p>
<blockquote>
<pre>Router#
Router#<b>tclsh</b>
Router(tcl)#<b>set i "0"</b>
0
Router(tcl)#<b>foreach subnet {</b>
<b>+&gt; 48
+&gt; 50
+&gt; 52
+&gt; 54
+&gt;} {
+&gt; puts "interface loopback $i"
+&gt; puts " ip address 192.168.$subnet.1 255.255.255.0"
+&gt; incr i 1
+&gt;}</b>
interface loopback 0
 ip address 192.168.48.1 255.255.255.0
interface loopback 1
 ip address 192.168.50.1 255.255.255.0
interface loopback 2
 ip address 192.168.52.1 255.255.255.0
interface loopback 3
 ip address 192.168.54.1 255.255.255.0

Router(tcl)#exit</pre>
</blockquote>
<p>Notice how the script only sends the configuration to standard output. In order to actually create the interfaces we have to copy and paste the script output into configure terminal:</p>
<blockquote>
<pre>Router#
Router#<b>conf t</b>
Enter configuration commands, one per line.  End with CNTL/Z.
Router(config)#<b>interface loopback 0</b>
Router(config-if)#<b> ip address 192.168.48.1 255.255.255.0</b>
Router(config-if)#<b>interface loopback 1</b>
Router(config-if)#<b> ip address 192.168.50.1 255.255.255.0</b>
Router(config-if)#<b>interface loopback 2</b>
Router(config-if)#<b> ip address 192.168.52.1 255.255.255.0</b>
Router(config-if)#<b>interface loopback 3</b>
Router(config-if)#<b> ip address 192.168.54.1 255.255.255.0</b>
Router(config-if)#
*Mar  1 00:01:19.331: %LINEPROTO-5-UPDOWN: Line protocol on Interface Loopback0, changed state to up
*Mar  1 00:01:19.547: %LINEPROTO-5-UPDOWN: Line protocol on Interface Loopback1, changed state to up
*Mar  1 00:01:19.659: %LINEPROTO-5-UPDOWN: Line protocol on Interface Loopback2, changed state to up
*Mar  1 00:01:19.779: %LINEPROTO-5-UPDOWN: Line protocol on Interface Loopback3, changed state to up
Router(config-if)#<b>end</b>
Router#<b>sh protocols</b>
Global values:
  Internet Protocol routing is enabled
FastEthernet0/0 is administratively down, line protocol is down
FastEthernet0/1 is administratively down, line protocol is down
Loopback0 is up, line protocol is up
  Internet address is 192.168.48.1/24
Loopback1 is up, line protocol is up
  Internet address is 192.168.50.1/24
Loopback2 is up, line protocol is up
  Internet address is 192.168.52.1/24
Loopback3 is up, line protocol is up
  Internet address is 192.168.54.1/24

</pre>
</blockquote>
<p>Very handy when doing labs <img src="https://s.w.org/images/core/emoji/2.2.1/72x72/1f642.png" alt="🙂" class="wp-smiley" style="height: 1em; max-height: 1em;" /></p>
]]></content:encoded>
			<wfw:commentRss>/2012/07/more-on-tcl-and-loopback-interfaces/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
