1# VMware vSphere Python SDK 2# Copyright (c) 2008-2015 VMware, Inc. All Rights Reserved. 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15 16""" 17This module is a converter from dynamic type to pyVmomi type 18""" 19__author__ = "VMware, Inc." 20 21from pyVmomi import VmomiSupport, vmodl 22from Cache import Cache 23 24## Dynamic type importer 25# 26class DynamicTypeImporter: 27 """ Dynamic type importer """ 28 29 ## Constructor 30 # 31 # @param stub Server stub 32 def __init__(self, stub, hostSystem=None): 33 self.stub = stub 34 self.hostSystem = hostSystem 35 36 ## Get dynamic type manager 37 # 38 # @return moRef to dynamic type manager 39 @Cache 40 def GetTypeManager(self): 41 """ Get dynamic type manager """ 42 dynTypeMgr = None 43 if self.hostSystem: 44 try: 45 dynTypeMgr = self.hostSystem.RetrieveDynamicTypeManager() 46 except vmodl.fault.MethodNotFound as err: 47 pass 48 49 if not dynTypeMgr: 50 # Older host not support RetrieveDynamicTypeManager 51 cmdlineTypesMoId = "ha-dynamic-type-manager" 52 dynTypeMgr = vmodl.reflect.DynamicTypeManager(cmdlineTypesMoId, 53 self.stub) 54 return dynTypeMgr 55 56 ## Import dynamic types 57 # 58 # @param prefix Only types with the specified prefix are imported 59 # @return dynamic types 60 @Cache 61 def ImportTypes(self, prefix=''): 62 """ Build dynamic types """ 63 # Use QueryTypeInfo to get all types 64 dynTypeMgr = self.GetTypeManager() 65 filterSpec = None 66 if prefix != '': 67 filterSpec = vmodl.reflect.DynamicTypeManager.TypeFilterSpec( 68 typeSubstr=prefix) 69 allTypes = dynTypeMgr.QueryTypeInfo(filterSpec) 70 71 ## Convert dynamic types to pyVmomi types 72 # 73 DynamicTypeConstructor().CreateTypes(allTypes) 74 return allTypes 75 76 77## Construct pyVmomi types from dynamic types definition 78# 79class DynamicTypeConstructor: 80 """ Dynamic type constructor """ 81 82 _mapFlags = { "optional": VmomiSupport.F_OPTIONAL, 83 "linkable": VmomiSupport.F_LINKABLE, 84 "link": VmomiSupport.F_LINK, 85 "secret": VmomiSupport.F_SECRET } 86 87 ## Constructor 88 # 89 def __init__(self): 90 """ Constructor """ 91 pass 92 93 ## Create pyVmomi types from vmodl.reflect.DynamicTypeManager.AllTypeInfo 94 # 95 # @param allTypes vmodl.reflect.DynamicTypeManager.AllTypeInfo 96 def CreateTypes(self, allTypes): 97 """ 98 Create pyVmomi types from vmodl.reflect.DynamicTypeManager.AllTypeInfo 99 """ 100 enumTypes, dataTypes, managedTypes = self._ConvertAllTypes(allTypes) 101 self._CreateAllTypes(enumTypes, dataTypes, managedTypes) 102 103 ## Convert all dynamic types to pyVmomi type definitions 104 # 105 # @param allTypes vmodl.reflect.DynamicTypeManager.AllTypeInfo 106 # @return a tuple of (enumTypes, dataTypes, managedTypes) 107 def _ConvertAllTypes(self, allTypes): 108 """ Convert all dynamic types to pyVmomi type definitions """ 109 # Generate lists good for VmomiSupport.CreateXYZType 110 enumTypes = self._Filter(self._ConvertEnumType, allTypes.enumTypeInfo) 111 dataTypes = self._Filter(self._ConvertDataType, allTypes.dataTypeInfo) 112 managedTypes = self._Filter(self._ConvertManagedType, 113 allTypes.managedTypeInfo) 114 retAllTypes = (enumTypes, dataTypes, managedTypes) 115 return retAllTypes 116 117 ## Create pyVmomi types from pyVmomi type definitions 118 # 119 # @param enumTypes pyVmomi enum type definitions 120 # @param dataTypes pyVmomi data type definitions 121 # @param managedTypes pyVmomi managed type definitions 122 def _CreateAllTypes(self, enumTypes, dataTypes, managedTypes): 123 """ Create pyVmomi types from pyVmomi type definitions """ 124 125 # Create versions 126 for typeInfo in managedTypes: 127 name = typeInfo[0] 128 version = typeInfo[3] 129 VmomiSupport.AddVersion(version, '', '1.0', 0, name) 130 VmomiSupport.AddVersionParent(version, 'vmodl.version.version0') 131 VmomiSupport.AddVersionParent(version, 'vmodl.version.version1') 132 VmomiSupport.AddVersionParent(version, version) 133 134 # Create partial types 135 for fn, infos in (VmomiSupport.CreateEnumType, enumTypes), \ 136 (VmomiSupport.CreateDataType, dataTypes), \ 137 (VmomiSupport.CreateManagedType, managedTypes): 138 for typeInfo in infos: 139 try: 140 fn(*typeInfo) 141 except Exception as err: 142 #Ignore errors due to duplicate importing 143 pass 144 145 def _ConvertAnnotations(self, annotations): 146 """ Convert annotations to pyVmomi flags """ 147 flags = 0 148 if annotations: 149 for annotation in annotations: 150 flags |= self._mapFlags.get(annotation.name, 0) 151 return flags 152 153 @staticmethod 154 def _Filter(fn, types): 155 """ Call fn for each non null element in types. Similiar to filter """ 156 if types: 157 return [fn(prop) for prop in types if prop is not None] 158 else: 159 return [] 160 161 def _ConvertParamType(self, paramType): 162 """ 163 Convert vmodl.reflect.DynamicTypeManager.ParamTypeInfo to pyVmomi param 164 definition 165 """ 166 if paramType: 167 name = paramType.name 168 version = paramType.version 169 aType = paramType.type 170 flags = self._ConvertAnnotations(paramType.annotation) 171 privId = paramType.privId 172 param = (name, aType, version, flags, privId) 173 else: 174 param = None 175 return param 176 177 def _ConvertMethodType(self, methodType): 178 """ 179 Convert vmodl.reflect.DynamicTypeManager.MethodTypeInfo to pyVmomi method 180 definition 181 """ 182 if methodType: 183 name = methodType.name 184 wsdlName = methodType.wsdlName 185 version = methodType.version 186 params = self._Filter(self._ConvertParamType, methodType.paramTypeInfo) 187 privId = methodType.privId 188 faults = methodType.fault 189 190 # Figure out reture info 191 if methodType.returnTypeInfo: 192 returnTypeInfo = methodType.returnTypeInfo 193 retFlags = self._ConvertAnnotations(returnTypeInfo.annotation) 194 methodRetType = returnTypeInfo.type 195 else: 196 retFlags = 0 197 methodRetType = "void" 198 if wsdlName.endswith("_Task"): 199 # TODO: Need a seperate task return type for task, instead of 200 # hardcode vim.Task as return type 201 retType = "vim.Task" 202 else: 203 retType = methodRetType 204 retInfo = (retFlags, retType, methodRetType) 205 206 method = (name, wsdlName, version, params, retInfo, privId, faults) 207 else: 208 method = None 209 return method 210 211 def _ConvertManagedPropertyType(self, propType): 212 """ 213 Convert vmodl.reflect.DynamicTypeManager.PropertyTypeInfo to pyVmomi 214 managed property definition 215 """ 216 if propType: 217 name = propType.name 218 version = propType.version 219 aType = propType.type 220 flags = self._ConvertAnnotations(propType.annotation) 221 privId = propType.privId 222 prop = (name, aType, version, flags, privId) 223 else: 224 prop = None 225 return prop 226 227 def _ConvertManagedType(self, managedType): 228 """ 229 Convert vmodl.reflect.DynamicTypeManager.ManagedTypeInfo to pyVmomi 230 managed type definition 231 """ 232 if managedType: 233 vmodlName = managedType.name 234 wsdlName = managedType.wsdlName 235 version = managedType.version 236 parent = managedType.base[0] 237 props = self._Filter(self._ConvertManagedPropertyType, managedType.property) 238 methods = self._Filter(self._ConvertMethodType, managedType.method) 239 moType = (vmodlName, wsdlName, parent, version, props, methods) 240 else: 241 moType = None 242 return moType 243 244 def _ConvertDataPropertyType(self, propType): 245 """ 246 Convert vmodl.reflect.DynamicTypeManager.PropertyTypeInfo to pyVmomi 247 data property definition 248 """ 249 if propType: 250 name = propType.name 251 version = propType.version 252 aType = propType.type 253 flags = self._ConvertAnnotations(propType.annotation) 254 prop = (name, aType, version, flags) 255 else: 256 prop = None 257 return prop 258 259 def _ConvertDataType(self, dataType): 260 """ 261 Convert vmodl.reflect.DynamicTypeManager.DataTypeInfo to pyVmomi data 262 type definition 263 """ 264 if dataType: 265 vmodlName = dataType.name 266 wsdlName = dataType.wsdlName 267 version = dataType.version 268 parent = dataType.base[0] 269 props = self._Filter(self._ConvertDataPropertyType, dataType.property) 270 doType = (vmodlName, wsdlName, parent, version, props) 271 else: 272 doType = None 273 return doType 274 275 def _ConvertEnumType(self, enumType): 276 """ 277 Convert vmodl.reflect.DynamicTypeManager.EnumTypeInfo to pyVmomi enum 278 type definition 279 """ 280 if enumType: 281 vmodlName = enumType.name 282 wsdlName = enumType.wsdlName 283 version = enumType.version 284 values = enumType.value 285 enumType = (vmodlName, wsdlName, version, values) 286 else: 287 enumType = None 288 return enumType 289 290