Module wmiutils
[hide private]

Source Code for Module wmiutils

  1  #coding=utf-8 
  2  """ 
  3  This module provides a set of tools to access Common Information Model (CIM) classes 
  4  through Windows Management Instrumentation (WMI). 
  5   
  6  WMI API can be accessed by various protocols such as 
  7  * Windows shell -- by using 'wmic' command line tool 
  8  * WMI protocol -- WMI natively provides remote connection capabilities 
  9  * PowerShell -- PowerShell 2.0 also provides an access to WMI and remote connection capabilities 
 10   
 11  This module provides a set of classes which are created on top of Universal Discovery clients and provide unified interface to access CIM. 
 12  That said, the code which uses this module is totally detached from the underlying protocol. 
 13  """ 
 14  import logger 
 15  import shellutils 
 16  import re 
 17   
 18  from java.util import Comparator 
 19  from java.util import TreeSet 
 20  from java.util import Random 
 21  from java.lang import System 
 22  from java.lang import Long 
 23  from java.lang import Exception as JavaException 
 24   
 25  from appilog.common.system.types import ObjectStateHolder 
 26  from appilog.common.system.types import AttributeStateHolder 
 27  #from appilog.common.system.types.vectors import ObjectStateHolderVector 
 28   
 29  from com.hp.ucmdb.discovery.library.communication.downloader.cfgfiles import GeneralSettingsConfigFile 
 30   
31 -class Converter:
32 """ 33 This class is a base abstract class for converters. 34 Converters are used to transform values obtained from CIM. 35 @deprecated: This class is deprecated 36 """
37 - def convert(self, originalValue):
38 raise ValueError, 'Not implemented'
39
40 -class NoopConverter(Converter):
41 """ 42 This is a default converter which does just nothing. 43 @deprecated: This class is deprecated 44 """
45 - def convert(self, originalValue):
46 return originalValue
47 48 "Instance of the default 'no operation' (NOOP) converter. This API is deprecated" 49 NOOP_CONVERTER = NoopConverter() 50
51 -class ByMapConverter(Converter):
52 """ 53 This converter considers value obtained from CIM as a key in the dictionary. 54 @deprecated: This class is deprecated 55 """
56 - def __init__(self, map):
57 self.map = map
58
59 - def convert(self, originalValue):
60 """ 61 Returns value from the dictionary corresponding to 'originalValue' key 62 @raise UnmapperValueException: if there is no value registered for passed key. 63 """ 64 if self.map.has_key(originalValue): 65 return self.map[originalValue] 66 else: 67 raise UnmappedValueException, originalValue
68
69 -class ByFunctionConverter(Converter):
70 """ 71 This converter allows making conversion by custom function. 72 For example if it is required to parse out a part of the string by some regular expression. 73 @deprecated: This class is deprecated 74 """
75 - def __init__(self, function):
76 """ 77 @param function: callable object which will do actual conversion. 78 """ 79 self.function = function
80
81 - def convert(self, originalValue):
82 """ 83 Converts provided value by function passed to converter constructor. 84 This method does not make any special exception handling. It just invokes conversion function. 85 """ 86 return self.function(originalValue)
87
88 -class ResultItem:
89 """ 90 This is a stub class used for result objects. 91 All properties are added here dynamically at runtime. 92 @see: WmiQueryBuilder.parseResults 93 """ 94 pass
95
96 -class ColumnNameBasedComparator(Comparator):
97 """ 98 This class is used to sort queried properties names. 99 Sorting is important because it allows to specify queried class properties in arbitrary order. 100 """
101 - def compare(self, element1, element2):
102 return cmp(element1.columnName, element2.columnName)
103
104 -class QueryElement:
105 """ 106 This class represents queried CIM class property 107 """
108 - def __init__(self, columnName, attributeName, type):
109 """ 110 @param columnName: The name of the queried property 111 @param attributeName: deprecated 112 @type type: deprecated 113 """ 114 self.columnName = columnName 115 self.attributeName = attributeName 116 self.type = type
117 118
119 -class BaseWmiQueryBuilder:
120 """ 121 This is a base class for all QueryBuilders. 122 QueryBuilder is a class which provides single 123 interface to compose WMI query regardless to the underlying protocol 124 """
125 - def __init__(self, objectName):
126 "@param objectName: the name of the queried CIM class" 127 self.queryElements = TreeSet(ColumnNameBasedComparator()) 128 self.objectName = objectName 129 self.whereClause = None
130
131 - def addQueryElement(self, columnName, attributeName = None, type = 'string'):
132 """ 133 @deprecated: This method should not be used by clients 134 @see: addWmiObjectProperties method instead 135 """ 136 if not attributeName: 137 attributeName = columnName 138 queryElement = QueryElement(columnName, attributeName, type) 139 self.queryElements.add(queryElement)
140
141 - def addWmiObjectProperties(self, *columnNames):
142 """ 143 @types: *str -> BaseWmiQueryBuilder 144 @param columnNames: the list of the names of the queried properties, order of properties if not important. 145 """ 146 for columnName in columnNames: 147 self.addQueryElement(columnName) 148 return self
149
150 - def addWhereClause(self, whereClause):
151 """ 152 This method allows to add 'WHERE' clause to the WMI query 153 @types: str -> None 154 """ 155 self.whereClause = whereClause
156
157 - def buildQuery(self):
158 """ 159 Abstract method for query buidling 160 """ 161 raise NotImplemented, "buildQuery"
162
163 - def parseResults(self, resultSet):
164 """ 165 Abstract method for results parsing 166 """ 167 raise NotImplemented, "parseResults"
168
169 - def getObjectName(self):
170 """ 171 Returns queried CIM class name 172 """ 173 return self.objectName
174
175 -class WmiQueryBuilder(BaseWmiQueryBuilder):
176 """ 177 This class represents QueryBuilder for WMI protocol. 178 """ 179 180 WMI_QUERY_TEMPLATE = 'SELECT %s FROM %s' 181
182 - def __init__(self, objectName):
183 BaseWmiQueryBuilder.__init__(self, objectName)
184
185 - def buildQuery(self):
186 """ 187 This method builds WMI query using the following template: 188 SELECT property [, property ...] FROM objectName [WHERE whereClause] 189 """ 190 COMMA = ', ' 191 columnNamesList = [element.columnName for element in self.queryElements if element.columnName] 192 columnNames = COMMA.join(columnNamesList) 193 194 wmiQuery = self.WMI_QUERY_TEMPLATE % (columnNames, self.objectName) 195 196 if self.whereClause: 197 wmiQuery += ' WHERE ' + self.whereClause 198 199 return wmiQuery
200
201 - def parseResults(self, resultSet):
202 """ 203 resultSet -> list(ResultItem) 204 This method forms the result of WMI query. The result is a list of objects of type ResultItem 205 with dynamically added properties corresponding to the queried properties names. 206 """ 207 resultItems = [] 208 table = resultSet.asTable() 209 210 for rowIndex in range(len(table)): 211 columnIndex = 0 212 resultItem = ResultItem() 213 iterator = self.queryElements.iterator() 214 while iterator.hasNext(): 215 queryElement = iterator.next() 216 name = queryElement.attributeName 217 setattr(resultItem, name, table[rowIndex][columnIndex]) 218 columnIndex += 1 219 resultItems.append(resultItem) 220 221 return resultItems
222 223
224 -class WmicQueryBuilder(BaseWmiQueryBuilder):
225 """ 226 This class forms WMI query to be executed by 'wmic' command line tool 227 """ 228 229 WMIC_QUERY_TEMPLATE = 'wmic %(output)s%(namespace)s%(path)s%(object)s%(where)s get %(properties)s /value < %%SystemRoot%%\\win.ini' 230
231 - def __init__(self, objectName):
232 BaseWmiQueryBuilder.__init__(self, objectName) 233 self._keyAttributesLowerCase = [] 234 self.__outputFile = None 235 self.__usePathCommand = 0 236 self._namespace = None 237 self._splitListOutput = None
238
239 - def setOutputFile(self, outputFile):
240 self.__outputFile = outputFile
241
242 - def usePathCommand(self, value):
243 self.__usePathCommand = value
244
245 - def setNamespace(self, namespace):
246 """ 247 Sets queried object namespace 248 @types: str -> void 249 """ 250 if namespace: 251 self._namespace = namespace
252
253 - def useSplitListOutput(self, value):
254 self._splitListOutput = value
255
256 - def buildQuery(self):
257 """ 258 Builds wmic query using template: 259 wmic %(output)s%(namespace)s%(path)s%(object)s%(where)s get %(properties)s /value < %%SystemRoot%%\\win.ini 260 """ 261 262 queryParameters = {} 263 264 queryParameters['output'] = self.__outputFile and '/output:"%s" ' % self.__outputFile or '' 265 266 queryParameters['namespace'] = self._namespace and '/namespace:%s ' % self._namespace or '' 267 268 queryParameters['path'] = self.__usePathCommand and 'path ' or '' 269 270 queryParameters['object'] = self.objectName 271 272 queryParameters['where'] = self.whereClause and ' where "%s"' % self.whereClause or '' 273 274 COMMA = ', ' 275 columnNamesList = [element.columnName for element in self.queryElements if element.columnName] 276 columnNames = COMMA.join(columnNamesList) 277 self._keyAttributesLowerCase += [name.lower() for name in columnNamesList] 278 279 queryParameters['properties'] = columnNames 280 281 return self.WMIC_QUERY_TEMPLATE % queryParameters
282
283 - def __isListType(self, fieldValue):
284 if fieldValue and re.match("\s*\{.*\}\s*", fieldValue): 285 return 1
286
287 - def __parseAsList(self, fieldValue):
288 resultList = [] 289 if fieldValue: 290 resultList = re.split('[\,\"]+', fieldValue.replace('{', '').replace('}', '')) 291 return map(lambda elem: elem.strip(), resultList)
292
293 - def parseResults(self, output, separator = '='):
294 resultItems = [] 295 #get first start token of each output part 296 output = output.strip() 297 firstToken = output[0:output.find(separator)] 298 #restore wmicOutput for correct split 299 output = '\n%s' % output 300 #process each user fragment 301 for fragment in output.split('\n%s%s' % (firstToken, separator)): 302 if not fragment: continue 303 attributes = {} 304 previousKey = None 305 #gather information 306 for line in (('%s%s%s' % (firstToken, separator, fragment)).strip().split('\n')): 307 keyIndex = line.find(separator) 308 key = line[0:keyIndex].lower().strip() 309 if keyIndex == -1 or key not in self._keyAttributesLowerCase: 310 if previousKey: 311 attributes[previousKey] += line and line.strip() 312 else: 313 value = line[keyIndex + 1:] 314 attributes[key] = value and value.strip() 315 previousKey = key 316 #create resulting items 317 if not attributes: continue 318 resultItem = ResultItem() 319 iterator = self.queryElements.iterator() 320 while iterator.hasNext(): 321 queryElement = iterator.next() 322 name = queryElement.attributeName 323 columnName = queryElement.columnName.lower() 324 value = attributes.get(columnName) 325 value = value and value.strip() 326 if self._splitListOutput and self.__isListType(value): 327 value = self.__parseAsList(value) 328 setattr(resultItem, name, value) 329 resultItems.append(resultItem) 330 return resultItems
331
332 -class PowerShelWmilQueryBuilder(WmicQueryBuilder):
333 ''' PowerShell specific query builder. It uses PowerShell native WMI command line calls. 334 Added some fake methods in order to provide compatibility and abstraction layer from the exact call methods of shell WmicQueryBuilder 335 ''' 336 QUERY_TEMPLATE = 'Get-WmiObject %(namespace)s -Query "SELECT %(properties)s FROM %(object)s %(where)s" | Format-List %(properties)s'
337 - def __init__(self, objectName):
338 WmicQueryBuilder.__init__(self, objectName)
339
340 - def setOutputFile(self, outputFile):
341 logger.warn("Intermediate file is not supported in WMI by PowerShell")
342
343 - def usePathCommand(self, value):
344 logger.warn("WMI class names supported only. No aliases")
345
346 - def setNamespace(self, namespace):
347 if namespace: 348 self._namespace = namespace
349
350 - def useSplitListOutput(self, value):
351 self._splitListOutput = value
352
353 - def buildQuery(self):
354 355 queryParameters = {} 356 357 queryParameters['namespace'] = self._namespace and '-Namespace "%s" ' % self._namespace or '' 358 359 queryParameters['object'] = self.objectName 360 361 queryParameters['where'] = self.whereClause and ' WHERE %s' % self.whereClause.replace('"', "'") or '' 362 363 COMMA = ', ' 364 columnNamesList = [element.columnName for element in self.queryElements if element.columnName] 365 columnNames = COMMA.join(columnNamesList) 366 self._keyAttributesLowerCase += [name.lower() for name in columnNamesList] 367 368 queryParameters['properties'] = columnNames 369 370 return self.QUERY_TEMPLATE % queryParameters
371
372 -class _Agent:
373 """Base class for WMI agent""" 374
375 - def getWmiData(self, queryBuilder, timeout = 0):
376 '@types: BaseWmiQueryBuilder, int -> list(ResultItem)' 377 raise NotImplemented
378
379 - def executeWmiQuery(self, queryBuilder, timeout = 0):
380 raise NotImplemented
381
382 - def close(self):
383 raise NotImplemented
384 385
386 -class WmiAgent(_Agent):
387 'Agent wraps WMI agent'
388 - def __init__(self, wmiClient, Framework = None):
389 self.wmiClient = wmiClient
390
391 - def getWmiData(self, queryBuilder, timeout = 0):
392 '''@types: WmiQueryBuilder, int -> list(ResultItem) 393 @param timeout: parameter is not used, provided only for unique interface with WmicAgent 394 ''' 395 if timeout: 396 logger.warn("Specified timeout for query by WMI protocol has no effect as it is not supported by client") 397 query = queryBuilder.buildQuery() 398 resultSet = self.wmiClient.executeQuery(query)#@@CMD_PERMISION wmi protocol execution 399 return queryBuilder.parseResults(resultSet)
400
401 - def close(self):
402 self.wmiClient.close()
403 404
405 -class WmicAgent(_Agent):
406 """ 407 This class wraps WMI client to provide an interface to run WMI queries. 408 """ 409 410 __PROPERTY_NAME_USE_INTERMEDIATE_FILE = 'useIntermediateFileForWmic' 411 __DEFAULT_REMOTE_TEMP_SHARE = "admin$\\Temp" 412 __DEFAULT_REMOTE_INTERNAL_TEMP_PATH = "%SystemRoot%\\Temp" 413 __WMIC_OUTPUT_ENCODING = "utf-16" 414
415 - def __init__(self, shell):
416 '@types: Shell -> None' 417 self.shell = shell 418 globalSettings = GeneralSettingsConfigFile.getInstance() 419 self.useIntermediateFile = globalSettings.getPropertyBooleanValue(WmicAgent.__PROPERTY_NAME_USE_INTERMEDIATE_FILE, 0)
420
421 - def getWmiData(self, queryBuilder, timeout = 0):
422 """ 423 @types: WmiQueryBuilder, int -> list(ResultItem) 424 @param timeout: parameter is not used, provided only for unique interface with WmicAgent 425 """ 426 output = None 427 if self.useIntermediateFile: 428 output = self.getWmiDataWithIntermediateFile(queryBuilder, timeout) 429 else: 430 output = self.executeWmiQuery(queryBuilder, timeout) 431 return queryBuilder.parseResults(output)
432
433 - def executeWmiQuery(self, queryBuilder, timeout = 0):
434 """ Execute query and return raw string output 435 @types: WmicQueryBuilder[, int = 0] -> str 436 @raise ValueError: if WMIC query execution failed 437 """ 438 query = queryBuilder.buildQuery() 439 result = self.shell.execCmd(query, timeout)#@@CMD_PERMISION wmi protocol execution 440 errorCode = self.shell.getLastCmdReturnCode() 441 if errorCode: 442 raise ValueError, "Wmic query execution failed. %s Error code %s" % (result, errorCode) 443 return result
444
445 - def getWmiDataWithIntermediateFile(self, queryBuilder, timeout = 0):
446 """ Execute built query and redirect output to intermediate file on destination, 447 copy file from remote and read output. 448 @types: WmicQueryBuilder[, int] -> str 449 @raise Exception: WMI query failed 450 @raise ValueError: file operation failed 451 """ 452 id = self.__generateUniqueId() 453 objectName = queryBuilder.getObjectName() 454 intermediateFileName = "_".join([id, objectName]) 455 456 remoteShareDir = WmicAgent.__DEFAULT_REMOTE_TEMP_SHARE 457 remoteInternalDir = WmicAgent.__DEFAULT_REMOTE_INTERNAL_TEMP_PATH 458 fullRemoteShareDir = "\\".join((remoteShareDir, id)) 459 fullRemoteInternalDir = "\\".join((remoteInternalDir, id)) 460 fullIntermediateInternalFilePath = "\\".join((fullRemoteInternalDir, intermediateFileName)) 461 462 self.shell.createDirectoryViaShellCommand(fullRemoteInternalDir) 463 queryBuilder.setOutputFile(fullIntermediateInternalFilePath) 464 465 try: 466 self.executeWmiQuery(queryBuilder, timeout) 467 except (Exception, JavaException), e: 468 self.__cleanRemoteIntermediateFiles(intermediateFileName, fullRemoteShareDir, fullRemoteInternalDir) 469 raise e 470 471 localIntermediateFile = None 472 try: 473 localIntermediateFile = self.shell.copyFileFromRemoteShare(intermediateFileName, fullRemoteShareDir) 474 if not localIntermediateFile: 475 raise ValueError, "Failed copying remote file '%s' from share '%s'" % (intermediateFileName, fullRemoteShareDir) 476 finally: 477 self.__cleanRemoteIntermediateFiles(intermediateFileName, fullRemoteShareDir, fullRemoteInternalDir) 478 479 buffer = None 480 try: 481 buffer = shellutils.readLocalFile(localIntermediateFile, WmicAgent.__WMIC_OUTPUT_ENCODING) 482 if buffer is not None: 483 return buffer 484 else: 485 raise ValueError, "Failed reading local file '%s'" % localIntermediateFile 486 finally: 487 shellutils.deleteLocalFile(localIntermediateFile)
488
489 - def __generateUniqueId(self):
490 random = Random().nextLong() 491 systime = System.currentTimeMillis() 492 return Long.toHexString( random ^ systime )
493
494 - def __cleanRemoteIntermediateFiles(self, fileName, remoteShareDir, remoteInternalDir):
495 '@types: str, str, str -> None' 496 try: 497 self.shell.deleteRemoteFileFromShare(fileName, remoteShareDir) 498 except: 499 logger.warn("Failed to delete temporary file '%s' from '%s'" % (fileName, remoteShareDir)) 500 try: 501 self.shell.deleteDirectoryViaShellCommand(remoteInternalDir) 502 except: 503 logger.warn("Failed to delete temporary folder '%s'" % remoteInternalDir)
504
505 - def close(self):
506 self.shell.closeClient()
507
508 -class WmiPowerShellAgent(_Agent):
509 - def __init__(self, shell):
510 '@types: shellutils.PowerShell -> None' 511 self.shell = shell
512
513 - def getWmiData(self, queryBuilder, timeout = 0):
514 output = self.executeWmiQuery(queryBuilder, timeout) 515 return queryBuilder.parseResults(output, ':')
516
517 - def executeWmiQuery(self, queryBuilder, timeout = 0):
518 """ Execute query and return raw string output 519 @types: PowerShelWmilQueryBuilder[, int = 0] -> str 520 @raise ValueError: if query execution failed 521 """ 522 query = queryBuilder.buildQuery() 523 output = self.shell.execCmd(query, timeout)#@@CMD_PERMISION wmi protocol execution 524 errorCode = self.shell.getLastCmdReturnCode() 525 if errorCode != 0: 526 raise ValueError, "Powershell WMI query execution failed. %s Error code %s" % (output, errorCode) 527 return output
528
529 - def close(self):
530 self.shell.closeClient()
531 532
533 -class WmiAgentProvider:
534 'Provides access to WMI using WMI agent'
535 - def __init__(self, wmiClient):
536 'WMI agent' 537 self.__agent = WmiAgent(wmiClient)
538
539 - def getAgent(self):
540 '@types: -> WmiAgent' 541 return self.__agent
542
543 - def getBuilder(self, className):
544 '@types: str, str -> WmiQueryBuilder' 545 return WmiQueryBuilder(className)
546
547 -class WmicProvider(WmiAgentProvider):
548 - def __init__(self, shell):
549 self.__agent = WmicAgent(shell)
550
551 - def getAgent(self):
552 '@types: -> WmicAgent' 553 return self.__agent
554
555 - def getBuilder(self, className):
556 '@types: str-> WmicQueryBuilder' 557 builder = WmicQueryBuilder(className) 558 builder.usePathCommand(1) 559 builder.useSplitListOutput(1) 560 return builder
561
562 -class PowerShellWmiProvider(WmiAgentProvider):
563 'Provides access to WMI using powershell commands'
564 - def __init__(self, shell):
565 self.__agent = WmiPowerShellAgent(shell)
566
567 - def getAgent(self):
568 '@types: -> WmiPowerShellAgent or WmicAgent' 569 return self.__agent
570
571 - def getBuilder(self, className):
572 '@types: str, str -> PowerShelWmilQueryBuilder' 573 builder = PowerShelWmilQueryBuilder(className) 574 builder.useSplitListOutput(1) 575 return builder
576
577 -def getWmiProvider(client):
578 """ 579 This method returns Provider to work with WMI. 580 @rtype: WmiAgentProvider 581 @param client: row client. Supported client types: Windows shell, PowerShell, WMI 582 @raise ValueError: if there is no WMI provider implemented for client 583 """ 584 clientType = client.getClientType() 585 if clientType == 'wmi': 586 return WmiAgentProvider(client) 587 if (clientType == 'ntadmin') or (clientType == 'ssh') or (clientType == 'uda'): 588 return WmicProvider(client) 589 if clientType == 'powershell': 590 return PowerShellWmiProvider(client) 591 raise ValueError, 'No WMI provider for client type: %s' % clientType
592
593 -class AttributeMapping:
594 """ 595 @deprecated: 596 """
597 - def __init__(self, attributeName, sourceAttributeName, type, converter):
598 self.attributeName = attributeName 599 600 if sourceAttributeName: 601 self.sourceAttributeName = sourceAttributeName 602 else: 603 self.sourceAttributeName = attributeName 604 605 self.type = type 606 self.converter = converter
607
608 - def setAttribute(self, osh, sourceElement):
609 sourceValue = getattr(sourceElement, self.sourceAttributeName) 610 611 try: 612 convertedValue = self.converter.convert(sourceValue) 613 except ConversionException: 614 raise AttributeMappingException, self.attributeName 615 616 osh.setAttribute(AttributeStateHolder(self.attributeName, convertedValue, self.type))
617
618 -class OshMapping:
619 """ 620 @deprecated: 621 """
622 - def __init__(self, oshName):
623 self.oshName = oshName 624 self.attributeMappings = []
625
626 - def defineMapping(self, attributeName, sourceAttributeName = None, type = 'string', converter = NOOP_CONVERTER):
627 attributeMapping = AttributeMapping(attributeName, sourceAttributeName, type, converter) 628 self.attributeMappings.append(attributeMapping)
629
630 - def createOSHs(self, sourceElements, OSHVResult = None):
631 oshs = [] 632 for sourceElement in sourceElements: 633 osh = self.createOSH(sourceElement) 634 oshs.append(osh) 635 636 if OSHVResult: 637 for osh in oshs: 638 OSHVResult.add(osh) 639 640 return oshs
641
642 - def fillOSH(self, osh, sourceElement):
643 for attributeMapping in self.attributeMappings: 644 attributeMapping.setAttribute(osh, sourceElement)
645
646 - def createOSH(self, sourceElement):
647 osh = ObjectStateHolder(self.oshName) 648 self.fillOSH(osh, sourceElement) 649 return osh
650
651 -class WmiToOshMapper:
652 """ 653 @deprecated: 654 """
655 - def __init__(self, wmiObjectName, oshName, wmiAgent):
656 self.wmiAgent = wmiAgent 657 self.oshMapping = OshMapping(oshName) 658 self.queryBuilder = WmiQueryBuilder(wmiObjectName)
659
660 - def defineMapping(self, wmiColumnName, oshAttributeName, oshAttributeType = 'string', converter = NOOP_CONVERTER):
661 self.queryBuilder.addQueryElement(wmiColumnName) 662 self.oshMapping.defineMapping(wmiColumnName, oshAttributeName, oshAttributeType, converter)
663
664 - def createOSHs(self):
665 wmiData = self.wmiAgent.getWmiData(self.queryBuilder) 666 return self.oshMapping.createOSHs(wmiData)
667 668
669 -class WmiAgentException(Exception):
670 pass
671
672 -class ConversionException(WmiAgentException):
673 pass
674
675 -class UnmappedValueException(ConversionException):
676 pass
677
678 -class AttributeMappingException(WmiAgentException):
679 pass
680 681 682 Language = shellutils.Language 683 684 LANGUAGES = shellutils.LANGUAGES 685 686 DEFAULT_LANGUAGE = shellutils.DEFAULT_LANGUAGE 687
688 -class LanguageDiscoverer:
689 """ 690 Discoverer determines the language of target system via WMI queries. 691 Currently it implements the same flow as in shellutils. 692 Supports both WMI and shell/wmic clients, however using it for shell is redundant since shellutils already detects language. 693 """
694 - def __init__(self, wmiProvider):
695 self._provider = wmiProvider
696
697 - def getLanguage(self):
698 language = None 699 osInfo = self._getOsInfo() 700 if osInfo: 701 osLanguage = osInfo.OSLanguage 702 language = self._getLanguageByOsLanguage(osLanguage) 703 704 if language is None: 705 codeSet = osInfo.CodeSet 706 language = self._getLanguageByCodeSet(codeSet) 707 708 if language is None: 709 logger.debug("Failed to determine target operating system language, falling back to default language") 710 language = DEFAULT_LANGUAGE 711 712 logger.debug('Bundle postfix %s' % language.bundlePostfix) 713 return language
714
715 - def _getOsInfo(self):
716 queryBuilder = self._provider.getBuilder('Win32_OperatingSystem') 717 queryBuilder.addWmiObjectProperties('CodeSet', 'OSLanguage') 718 agent = self._provider.getAgent() 719 results = agent.getWmiData(queryBuilder) 720 if results is not None and len(results) == 1: 721 return results[0] 722 else: 723 logger.warn("Query for OS language details has failed")
724
725 - def _getLanguageByOsLanguage(self, osLanguage):
726 if osLanguage and osLanguage.isdigit(): 727 try: 728 intOsLanguage = int(osLanguage) 729 for lang in LANGUAGES: 730 if intOsLanguage in lang.wmiCodes: 731 return lang 732 except: 733 pass
734
735 - def _getLanguageByCodeSet(self, codeSet):
736 if codeSet and codeSet.isdigit(): 737 try: 738 intCodeSet = int(codeSet) 739 for lang in LANGUAGES: 740 if intCodeSet == lang.codepage: 741 return lang 742 except: 743 pass
744