[Updated 26-03: Added the NSX API call script]

During the last few years we’ve had some fun demos at the Dutch VMUG Usercon. We’ve automated a coffee machine using vRealize Orchestrator. We did a vRealize Automation challenge where competitors could control a lightsaber when they successfully completed the blueprint. Because the Dutch VMUG Usercon is the largest in the world, 1.000 attendees, we needed to come up with something special. So we decided to control NSX using Log Insight webhooks and a Lego Mindstorms robot.

Actually @smitmartijn already volunteered to setup a NSX demo with micro-segmentation.  We build on that idea and to show the endless possibilities with VMware software we threw vRealize Log Insight and vRealize Operations in the mix. The idea was to have Usercon attendees control NSX using the Lego Mindstorms robot. The VMUG Usercon is a gathering of tech-savy VMware enthusiasts who like nothing more than to get their hands on tech,  geeky stuff. So a Lego Mindstorms robot should attract some attention.

Building the robot

First I build the Gripp3r robot from the Lego manual because this was a robot which was able to pick up and move items. I had to extend this design and add two additional functions. The robot should be able to recognise the ‘zone’ in which it placed an object. Second, it had to recognise which virtual machine it was moving. For this I added two color sensors. One facing down to detect the color of the ‘zone’, red for unsafe/not segmented, green for the safe micro-segmented zone. I placed the second color sensor near the gripper which enabled me to detect the color of the object, blue for virtual machine 1, white for virtual machine two.

For the ones of you who know Lego Mindstorms, you can program it by placing blocks on a design canvas and assigning a function to it. Much like the example you see below.

Log Insight webhooks

The programming was easy and before I knew I had a robot which could be controlled with a remote control and was able to pick up and move objects.

Programming the robot

The next step was to setup communications between the robot and NSX. Because the Lego Mindstorms EV3 software is Linux based, the idea was to use vRealize Log Insight to gather the syslog and base actions of of that. The only this I needed to do was to enable syslog and point it to our Log Insight instance, easy…….. Ehm wrong! The standard Lego software proved to be very closed and read-only allowing no changes. Some searching pointed me to ‘ev3dev‘. which is a Debian Linux-based operating system that runs on several Lego Mindstroms compatible platforms including the Lego Mindstroms EV3 we were using. The only downside was that the object oriented programming shown above did no longer work. I would have to program Lego Mindstroms EV3 using Python, JavaScript, Go, C or C++. Because a lot of examples online used Python I decided to go with that.

Log Insight webhooks Log Insight webhooks Log Insight webhook

After a long weekend I got it working. I programmed to robot to respond to the ir-remote control. I created two tubes, a white and a blue one, which represent the virtual machines to move around. For the ones who would like to do this themselves, here’s the code.

#!/usr/bin/env python3
from ev3dev.ev3 import *
from time import sleep

import syslog
syslog.syslog(syslog.LOG_INFO, "EV3 Starting NLVMUG ADV project")

import ev3dev.ev3 as ev3
ev3.Sound.speak('Welcome, my name is EV3!').wait()

import urllib.request

from time import sleep
from ev3dev.ev3 import *

# Connect one small motor on output A and two large motors on output ports B and C
tmotor = MediumMotor('outA')
lmotor = LargeMotor('outB')
rmotor = LargeMotor('outC')

# Connect touch sensor on input 1,color sensor on input 2 and a second color sensor on input 3
ts = TouchSensor('in1') 
cl1 = ColorSensor('in2') 
cl2 = ColorSensor('in3') 

# Connect IR sensor to input 4 for remote control
rc = RemoteControl();

# Check that the motors and sensors are actually connected
assert tmotor.connected
assert lmotor.connected
assert rmotor.connected
assert ts.connected
assert cl1.connected
assert cl2.connected
assert rc.connected

# Put the color sensor into COL-COLOR mode.
cl1.mode='COL-REFLECT'
# colors=('unknown','black','blue','green','yellow','red','white','brown')
cl2.mode='COL-REFLECT'

# Turn leds off
Leds.all_off()

def roll(motor, led_group, direction):
    """
    Generate remote control event handler. It rolls given motor into given
    direction (1 for forward, -1 for backward). When motor rolls forward, the
    given led group flashes green, when backward -- red. When motor stops, the
    leds are turned off.

    The on_press function has signature required by RemoteControl class.
    It takes boolean state parameter; True when button is pressed, False
    otherwise.
    """
    def on_press(state):
        if state:
            # Roll when button is pressed
            motor.run_forever(speed_sp=500*direction)
            Leds.set_color(led_group, direction > 0 and Leds.GREEN or Leds.RED)
        else:
            # Stop otherwise
            motor.stop(stop_action='brake')
            Leds.set(led_group, brightness_pct=0)
    return on_press

def tilt(motor, direction):
    """
    Generate remote control event handler to tilt the gripper. 
    Positive speed value moves gripper up, Negative speed value moves gripper down.
    Up/down determined by touch sensor value.

    The on_press function has signature required by RemoteControl class.
    It takes boolean state parameter; True when button is pressed, False
    otherwise.
    """
    def on_press(state):
        if (state and ts.value()):
            motor.run_timed(time_sp=1400, speed_sp=500*direction)
            # ev3.Sound.speak('Got you!').wait()
        elif (state and not ts.value()):
            motor.run_timed(time_sp=1400, speed_sp=-500*direction)
            if (cl1.value() > 40):
                VM_QUARANTINE = 'Un-Secure zone'
                VM_ZONE = 'red'
            else:
                VM_QUARANTINE = 'Microsegmented zone'
                VM_ZONE = 'green' 
            print('zone value={}'.format(cl1.value()))
            print(VM_QUARANTINE)
            if (cl2.value() < 10):
                VM_NAME = 'VM1'
            else:
                VM_NAME = 'VM2'
            print('vm value={}'.format(cl2.value()))
            print(VM_NAME)
            syslog.syslog(syslog.LOG_INFO, "EV3 placed %s in the %s" %(VM_NAME, VM_QUARANTINE))
        else:
            # Stop otherwise
            motor.stop(stop_action='brake')

    return on_press


# Assign event handler to each of the remote buttons
rc.on_red_up    = roll(lmotor, Leds.LEFT,   1)
rc.on_red_down  = roll(lmotor, Leds.LEFT,  -1)
rc.on_blue_up   = roll(rmotor, Leds.RIGHT,  1)
rc.on_blue_down = roll(rmotor, Leds.RIGHT, -1)
rc.on_beacon	= tilt(tmotor, 1)

# Enter event processing loop
while True:
    rc.process()
    sleep(0.01)
    
# Press Ctrl-C to exit

Setup communications

As you can see in the code above, the robot writes a message to the syslog every time it puts an object down. The syslog message includes the zone name and the virtual machine number. To enable syslog I installed syslog-ng and configured the syslog to be forwarded to our Log Insight instance.

Once I set this up, Log Insight picked up on the syslog message right away. Easy does it.

Log Insight webhooks

Trigger actions on NSX

Log Insight webhooksNow we had to perform actions in NSX. We decided to use Log Insight webhooks to initiate the assignment of the security groups to the virtual machines which in turn results in the virtual machine being micro-segmented.

Log Insight webhooks are available from version 3.3 and provide a simple and extensible way to map Log Insight alerts to third-party actions. Of course, you need to translate Log Insight webhooks from the output format of Log Insight into the input format of the third-party destination using a shim.

With Log Insight webhooks you can build integrations with:

  • PagerDuty.
  • Slack.
  • Socialcast.
  • Bugzilla.
  • HipChat.
  • Jenkins.
  • OpsGenie.
  • ServiceNow.
  • PushBullet.
  • vRealize Orchestrator.
  • ZenDesk.

We then created filters in Log Insight and created alerts for them using Log Insight webhooks to initiate the action in NSX using a webserver.

NSX API

After creating the Log Insight webhooks, we needed something that translates a Log Insight webhook to a NSX API call. This was done using a web server with a basic PHP script behind it. The PHP script has different routes for each action:

  • http://webserver/vm1_green – Safeguarding VM1 by blocking traffic
  • http://webserver/vm2_green – Safeguarding VM2 by blocking traffic
  • http://webserver/vm1_red – Unsecuring VM1 by allowing traffic
  • http://webserver/vm2_red – Unsecuring VM1 by allowing traffic

To create this I used the Slim PHP Framework as a kickstarter, which makes it pretty easy and allows the code to be small. Below is the entire script:

The demo shows that with Log Insight we can monitor anything that produces a log file and perform actions based on the log output. This makes Log Insight a very powerful tool and a next step toward auto-remediation of problems or even a self-healing data center. The demo was received with a lot af enthusiasm, attendees really liked the visualisation of the micro-segmentation assignment and the possibilities that Log Insight brings.

All the code that was used in this project can be found on GitHub here:

gitHub-download-button NSX