PageRenderTime 47ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/salt/states/mysql_query.py

https://github.com/vitaliyf/salt
Python | 180 lines | 162 code | 0 blank | 18 comment | 0 complexity | 40dc1a41078a1560a96a298d7e8abce8 MD5 | raw file
Possible License(s): Apache-2.0
  1. # -*- coding: utf-8 -*-
  2. '''
  3. Execution of MySQL queries
  4. ==========================
  5. .. versionadded:: Helium
  6. :depends: - MySQLdb Python module
  7. :configuration: See :py:mod:`salt.modules.mysql` for setup instructions.
  8. The mysql_query module is used to execute queries on MySQL databases.
  9. Its output may be stored in a file or in a grain.
  10. .. code-block:: yaml
  11. query_id:
  12. mysql_query.run
  13. - database: my_database
  14. - query: "SELECT * FROM table;"
  15. - output: "/tmp/query_id.txt"
  16. '''
  17. import sys
  18. import os.path
  19. def __virtual__():
  20. '''
  21. Only load if the mysql module is available in __salt__
  22. '''
  23. return 'mysql.query' in __salt__
  24. def _get_mysql_error():
  25. '''
  26. Look in module context for a MySQL error. Eventually we should make a less
  27. ugly way of doing this.
  28. '''
  29. return sys.modules[
  30. __salt__['test.ping'].__module__
  31. ].__context__.pop('mysql.error', None)
  32. def run(name,
  33. database,
  34. query,
  35. output=None,
  36. grain=None,
  37. key=None,
  38. overwrite=True,
  39. **connection_args):
  40. '''
  41. Execute an arbitrary query on the specified database
  42. name
  43. Used only as an ID
  44. database
  45. The name of the database to execute the query on
  46. query
  47. The query to execute
  48. output
  49. grain: output in a grain
  50. other: the file to store results
  51. None: output to the result comment (default)
  52. grain:
  53. grain to store the output (need output=grain)
  54. key:
  55. the specified grain will be treated as a dictionnary, the result
  56. of this state will be stored under the specified key.
  57. overwrite:
  58. The file or grain will be overwritten if it already exists (default)
  59. '''
  60. ret = {'name': name,
  61. 'changes': {},
  62. 'result': True,
  63. 'comment': 'Database {0} is already present'.format(name)}
  64. # check if database exists
  65. if not __salt__['mysql.db_exists'](database, **connection_args):
  66. err = _get_mysql_error()
  67. if err is not None:
  68. ret['comment'] = err
  69. ret['result'] = False
  70. return ret
  71. ret['result'] = None
  72. ret['comment'] = ('Database {0} is not present'
  73. ).format(name)
  74. return ret
  75. # Check if execution needed
  76. if output == 'grain':
  77. if grain is not None and key is None:
  78. if not overwrite and grain in __salt__['grains.ls']():
  79. ret['comment'] = 'No execution needed. Grain ' + grain\
  80. + ' already set'
  81. return ret
  82. elif __opts__['test']:
  83. ret['result'] = None
  84. ret['comment'] = 'Query would execute, storing result in '\
  85. + 'grain: ' + grain
  86. return ret
  87. elif grain is not None:
  88. if grain in __salt__['grains.ls']():
  89. grain_value = __salt__['grains.get'](grain)
  90. else:
  91. grain_value = {}
  92. if not overwrite and key in grain_value:
  93. ret['comment'] = 'No execution needed. Grain ' + grain\
  94. + ':' + key + ' already set'
  95. return ret
  96. elif __opts__['test']:
  97. ret['result'] = None
  98. ret['comment'] = 'Query would execute, storing result in '\
  99. + 'grain: ' + grain + ':' + key
  100. return ret
  101. else:
  102. ret['result'] = False
  103. ret['comment'] = "Error: output type 'grain' needs the grain "\
  104. + "parameter\n"
  105. return ret
  106. elif output is not None:
  107. if not overwrite and os.path.isfile(output):
  108. ret['comment'] = 'No execution needed. File ' + output\
  109. + ' already set'
  110. return ret
  111. elif __opts__['test']:
  112. ret['result'] = None
  113. ret['comment'] = 'Query would execute, storing result in '\
  114. + 'file: ' + output
  115. return ret
  116. elif __opts__['test']:
  117. ret['result'] = None
  118. ret['comment'] = 'Query would execute, not storing result'
  119. # The database is present, execute the query
  120. query_result = __salt__['mysql.query'](database, query, **connection_args)
  121. mapped_results = []
  122. if 'results' in query_result:
  123. for res in query_result['results']:
  124. mapped_line = {}
  125. for idx, col in enumerate(query_result['columns']):
  126. mapped_line[col] = res[idx]
  127. mapped_results.append(mapped_line)
  128. query_result['results'] = mapped_results
  129. ret['comment'] = query_result
  130. if output == 'grain':
  131. if grain is not None and key is None:
  132. __salt__['grains.setval'](grain, query_result)
  133. ret['changes']['query'] = "Executed. Output into grain: "\
  134. + grain
  135. elif grain is not None:
  136. if grain in __salt__['grains.ls']():
  137. grain_value = __salt__['grains.get'](grain)
  138. else:
  139. grain_value = {}
  140. grain_value[key] = query_result
  141. __salt__['grains.setval'](grain, grain_value)
  142. ret['changes']['query'] = "Executed. Output into grain: "\
  143. + grain + ":" + key
  144. elif output is not None:
  145. ret['changes']['query'] = "Executed. Output into " + output
  146. with open(output, 'w') as output_file:
  147. if 'results' in query_result:
  148. for res in query_result['results']:
  149. for col, val in res:
  150. output_file.write(col + ':' + val + '\n')
  151. else:
  152. output_file.write(str(query_result))
  153. else:
  154. ret['changes']['query'] = "Executed"
  155. return ret