PageRenderTime 34ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/salt/runners/nacl.py

https://gitlab.com/ricardo.hernandez/salt
Python | 140 lines | 114 code | 6 blank | 20 comment | 3 complexity | 630f5bac399b4292a9996c79daf46e76 MD5 | raw file
  1. # -*- coding: utf-8 -*-
  2. '''
  3. This runner helps create encrypted passwords that can be included in pillars.
  4. :depends: libnacl, https://github.com/saltstack/libnacl
  5. This is often useful if you wish to store your pillars in source control or
  6. share your pillar data with others that you trust. I don't advise making your pillars public
  7. regardless if they are encrypted or not.
  8. The following configurations can be defined in the master config
  9. so your users can create encrypted passwords using the runner nacl:
  10. .. code-block:: bash
  11. cat /etc/salt/master.d/nacl.conf
  12. nacl.config:
  13. key: 'cKEzd4kXsbeCE7/nLTIqXwnUiD1ulg4NoeeYcCFpd9k='
  14. keyfile: /root/.nacl
  15. Now with the config in the master you can use the runner nacl like:
  16. .. code-block:: bash
  17. salt-run nacl.enc 'data'
  18. '''
  19. from __future__ import absolute_import
  20. import base64
  21. import os
  22. import salt.utils
  23. import salt.syspaths
  24. REQ_ERROR = None
  25. try:
  26. import libnacl.secret
  27. except ImportError as e:
  28. REQ_ERROR = 'libnacl import error, perhaps missing python libnacl package'
  29. __virtualname__ = 'nacl'
  30. def __virtual__():
  31. return (REQ_ERROR is None, REQ_ERROR)
  32. def _get_config(**kwargs):
  33. '''
  34. Return configuration
  35. '''
  36. config = {
  37. 'key': None,
  38. 'keyfile': None,
  39. }
  40. config_key = '{0}.config'.format(__virtualname__)
  41. config.update(__opts__.get(config_key, {}))
  42. for k in set(config.keys()) & set(kwargs.keys()):
  43. config[k] = kwargs[k]
  44. return config
  45. def _get_key(rstrip_newline=True, **kwargs):
  46. '''
  47. Return key
  48. '''
  49. config = _get_config(**kwargs)
  50. key = config['key']
  51. keyfile = config['keyfile']
  52. if not key and keyfile:
  53. if not os.path.isfile(keyfile):
  54. raise Exception('file not found: {0}'.format(keyfile))
  55. with salt.utils.fopen(keyfile, 'rb') as keyf:
  56. key = keyf.read()
  57. if key is None:
  58. raise Exception('no key found')
  59. key = str(key)
  60. if rstrip_newline:
  61. key = key.rstrip('\n')
  62. return key
  63. def keygen(keyfile=None):
  64. '''
  65. Use libnacl to generate a private key
  66. CLI Examples:
  67. .. code-block:: bash
  68. salt-run nacl.keygen
  69. salt-run nacl.keygen keyfile=/root/.nacl
  70. salt-run --out=newline_values_only nacl.keygen > /root/.nacl
  71. '''
  72. b = libnacl.secret.SecretBox()
  73. key = b.sk
  74. key = base64.b64encode(key)
  75. if keyfile:
  76. if os.path.isfile(keyfile):
  77. raise Exception('file already found: {0}'.format(keyfile))
  78. with salt.utils.fopen(keyfile, 'w') as keyf:
  79. keyf.write(key)
  80. return 'saved: {0}'.format(keyfile)
  81. return key
  82. def enc(data, **kwargs):
  83. '''
  84. Takes a key generated from `nacl.keygen` and encrypt some data.
  85. CLI Examples:
  86. .. code-block:: bash
  87. salt-run nacl.enc datatoenc
  88. salt-run nacl.enc datatoenc keyfile=/root/.nacl
  89. salt-run nacl.enc datatoenc key='cKEzd4kXsbeCE7/nLTIqXwnUiD1ulg4NoeeYcCFpd9k='
  90. '''
  91. key = _get_key(**kwargs)
  92. sk = base64.b64decode(key)
  93. b = libnacl.secret.SecretBox(sk)
  94. return base64.b64encode(b.encrypt(data))
  95. def dec(data, **kwargs):
  96. '''
  97. Takes a key generated from `nacl.keygen` and decrypt some data.
  98. CLI Examples:
  99. .. code-block:: bash
  100. salt-run nacl.dec pEXHQM6cuaF7A=
  101. salt-run nacl.dec data='pEXHQM6cuaF7A=' keyfile=/root/.nacl
  102. salt-run nacl.dec data='pEXHQM6cuaF7A=' key='cKEzd4kXsbeCE7/nLTIqXwnUiD1ulg4NoeeYcCFpd9k='
  103. '''
  104. key = _get_key(**kwargs)
  105. sk = base64.b64decode(key)
  106. b = libnacl.secret.SecretBox(key=sk)
  107. return b.decrypt(base64.b64decode(data))