Tuesday, March 27, 2012

Cloudstack Integration - Detecting instance creation and deletion

So, you want to integrate your cloud?


Let us assume you have a cloud built on cloudstack. Now that you have this cloud, you may need integrate some of your other systems with cloudstack. Why? Well, for all those compute instances that you will run in the cloud, perhaps you will need to tell your other systems about them?

Perhaps you have a monitoring system that you need to configure so that it knows about your new instances?

Perhaps you need to register a dns entry?

Perhaps you need to tell puppet or chef about your new instance?

Perhaps you need to send an email to your boss asking for a raise every time a cloud instance is created?

I had some of these issues and I found out that cloudstack didn't have a great way, out of the box, to run 'custom jobs' when an instance was created or destroyed. However, cloudstack does do a great job giving us the information we need to make this happen. So, with a little help from the folks @ cloudstack, here is what I came up with.



Create and destroy?


Let us assume we want to configure our monitoring system and tell it to start monitoring instances the moment they get created. And, since we care about cleaning up our monitoring system, we also care about removing the instance from the system when the instance is destroyed.

So, how can we find out from cloudstack when these things occur?

At first, I thought about putting something in the OS template itself so that the instance itself would do these things. However, I realized that this might not be the best thing for me a few reasons. Those reasons were:

  • The instance will have no way of knowing if it is being destroyed. (versus just stopped). This would prevent the instance from calling the 'remove me' jobs. 
  • I didn't want to manage and troubleshoot things on a lot of instances (versus a central location). 
  • It might not be secure (assuming a lot of people would have access to the instances). 

So, I decided to query cloudstack itself for this information. Here are some of the options that I came up with:

  • Query the DB directly
  • Parse the log file for output
  • Access the cloud stack events via the api
  • Access the cloud stack instance information via the api
I ended up choosing to use the event information via the api. It had all the inforamtion I needed and using the api is always the best coarse if it is available to you.

So, I wrote a script that polls for event info every X seconds. The script determines if there has been an instance that was created or destroyed successfully. And, if so, the script runs a bunch of integration tasks (like configure my monitoring system).

I wrote the script in python using the python cloudstack library found here:

https://github.com/jasonhancock/cloudstack-python-client


How to get the events?

In order to get the list of events, I decided to use the api method 'listAsyncJobs to get the events. If we want to get the events for all users (not just the account's events), we need to pass the isrecursive and listall parameters correctly).



Code snipnet:


#!/usr/bin/python
import CloudStack

api = 'http://10.1.2.3:8080/client/api'
apikey = 'xxxxxxxxxxxxxxxx'
secret = 'xxxxxxxxxxxxxx'

cloudstack = CloudStack.Client(api, apikey, secret)

jobs = cloudstack.listAsyncJobs({'isrecursive': 'true', 'listall': 'true'})
for job in jobs:



How to detect new instances?

Basically, you need to check for these things:

- event cmd =  ' com.cloud.api.commands.DeployVMCmd'
- event jobstatus = 1  (this means the event was a success)

If these two items are true, we know we have a new instance in our cloud.


Code snipnet:


       # check for new vm jobs
       if ((job['cmd'])=="com.cloud.api.commands.DeployVMCmd"):
         if ((job['jobstatus'])>1):
           #print "SOMETHING WENT WRONG WITH NEW INSTANCE"
         if ((job['jobstatus'])<1):
           #print "VM being created now............"
        if ((job['jobstatus'])==1):
           #print "NEW VM was created successfully........."
           # Here is where we would add the part to configure our monitoring system

How to detect destroyed instances?

Basically, you need to check for these things:

- event cmd =  'com.cloud.api.commands.DestroyVMCmd'

- event jobstatus = 1  (this means the event was a success)


If these two items are true, we know that a cloud instance was destroyed in our cloud.



How to get information about the instance in question?

Now that we know an instance was created or destroyed, our script will need to know some information about the instance in question. No problem!

The data returned in the event itself will have this information!

Below, you will see how I get the instance ID, hostname, and IP address. (other information is available if you need it)

Now that your have that information, you call go create that dns entry or setup monitoring or whatever you need to!


Code snipet:

           vmname=job['jobresult']['virtualmachine']['name']
           vmzoneid=job['jobresult']['virtualmachine']['zoneid']
           for nic in job['jobresult']['virtualmachine']['nic']:
               vmip=nic['ipaddress']
           zones = cloudstack.listZones({'id': vmzoneid})
           for zone in zones:
                  vmdomain=zone['domain']
           vmhostname=vmname+"."+vmdomain

            print vmid, vmhostname, vmip

To sum it up

Now, if you want, you can take your cloudstack cloud and integrate it so that your instances in your cloud are fully and automatically integrated to all your other systems too.

If someone is interesting in the full code I used, let me know and perhaps I can post it up somewhere.

Thanks and happy hunting
Chris


2 comments:

  1. I'm interesting in the code you offer in your post. I would be grateful if you put it somewhere.

    Best Regards,
    Jorge

    ReplyDelete