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