Categories

CUC (6) CUCM (26) Jabber (6) Python (2) Routing (2) Solarwinds Orion NPM (4) switching (1) Video (6) voice (2)

Thursday, 27 July 2017

Raspberry pi Cron jobs

There really isn't much raspi specific about cron jobs but I started looking into how cron jobs work when I was trying to run a python script automatically.

Cron, is essentially a daemon, that starts up at boot.


On the raspi (and most CentOs/Linux distro's), the location of crontabs file is:   


\var\spool\cron

The crontab file is where you define all the executions that need to take place and at what time.

The crontab syntax is as per below




A crontab file has five fields for specifying day , date and time followed by the command to be run at that interval.


Commands:


crontab -e    Edit crontab file, or create one if it doesn’t already exist.
crontab -l    crontab list of cronjobs , display crontab file contents.
crontab -r    Remove your crontab file.
crontab -v    Display the last time you edited your crontab file. (This option is                        Only available on a few systems.)



so to start editing use crontab -e which will open the unedited crontab in Nano, add executions and then CONTROL+O to save, then exit 

For example:

The command line below in a crontab file deletes all files in a temp folder at 18:30 every day:

30     18     *     *     *         rm /home/trespasser/tmp/*

If you wanted to log the execution of the above crontab execution, point it to create a log file as per below:

30     18     *     *     *         rm /home/trespasser/tmp/* > /home/trespasser/cronlogs/clean_tmp_dir.log


Frequency/repetition.

You can edit crontab to execute a certain line at a certain interval, say every 5 minutes; all the time. In order to do that, and let me keep the previous python script execution as our example:

*/5 * * * * sudo python3 /home/pi/pythonscripts/dfj_gmail_test_v1g.py > /home/pi/pythonscripts/cronlog.log

Here, the line is executed every 5 minutes, disregarding time of day.


You might want to run a python script in the back ground to run in a certain frequency. Now you could loop the script itself, but that would mean you would need to constantly have a session open to the raspi or start it up manually each time it lost power or got recycled, unless you run it with no hangup (I will discuss this in a separate post).

Of course none of this is any good if the cron daemon is not running. To verify if it is:

pi@raspberrypi:/var/log$ service cron status

cron is running.


Now what you have to remember, is that the HOME directory from which crontab works is /home.  This means if you want to run a script for instance from any other directory then /home so one of its subdirectories for instance, it is wise to do a cd line in crontab first to move to the directory from which to execute the script.

Now, before you rely on your crontab's execution, it is good to mock up the command line that you added to the crontab file from the command prompt to see if you did not make any syntax mistakes.

Multiple command lines to do the same execution, in general, is not a good idea as multiple lines do no reference each other. For example:

a crontab with:

01 15 * * * cd /home/pi/pythonscripts
01  15 * * *sudo python3 dfj_gmail_test_v1g.py > /home/pi/pythonscripts/cronlog.log)

would not work as the first line, containing cd /home/pi/pythonscript does not actuall effect the excecution of the second crontab line. So it is better to merge these two commands (lines) into one crontab statement, merging them with &&


cd /home/pi/pythonscripts && sudo python3 dfj_gmail_test_v1g.py > /home/pi/pythonscripts/cronlog.lo

alternatively point the execution of your python script, to its absolute path, as per below:



sudo python3 /home/pi/pythonscripts/dfj_gmail_test_v1g.py > /home/pi/pythonscripts/cronlog.lo


One thing you have to make sure of is that your machine has the correct time and timezone, and the raspberry pi, you might need to run raspi-config (internalization options). 

If you want to trouble shoot the execution of Crontab, possibly because i, writes it's execution result to syslog, which can be found at : 

/var/log/syslog


for example:

ul 28 16:19:01 raspberrypi /usr/sbin/cron[1935]: (pi) RELOAD (crontabs/pi)
Jul 28 16:25:01 raspberrypi /USR/SBIN/CRON[2697]: (pi) CMD (cd /home/pi/pythonscripts )
Jul 28 16:25:01 raspberrypi /USR/SBIN/CRON[2698]: (pi) CMD (sudo python3 dfj_gmail_test_v1g.py > /home/pi/pythonscripts/cronlog.log)

Jul 28 16:25:02 raspberrypi /USR/SBIN/CRON[2695]: (CRON) info (No MTA installed, discarding output)

checking your syslog, will also confirm the time your line in the crontab was executed.


Namaste! Folks

Monday, 10 July 2017

Python object indexing and slicing; lists, strings and tuples.

Wonder where this is leading to, anyway. Let's kick off.


Because lists are sequences, indexing and slicing work the same way for lists as they do for strings (which are essentially a definition of ordered collections of characters, so accessible by position). The key to slicing and indexing is the offset. Python starts at 0 and ends at on less than the length of the string or list. This is important, because the latest character in a string or object in a list is not addressable. You can also use negative offsets, think of this as counting backward from the end. The picture below shows how offsets can be used.





Consider the following string and let's pull the first and last character of that string:

>>> S="flyffy bunny"
>>> S[0],S[-1]
('f', 'y')
>>> 

and slicing (extracting a section):

>>> S[-5:-1]           #negative offset slicing, count from right
'bunn'
>>> S[0:3]
'fly'

another example:

>>> S[1:-1]
'lyffy bunn'

>>> S[0:-1]

'flyffy bunn'

or just apply it straight:

>>> 'flyffy bunny'[1:3]

'ly'

>>> 'flyffy bunny'[slice(1,30)]
'lyffy bunny'


Now consider the following list, containing 3 objects:

>>> L = ['spam', 'Spam', 'SPAM!']

>>> L[2]                #offset starts at 0, which is the object on the left 

'SPAM!'


>>> L[2]                  #Negative; count offset from the right
>>> L[1:]                 # Slicing fetches sections (1st offset from left)

['Spam', 'SPAM!']




Slices can be used to extract columns of data, and to prefix of remove leading and trailing text.


In short:


• S[1:3] fetches items at offsets 1 up to but not including 3.
• S[1:] fetches items at offset 1 through the end (the sequence length).
• S[:3] fetches items at offset 0 up to but not including 3.
• S[:−1] fetches items at offset 0 up to but not including the last item.
• S[:] fetches items at offsets 0 through the end—making a top-level copy of S.

Extended slicing:

As of python 2.3, splice expressions allow  a third, optional index:  the step/stride.  

>>> S="123456789012345567890"
>>> S[0:10:2]

'13579'

This extended slice, takes characters between offset 0 and 10 by steps of 2, so 1 3 5 7 and 9

You can also use a negative stride.

Wednesday, 7 June 2017

Play queue announcements and recordings using Unity Connection

I haven't posted anything on Unity Connection for a while. What has happened so far?  Another joker's in the White House, crude has gone up and London is in a shit state of affairs.  Back to unity connection.  This post is about how to play a recorded message before a call gets handed over to a queue, hunt group or reception console.

Scenarios

For example, let's say you have a queue for an IT service desk and in the event of a large outage you want to play out a message notifying users of a large scale outage "we are currently suffering issues with users connecting to the internet in the Kansas City area and are working to resolve this", before the call is handed over to the queues. Or maybe you want to play out a welcome message before handing a call over to a reception console "welcome to Dead meat Inc. All our meat is guaranteed 100% dead before it lands on your plate". anyway the scenarios are endless, but you can see what I am getting at.

Nuts and bolts

These pre-recorded messages,  are nothing more than recorded greetings in a call handler, it is that simple. So let us get started.

1. Create the call handler CTI route points. For this particular exercise, you need two CTI route points.I will explain later, why you need two and not one.  So the way to do this is to add a CTI RP in CUCM and do a call forward all to your voicemail pilot point.For this example I will use 900617 and 18 for the two call handlers.
2. Add the first call handler, I have called it IT outage notifications and assigned it extension 900617:

Fig 1



3. Go to CUCX and add the first forwarding rule to point the first CTI RP to the correct Call handler, point it to the call handler called "IT outage notification", made in the previous step:

  1. Fig. 2 

Make sure you set it to "go directly to greeting" (see above). This will make the call hitting the handler, go straight to the recorded message/greeting.

Also add the call forwarding condition:

Fig.3

(forwarding station=900617 which is the extension of the CTI RP).

At this stage you should be able to dial into 900617 and the Standard greeting should be played. So test this first before you proceed. If you get an announcement along the lines of "from a touch tone telephone dial any extension...blah blah", your call is not getting through to your call handler and you might be missing your forwarding rule.

4. Set the greetings in your call handler.

This is where you are actually going to define what message will be played when someone calls into your queue and what happens to the caller once the message has been played.  Go back to your call handler, called IT outage Notification (or whatever you have called it) and go to Greetings. 
Let's use the scenario where you want to use a welcome meeting all the time and then go to reception.  So this means, in your 900618 call handler, the standard greeting would need to always play.  Below is a picture of what this welcome message/standard greeting, needs to look like:

Fig. 4 

So you will need to record the standard greeting and personalize it. Don't allow caller input during the meetings and after the greeting send it to a second call handler (IT outage notification after greeting handler) and attempt transfer. I mentioned in the beginning that we needed two call handlers to play a recording before transferring the call and the reason for this is greeting "transfer rules".

There is some contradicting information on what is applied first, the playing of greetings or the application of transfer rules. And to be honest, I have had both set up work, but I prefer to use a second call handler that does not play any greetings, but only attempts the transfer to the reception or queue or wherever it needs to transfer to.  So below is a screenshot of my transfer rules for the first call handler, and is actually a combination of direct transfers and sending the call to a second call handler for transfer.

Fig. 5


The standard greeting on transfers to 33570, once the standard greeting has been played (see figure 4) , this could be your reception.  In the example above (Fig 5) the alternate greeting is sent to 900618, the second call handler.

5. set up a second call handler with a transfer rule

Now set up a second call handler in the same way as your first call handler that contains the welcome message/standard greeting

This second call handler invokes the standard greeting when receiving a call:

Fig. 6




The standard greeting of the second call handler plays nothing (by setting Callers hear Nothing, see fig. 6), it just invokes the standard greeting transfer rule, and transfer the call to 33670, as per Fig. 7


Fig. 7

if you wanted to record the greetings, it is probably easiest to use the greeting administrator, unless moving around wav files is your cuppa tea. The greeting administrator also allows you to easily turn on and off an alternative greeting on one of your call handlers. You can turn the alternate greeting on and off in case you have an extraordinary notification you want to play to your callers, before connecting the call to the queue.

I have done a separate post on how to set up greeting administrator in a separate post.

Namaste!


Sunday, 4 June 2017

Basic QoS verification



Most people would happily apply auto QoS on their Cisco kit and assume that somehow this will guarantee QoS is set up properly like a true self fulfilling prophecy. Of course, there is no such thing. I would argue that that QoS configuration is not an out of the box feature that you just turn on. QoS requires tweaking and a thorough understanding of the quality and quantity of the network traffic in your organisation. When you set it up for the first time, you will most likely not get it 100% right. Maybe you will never get any complaint about the performance of your organisation's applications, simply because you have an obscene amount of bandwidth, maybe there never is any contention on your WAN links, which would make you a pretty happy engineer. For all those, not working for a bank or an insurance company; your WAN links will be just enough to carry the business or branch's traffic, so a properly functioning QoS configuration is important. All the voice engineers reading this article, will tell you that degraded audio and video will be reported straight away by your users. This sort of degradation is almost always symptomatic. I.e. if your QoS is not set up properly your video and audio is the first to suffer.


Cisco uses its MQC (Modular Quality of service Command line interface), to implement QoS on its devices.  Yes its modular, but this is still not a mean feat to configure and verify it.  In this post I will be trying to break down the basics of MQC in an attempt to give it some structure in the way that you can verify its workings. 

MQC is essentially a way to achieve the following:

When traffic enters a router/layer3 switch or any device that needs to police traffic, it needs a way to break up the traffic and decides what priority to give it, access lists can typically do that in combination with DSCP values that have already been set (Phones and telepresence endpoint use af41 for video and ef for audio only, so you you will need to do is trust these values, but putting mls qos trust dscp statements on your access ports). All this is done on the ingress port and essentially you have now 'labelled' (through DSCP) all your interesting traffic. Everything that has not been explicitly labelled will be considered default traffic and will be the first type of traffic to be dropped if there is contention on your egress interface. So on the egress interface you will need to create class maps that match certain DSCP values and give that traffic a certain bandwidth (%). The give it a shape average containing the maximum available bandwidth, this is called a service policy. Finally this service policy is applied to your egress interfaces.

MQC can be roughly broken up into 4 distinct parts of configuration:

  1. Classify traffic using access lists.
  2. Mark traffic in accordance with access lists and or DSCP trust markings
  3. Prioritize and assign bandwidth to each class to create a service policy
  4. Apply the service policy to the interface

Verification commands:

Are my policies applied to the relevant interfaces?
Issue the following command, to find out what service policies are applied to what interfaces, keep in mind that the direction of traffic decides if the service policy is applied at all.

router#show policy-map interface brief
Service-policy output: pm-shape-queue-out
 GigabitEthernet0/0 
Service-policy input: pm-classify-in
 GigabitEthernet0/1.2 
 GigabitEthernet0/1.3 
 GigabitEthernet0/1.5 
 GigabitEthernet0/1.6 
 GigabitEthernet0/1.7 
 GigabitEthernet0/1.8 
 GigabitEthernet0/1.9 
 GigabitEthernet0/1.10 
 GigabitEthernet0/1.11 
 GigabitEthernet0/1.100 
router#


In the example above the service policy called "pm-classify-in" is applied to the router on the ingress ports on Gi0/1, this is where traffic gets marked and classed. On the egress interface Gi0/0 the traffic gets policed and queued/dropped if necessary, using "pm-shape-queue-out".

Is traffic getting dropped?
Once you have established what policy map is applied to what interface you can see its service policy. Look out for the allocated bandwidth for a particular class map and verify offered rate, drop rate and queue drops, these are typically an indication that traffic is being policed and prioritized:

router#show policy-map interface Gi0/0
 GigabitEthernet0/0 

  Service-policy output: pm-shape-queue-out

    Class-map: class-default (match-any)  
      561242536 packets, 233371823734 bytes
      5 minute offered rate 463000 bps, drop rate 0000 bps
      Match: any 
      Queueing
      queue limit 64 packets
      (queue depth/total drops/no-buffer drops) 0/106307/0
      (pkts output/bytes output) 561136228/233229485989
      shape (average) cir 10000000, bc 40000, be 40000
      target shape rate 10000000

      Service-policy : pm-queue-mark-out

        queue stats for all priority classes:
          Queueing
          queue limit 64 packets
          (queue depth/total drops/no-buffer drops) 0/0/0
          (pkts output/bytes output) 69567362/32277474836

        Class-map: cm-prec-4-5-out (match-any)  
          69567365 packets, 32277476457 bytes
          5 minute offered rate 228000 bps, drop rate 0000 bps
          Match:  dscp ef (46)
            104148 packets, 11066856 bytes
            5 minute rate 0 bps
          Match:  dscp af41 (34)
            69463217 packets, 32266409601 bytes
            5 minute rate 228000 bps
          Priority: 33% (3300 kbps), burst bytes 82500, b/w exceed drops: 0   (notice the PRIORITY: 33% which indicates Low latency queueing applies)
          

        Class-map: cm-prec-3-out (match-any)  
          28990699 packets, 7045511506 bytes
          5 minute offered rate 10000 bps, drop rate 0000 bps
          Match: ip precedence 3 
            28990699 packets, 7045511506 bytes
            5 minute rate 10000 bps
          Queueing
          queue limit 64 packets
          (queue depth/total drops/no-buffer drops) 0/830/0
          (pkts output/bytes output) 28989869/7045236932
          bandwidth 5% (500 kbps)

        Class-map: cm-prec-2-out (match-any)  
          168340364 packets, 88941217174 bytes
          5 minute offered rate 85000 bps, drop rate 0000 bps
          Match: ip precedence 2 
            168340364 packets, 88941217174 bytes
            5 minute rate 85000 bps
          Queueing
          queue limit 64 packets
          (queue depth/total drops/no-buffer drops) 0/31192/0
          (pkts output/bytes output) 168309172/88898900167
          bandwidth 27% (2700 kbps)

        Class-map: cm-prec-1-out (match-any)  
          1546262 packets, 2100799191 bytes
          5 minute offered rate 5000 bps, drop rate 0000 bps
          Match: ip precedence 1 
            1546262 packets, 2100799191 bytes
            5 minute rate 5000 bps
          Queueing
          queue limit 64 packets
          (queue depth/total drops/no-buffer drops) 0/286/0
          (pkts output/bytes output) 1545976/2100399647
          bandwidth 5% (500 kbps)

        Class-map: class-default (match-any)  
          292797848 packets, 103006819352 bytes
          5 minute offered rate 112000 bps, drop rate 0000 bps
          Match: any 
          Queueing
          queue limit 64 packets
          (queue depth/total drops/no-buffer drops/flowdrops) 0/73999/0/73999
          (pkts output/bytes output) 292723849/102907474407
          Fair-queue: per-flow queue limit 16 packets

Am I marking my traffic correctly?

Well, this is a bit harder to answer and you might need get wireshark out of your tool box for this and verify is certain interesting traffic has the correct DSCP vlaue once it is received by the far end (use a span port for this for instance).  You could start with looking at your ACLs that define your interesting traffic and see if their statements are getting hit. For example, consider the following access-list, defining traffic for IP precedence 1:

ip access-list extended acl-prec-1
 remark Bulk Traffic
 permit ip any any precedence priority
 permit tcp any any eq 143

 permit tcp any any eq 993


router#      sh ip access-list acl-prec-1         
Extended IP access list acl-prec-1
    10 permit ip any any precedence priority (30831037 matches)
    20 permit tcp any any eq 143 (304 matches)

    30 permit tcp any any eq 993 (52018 matches)



As you can see all the statements in ACL "acl-prec-1", have matches. If you are not seeing any matches on a certain statement, you might need to double check things like IP addresses and ports and change the ACL until it is getting matched.

Another example is an ACL that matches all packets that have DSCP value ef (IP Precedence critical):

ip access-list extended acl-prec-5

 permit ip any any precedence critical

router# sh ip access-list acl-prec-5
Extended IP access list acl-prec-5

    10 permit ip any any precedence critical (1856824595 matches)



This ACL is based on DSCP values being set by the phones and or Telepresence endpoint (that would probably set DSCP to af41), again using the  "mls qos trust DSCP" command on the access port where these endpoint are connected to.



Tuesday, 30 May 2017

Test your links using iperf3

Recently I was looking for some tooling that could test QoS policy maps. So what I wanted to do is max out a link that has QoS applied towards a WAN provider. 


Iperf is essentially a tool that operates in a client/server fashion. So, if you want to  test a certain link in terms of performance, you would need to have iperf running on a machine on either side of the link; one as server, one as client.

By default it generates traffic, initiated on the client to the server, by default on destination port 5201 (UDP or TCP), so if you have a firewall in the path, make sure you open it for the default 5201 towards the iperf server.

Let us look at the full syntax and options first and then discuss a few examples and applications.

Simply run iperf3.exe <enter> from the DOS prompt, this will give you the out put below:


 Server or Client:
  -p, --port      #                       port to listen on/connect to
  -f, --format    [kmgKMG]        format to report: Kbits, Mbits, KBytes, MBytes
  -i, --interval  #                      seconds between periodic bandwidth reports
  -F, --file name                      xmit/recv the specified file
  -B, --bind      <host>            bind to a specific interface
  -V, --verbose                         more detailed output
  -J, --json                               output in JSON format
  --logfile f                              send output to a log file
  -d, --debug                            emit debugging output
  -v, --version                          show version information and quit
  -h, --help                               show this message and quit
Server specific:
  -s, --server                             run in server mode
  -D, --daemon                         run the server as a daemon
  -I, --pidfile file                      write PID file
  -1, --one-off                           handle one client connection then exit
Client specific:
  -c, --client    <host>              run in client mode, connecting to <host>
  -u, --udp                                use UDP rather than TCP
  -b, --bandwidth #[KMG][/#] target bandwidth in bits/sec (0 for unlimited)
                                                (default 1 Mbit/sec for UDP, unlimited for TCP)
                                                (optional slash and packet count for burst mode)
  -t, --time      #                         time in seconds to transmit for (default 10 secs)
  -n, --bytes     #[KMG]           number of bytes to transmit (instead of -t)
  -k, --blockcount #[KMG]      number of blocks (packets) to transmit (instead of -t or -n)
  -l, --len       #[KMG]              length of buffer to read or write
                                                (default 128 KB for TCP, 8 KB for UDP)
  --cport         <port>               bind to a specific client port (TCP and UDP, default: ephemeral port)
  -P, --parallel  #                      number of parallel client streams to run
  -R, --reverse                          run in reverse mode (server sends, client receives)
  -w, --window    #[KMG]      set window size / socket buffer size
  -M, --set-mss   #                   set TCP/SCTP maximum segment size (MTU - 40 bytes)
  -N, --no-delay                      set TCP/SCTP no delay, disabling Nagle's Algorithm
  -4, --version4                       only use IPv4
  -6, --version6                       only use IPv6
  -S, --tos N                            set the IP 'type of service'
  -Z, --zerocopy                       use a 'zero copy' method of sending data
  -O, --omit N                          omit the first n seconds
  -T, --title str                           prefix every output line with this string
  --get-server-output               get results from server
  --udp-counters-64bit             use 64-bit counters in UDP test packets

[KMG] indicates options that support a K/M/G suffix for kilo-, mega-, or giga-

iperf3 homepage at: http://software.es.net/iperf/
Report bugs to:     https://github.com/esnet/iperf


So, because iperf uses a client/server relationship, you will need to copy the iperf3.exe file, to the destination machine (most likely on the far end of the link you are testing), and start it up as the iperf server:

iperf3.exe -s
-----------------------------------------------------------
Server listening on 5201
-----------------------------------------------------------

This now means you can start generating traffic to the IP address to the iperf server. By default this traffic will be generated, using TCP port 5201.

Now that you have the iperf server running, generate some traffic towards it:

iperf3.exe -c 10.1.1.1 -t 60

This will generate TCP traffic for 60 seconds to 10.1.1.1 on port 5201, where 10.1.1.1 is the IP address of the iperf server.

So how could can you apply all this?


If you wanted to swap a link for instance to see what its maximum sustainable bandwidth is, or just to see if your provider is delivery what is set out to. Or if you want to swamp your link and push additional high priority traffic across (such as video and voice) to see if your real time media remain of good quality/are protected by QoS policies; run iperf with multiple parallel stream for, say 300 seconds, or at least a sufficient time frame to test and check.

Run:

iperf3.exe -c 10.1.1.1 -P4 - t 300


This will run 4 unlimited bandwidth streams  (P 4) for a period of 300 seconds to the iperf3 server at 10.1.1.1

QoS


With iperf3 it should be possible to generate traffic with a certain ToS (DSCP) value, this is done by useing the -S parameters so for instance:


iperf3.exe -c 10.1.1.1 -P4 - t 300 -S 184   (where 184 is DSCP/PHB ef)

Having said that, I have not been able to get this to work on win10 machine, so anyone who has' drop me a line. 


What you could do to test QoS is to swamp your link and run a video and or audio call across the same link at the same time, meanwhile checking jitter and media quality.

Oh and you might want to use wireshark as an additional tool so you can verify iperf's working. Try the following link to make DSCP settings more visible in wireshark:


https://www.mikrotik-routeros.com/2014/04/enabling-dscp-tos-display-column-in-wireshark/


All in all I think Iperf is quite a useful tool, and it comes for free, so why not use it.