mirror of
				https://github.com/apache/cloudstack.git
				synced 2025-10-26 08:42:29 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			154 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			154 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| #!/usr/bin/python
 | |
| # -*- coding: utf-8 -*-
 | |
| # Licensed to the Apache Software Foundation (ASF) under one
 | |
| # or more contributor license agreements.  See the NOTICE file
 | |
| # distributed with this work for additional information
 | |
| # regarding copyright ownership.  The ASF licenses this file
 | |
| # to you under the Apache License, Version 2.0 (the
 | |
| # "License"); you may not use this file except in compliance
 | |
| # with the License.  You may obtain a copy of the License at
 | |
| #
 | |
| #   http://www.apache.org/licenses/LICENSE-2.0
 | |
| #
 | |
| # Unless required by applicable law or agreed to in writing,
 | |
| # software distributed under the License is distributed on an
 | |
| # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 | |
| # KIND, either express or implied.  See the License for the
 | |
| # specific language governing permissions and limitations
 | |
| # under the License.
 | |
| 
 | |
| try:
 | |
|     import base64
 | |
|     import hashlib
 | |
|     import hmac
 | |
|     import httplib
 | |
|     import json
 | |
|     import os
 | |
|     import pdb
 | |
|     import re
 | |
|     import shlex
 | |
|     import sys
 | |
|     import time
 | |
|     import types
 | |
|     import urllib
 | |
|     import urllib2
 | |
| 
 | |
| except ImportError, e:
 | |
|     print "Import error in %s : %s" % (__name__, e)
 | |
|     import sys
 | |
|     sys.exit()
 | |
| 
 | |
| 
 | |
| def logger_debug(logger, message):
 | |
|     if logger is not None:
 | |
|         logger.debug(message)
 | |
| 
 | |
| 
 | |
| def make_request(command, args, logger, host, port,
 | |
|                  apikey, secretkey, protocol, path):
 | |
|     response = None
 | |
|     error = None
 | |
| 
 | |
|     if protocol != 'http' and protocol != 'https':
 | |
|         error = "Protocol must be 'http' or 'https'"
 | |
|         return None, error
 | |
| 
 | |
|     if args is None:
 | |
|         args = {}
 | |
| 
 | |
|     args["command"] = command
 | |
|     args["apiKey"] = apikey
 | |
|     args["response"] = "json"
 | |
|     request = zip(args.keys(), args.values())
 | |
|     request.sort(key=lambda x: x[0].lower())
 | |
| 
 | |
|     request_url = "&".join(["=".join([r[0], urllib.quote_plus(str(r[1]))])
 | |
|                            for r in request])
 | |
|     hashStr = "&".join(["=".join([r[0].lower(),
 | |
|                        str.lower(urllib.quote_plus(str(r[1]))).replace("+",
 | |
|                        "%20")]) for r in request])
 | |
| 
 | |
|     sig = urllib.quote_plus(base64.encodestring(hmac.new(secretkey, hashStr,
 | |
|                             hashlib.sha1).digest()).strip())
 | |
|     request_url += "&signature=%s" % sig
 | |
|     request_url = "%s://%s:%s%s?%s" % (protocol, host, port, path, request_url)
 | |
| 
 | |
|     try:
 | |
|         logger_debug(logger, "Request sent: %s" % request_url)
 | |
|         connection = urllib2.urlopen(request_url)
 | |
|         response = connection.read()
 | |
|     except Exception, e:
 | |
|         error = str(e)
 | |
| 
 | |
|     logger_debug(logger, "Response received: %s" % response)
 | |
|     if error is not None:
 | |
|         logger_debug(logger, error)
 | |
| 
 | |
|     return response, error
 | |
| 
 | |
| 
 | |
| def monkeyrequest(command, args, isasync, asyncblock, logger, host, port,
 | |
|                   apikey, secretkey, timeout, protocol, path):
 | |
| 
 | |
|     response = None
 | |
|     error = None
 | |
|     logger_debug(logger, "======== START Request ========")
 | |
|     logger_debug(logger, "Requesting command=%s, args=%s" % (command, args))
 | |
|     response, error = make_request(command, args, logger, host, port,
 | |
|                                    apikey, secretkey, protocol, path)
 | |
|     logger_debug(logger, "======== END Request ========\n")
 | |
| 
 | |
|     if error is not None:
 | |
|         return response, error
 | |
| 
 | |
|     def process_json(response):
 | |
|         try:
 | |
|             response = json.loads(str(response))
 | |
|         except ValueError, e:
 | |
|             error = "Error processing json response, %s" % e
 | |
|             logger_debug(logger, "Error processing json", e)
 | |
|         return response
 | |
| 
 | |
|     response = process_json(response)
 | |
|     if response is None:
 | |
|         return response, error
 | |
| 
 | |
|     isasync = isasync and (asyncblock == "true")
 | |
|     responsekey = filter(lambda x: 'response' in x, response.keys())[0]
 | |
| 
 | |
|     if isasync and 'jobid' in response[responsekey]:
 | |
|         jobid = response[responsekey]['jobid']
 | |
|         command = "queryAsyncJobResult"
 | |
|         request = {'jobid': jobid}
 | |
|         timeout = int(timeout)
 | |
|         pollperiod = 3
 | |
|         progress = 1
 | |
|         while timeout > 0:
 | |
|             print '\r' + '.' * progress,
 | |
|             time.sleep(pollperiod)
 | |
|             timeout = timeout - pollperiod
 | |
|             progress += 1
 | |
|             logger_debug(logger, "Job %s to timeout in %ds" % (jobid, timeout))
 | |
|             sys.stdout.flush()
 | |
|             response, error = monkeyrequest(command, request, isasync,
 | |
|                                             asyncblock, logger,
 | |
|                                             host, port,  apikey, secretkey,
 | |
|                                             timeout, protocol, path)
 | |
|             response = process_json(response)
 | |
|             responsekeys = filter(lambda x: 'response' in x, response.keys())
 | |
|             if len(responsekeys) < 1:
 | |
|                 continue
 | |
|             result = response[responsekeys[0]]
 | |
|             jobstatus = result['jobstatus']
 | |
|             if jobstatus == 2:
 | |
|                 jobresult = result["jobresult"]
 | |
|                 error = "\rAsync job %s failed\nError %s, %s" % (jobid,
 | |
|                         jobresult["errorcode"], jobresult["errortext"])
 | |
|                 return response, error
 | |
|             elif jobstatus == 1:
 | |
|                 print '\r',
 | |
|                 return response, error
 | |
|         error = "Error: Async query timeout occurred for jobid %s" % jobid
 | |
| 
 | |
|     return response, error
 |