On Aug 2, 2013, at 2:42 PM, Rohit Yadav wrote:
> On Thu, Aug 1, 2013 at 10:43 PM, Donal Lafferty
> <[email protected]>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