On Aug 2, 2013, at 2:42 PM, Rohit Yadav wrote:

> On Thu, Aug 1, 2013 at 10:43 PM, Donal Lafferty
> <donal.laffe...@citrix.com>wrote:
> 
>> I needed a different configuration than DevCloud provided, so I turned to
>> CloudMonkey to automate setup of my test environment.
>> 
>> This led to a blog on automating with CloudMonkey at
>> http://dlafferty.blogspot.co.uk/2013/07/using-cloudmonkey-to-automate.html
>> 
>> 
> Nice.
> 
> 
>> What I forgot to mention is that automation would be a lot simpler if we
>> were to do the following:
>> 
>> 1.       Update Apache CloudStack logging to provide API calls in a tidy
>> format that can be fed directly.  E.g. POST parameters are not logged,  GET
>> parameters are URL encoded.
>> 
>> 2.       Update CloudMonkey to allow username / password authentication
>> 
> 
> +1, send patch :)

I use following:
cloudauth.py retrieves a key pair...
cloudclient.py is a simple wrapper around cloudmonkey so that we can use it 
directly from python scripts and get json replies.

usage example:
def createZone(client):
    try:
        response = client.request('listZones')
        if response['listzonesresponse']:
            return response['listzonesresponse']['zone'][0]['id']

        response = client.request('createZone',
                                  {'name': 'default',
                                   'networktype': 'Advanced',
                                   'domain': 'ROOT',
                                   'dns1': PARAMS['external_dns'],
                                   'internaldns1': PARAMS['internal_dns']})
        return response['createzoneresponse']['zone']['id']

    except Exception as e:
        print 'Error while creating a zone:'
        print e
        raise



import cloudauth
from cloudmonkey.requester import monkeyrequest
import logging
import sys

class CloudClient(object):
    class Error(Exception):
        """ Base error."""
        pass

    def __init__(self, hostname, username, password):
        self.host = hostname
        self.username = username
        self.password = password
        self.port = 8080
        self.path = '/client/api'
        self.protocol = 'http'
        self.timeout = 3600
        keypair = cloudauth.getApiKey(self.host, self.username, self.password)
        if not keypair:
            sys.exit(1)
        (self.apiKey, self.secretKey) = keypair

    def request(self, command, args={}):
        response, error = monkeyrequest(command, args, True,
                                        "true", logging.getLogger(),
                                        self.host, self.port,
                                        self.apiKey, self.secretKey,
                                        self.timeout, self.protocol, self.path)
        if error is not None:
            raise self.Error("Request %s:\n%s\nfailed with error:\n%s" %
                             (command, str(args), error))
        return response
import json
import logging
import os
import subprocess
import tempfile
import urllib

def encodeURIComponent(str):
    return urllib.quote(str, safe='~()*!.\'')

def cloudLogin(hostname, username, password, tmp_name):
    login = ("command=login&username=" + username + "&password=" + password +
             "&response=json")
    cmd = ['curl',
           '-H', 'Content-Type: application/x-www-form-urlencoded',
           '-H', 'Accept: application/json',
           '-X', 'POST',
           '-d', login,
           '-c', tmp_name,
           'http://' + hostname + ':8080/client/api']
    proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    (output, err) = proc.communicate()
    response = json.loads(output)
    if response.get('errorresponse'):
        print response['errorresponse']['errortext']
        return None
    return response['loginresponse']

def getKeys(hostname, loginresp, tmp_name):
    urlParam = '&response=json&id=' + loginresp['userid'] + '&sessionkey=' + encodeURIComponent(loginresp['sessionkey'])
    cmd = ['curl',
           '-v',
           '-H', 'Content-Type: application/json',
           '-b', tmp_name,
           '-X', 'POST',
           'http://' + hostname + ':8080/client/api/?command=listUsers' + urlParam]
    proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    (output, err) = proc.communicate()
    response = json.loads(output)
    logging.debug(response)
    user = response['listusersresponse']['user'][0]
    if not 'apikey' in user:
        return None
    return user['apikey'], user['secretkey']


def registerKeys(hostname, loginresp, tmp_name):
    urlParam = '&response=json&id=' + loginresp['userid'] + '&sessionkey=' + encodeURIComponent(loginresp['sessionkey'])
    cmd = ['curl',
           '-v',
           '-H', 'Content-Type: application/json',
           '-b', tmp_name,
           '-X', 'POST',
           'http://' + hostname + ':8080/client/api/?command=registerUserKeys' + urlParam]
    proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    (output, err) = proc.communicate()
    response = json.loads(output)
    logging.debug(response)
    return response

def getApiKey(hostname, username, password):
    tmp_cookie = tempfile.mkstemp(suffix=".cookie")
    tmp_name = tmp_cookie[1]
    loginresp = cloudLogin(hostname, username, password, tmp_name)
    if not loginresp:
        return None

    keypair = getKeys(hostname, loginresp, tmp_name)

    if not keypair:
        response = registerKeys(hostname, loginresp, tmp_name)
        keys = response['registeruserkeysresponse']
        if 'userkeys' in keys:
            keypair = keys['userkeys']['apikey'], keys['userkeys']['secretkey']

    os.remove(tmp_name)
    return keypair



Reply via email to