mirror of
				https://github.com/apache/cloudstack.git
				synced 2025-10-26 08:42:29 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			177 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			177 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			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 json
 | |
|     import os
 | |
|     import types
 | |
| 
 | |
|     from config import cache_file
 | |
| except ImportError, e:
 | |
|     import sys
 | |
|     print "ImportError", e
 | |
|     sys.exit(1)
 | |
| 
 | |
| 
 | |
| def getvalue(dictionary, key):
 | |
|     if key in dictionary:
 | |
|         return dictionary[key]
 | |
|     else:
 | |
|         return None
 | |
| 
 | |
| 
 | |
| def splitcsvstring(string):
 | |
|     if string is not None:
 | |
|         return filter(lambda x: x.strip() != '', string.split(','))
 | |
|     else:
 | |
|         return []
 | |
| 
 | |
| 
 | |
| def splitverbsubject(string):
 | |
|     idx = 0
 | |
|     for char in string:
 | |
|         if char.islower():
 | |
|             idx += 1
 | |
|         else:
 | |
|             break
 | |
|     return string[:idx].lower(), string[idx:].lower()
 | |
| 
 | |
| 
 | |
| def savecache(apicache, json_file):
 | |
|     """
 | |
|     Saves apicache dictionary as json_file, returns dictionary as indented str
 | |
|     """
 | |
|     if apicache is None or apicache is {}:
 | |
|         return ""
 | |
|     apicachestr = json.dumps(apicache, indent=2)
 | |
|     with open(json_file, 'w') as cache_file:
 | |
|         cache_file.write(apicachestr)
 | |
|     return apicachestr
 | |
| 
 | |
| 
 | |
| def loadcache(json_file):
 | |
|     """
 | |
|     Loads json file as dictionary, feeds it to monkeycache and spits result
 | |
|     """
 | |
|     f = open(json_file, 'r')
 | |
|     data = f.read()
 | |
|     f.close()
 | |
|     try:
 | |
|         apicache = json.loads(data)
 | |
|     except ValueError, e:
 | |
|         print "Error processing json:", json_file, e
 | |
|         return {}
 | |
|     return apicache
 | |
| 
 | |
| 
 | |
| def monkeycache(apis):
 | |
|     """
 | |
|     Feed this a dictionary of api bananas, it spits out processed cache
 | |
|     """
 | |
|     if isinstance(type(apis), types.NoneType) or apis is None:
 | |
|         return {}
 | |
| 
 | |
|     responsekey = filter(lambda x: 'response' in x, apis.keys())
 | |
| 
 | |
|     if len(responsekey) == 0:
 | |
|         print "[monkeycache] Invalid dictionary, has no response"
 | |
|         return None
 | |
|     if len(responsekey) != 1:
 | |
|         print "[monkeycache] Multiple responsekeys, chosing first one"
 | |
| 
 | |
|     responsekey = responsekey[0]
 | |
|     verbs = set()
 | |
|     cache = {}
 | |
|     cache['count'] = getvalue(apis[responsekey], 'count')
 | |
|     cache['asyncapis'] = []
 | |
| 
 | |
|     for api in getvalue(apis[responsekey], 'api'):
 | |
|         name = getvalue(api, 'name')
 | |
|         verb, subject = splitverbsubject(name)
 | |
| 
 | |
|         apidict = {}
 | |
|         apidict['name'] = name
 | |
|         apidict['description'] = getvalue(api, 'description')
 | |
|         apidict['isasync'] = getvalue(api, 'isasync')
 | |
|         if apidict['isasync']:
 | |
|             cache['asyncapis'].append(name)
 | |
|         apidict['related'] = splitcsvstring(getvalue(api, 'related'))
 | |
| 
 | |
|         required = []
 | |
|         apiparams = []
 | |
|         for param in getvalue(api, 'params'):
 | |
|             apiparam = {}
 | |
|             apiparam['name'] = getvalue(param, 'name')
 | |
|             apiparam['description'] = getvalue(param, 'description')
 | |
|             apiparam['required'] = (getvalue(param, 'required') is True)
 | |
|             apiparam['length'] = int(getvalue(param, 'length'))
 | |
|             apiparam['type'] = getvalue(param, 'type')
 | |
|             apiparam['related'] = splitcsvstring(getvalue(param, 'related'))
 | |
|             if apiparam['required']:
 | |
|                 required.append(apiparam['name'])
 | |
|             apiparams.append(apiparam)
 | |
| 
 | |
|         apidict['requiredparams'] = required
 | |
|         apidict['params'] = apiparams
 | |
|         if verb not in cache:
 | |
|             cache[verb] = {}
 | |
|         cache[verb][subject] = apidict
 | |
|         verbs.add(verb)
 | |
| 
 | |
|     cache['verbs'] = list(verbs)
 | |
|     return cache
 | |
| 
 | |
| 
 | |
| def main(json_file):
 | |
|     """
 | |
|     cachemaker.py creates a precache datastore of all available apis of
 | |
|     CloudStack and dumps the precache dictionary in an
 | |
|     importable python module. This way we cheat on the runtime overhead of
 | |
|     completing commands and help docs. This reduces the overall search and
 | |
|     cache_miss (computation) complexity from O(n) to O(1) for any valid cmd.
 | |
|     """
 | |
|     f = open("precache.py", "w")
 | |
|     f.write("""# -*- coding: utf-8 -*-
 | |
| # Auto-generated code by cachemaker.py
 | |
| # 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.""")
 | |
|     f.write("\napicache = %s" % loadcache(json_file))
 | |
|     f.close()
 | |
| 
 | |
| if __name__ == "__main__":
 | |
|     print "[cachemaker] Pre-caching using user's cloudmonkey cache", cache_file
 | |
|     if os.path.exists(cache_file):
 | |
|         main(cache_file)
 | |
|     else:
 | |
|         print "[cachemaker] Unable to cache apis, file not found", cache_file
 | |
|         print "[cachemaker] Run cloudmonkey sync to generate cache"
 |