2014-05-04 19:57:32 +00:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
|
|
|
# Import Python libs
|
2014-11-21 19:05:13 +00:00
|
|
|
from __future__ import absolute_import
|
2014-05-04 19:57:32 +00:00
|
|
|
import os
|
2014-05-09 03:10:15 +00:00
|
|
|
from imp import find_module
|
2014-05-04 19:57:32 +00:00
|
|
|
|
|
|
|
# Import Salt Testing libs
|
2015-01-26 21:12:35 +00:00
|
|
|
from salttesting import skipIf
|
2014-05-04 19:57:32 +00:00
|
|
|
from salttesting.helpers import ensure_in_syspath
|
2014-05-08 22:44:56 +00:00
|
|
|
from salttesting.mock import patch, Mock, NO_MOCK, NO_MOCK_REASON
|
2014-05-04 19:57:32 +00:00
|
|
|
|
2014-06-01 05:55:52 +00:00
|
|
|
ensure_in_syspath('../../')
|
2014-05-04 19:57:32 +00:00
|
|
|
|
|
|
|
# Import Salt libs
|
|
|
|
import salt.loader
|
|
|
|
import salt.config
|
2014-07-08 16:16:05 +00:00
|
|
|
import salt.utils
|
2015-04-09 23:04:17 +00:00
|
|
|
from integration import TMP, ModuleCase
|
2015-04-26 09:51:28 +00:00
|
|
|
from salt.utils.odict import OrderedDict
|
2015-01-26 21:12:35 +00:00
|
|
|
|
|
|
|
import copy
|
2014-05-04 19:57:32 +00:00
|
|
|
|
2014-06-10 02:25:14 +00:00
|
|
|
GPG_KEYDIR = os.path.join(TMP, 'gpg-keydir')
|
2014-06-10 00:22:17 +00:00
|
|
|
|
|
|
|
# The keyring library uses `getcwd()`, let's make sure we in a good directory
|
|
|
|
# before importing keyring
|
|
|
|
if not os.path.isdir(GPG_KEYDIR):
|
|
|
|
os.makedirs(GPG_KEYDIR)
|
|
|
|
|
|
|
|
os.chdir(GPG_KEYDIR)
|
|
|
|
|
2014-05-09 11:45:07 +00:00
|
|
|
ENCRYPTED_STRING = '''
|
2014-05-04 19:57:32 +00:00
|
|
|
-----BEGIN PGP MESSAGE-----
|
|
|
|
I AM SO SECRET!
|
|
|
|
-----END PGP MESSAGE-----
|
2014-05-09 11:45:07 +00:00
|
|
|
'''
|
|
|
|
DECRYPTED_STRING = 'I am not a secret anymore'
|
2014-05-08 22:44:56 +00:00
|
|
|
SKIP = False
|
2014-05-04 19:57:32 +00:00
|
|
|
|
2014-05-08 22:44:56 +00:00
|
|
|
try:
|
2014-05-09 03:10:15 +00:00
|
|
|
find_module('gnupg')
|
|
|
|
except ImportError:
|
2014-05-08 22:44:56 +00:00
|
|
|
SKIP = True
|
2014-05-04 19:57:32 +00:00
|
|
|
|
2014-07-08 16:16:05 +00:00
|
|
|
if salt.utils.which('gpg') is None:
|
|
|
|
SKIP = True
|
|
|
|
|
2014-05-08 22:44:56 +00:00
|
|
|
|
|
|
|
@skipIf(NO_MOCK, NO_MOCK_REASON)
|
|
|
|
@skipIf(SKIP, "GPG must be installed")
|
2015-01-26 21:12:35 +00:00
|
|
|
class GPGTestCase(ModuleCase):
|
2014-05-04 19:57:32 +00:00
|
|
|
|
|
|
|
def setUp(self):
|
2015-01-26 21:12:35 +00:00
|
|
|
opts = dict(copy.copy(self.minion_opts))
|
|
|
|
opts['state_events'] = False
|
|
|
|
opts['id'] = 'whatever'
|
|
|
|
opts['file_client'] = 'local'
|
|
|
|
opts['file_roots'] = dict(base=['/tmp'])
|
|
|
|
opts['cachedir'] = 'cachedir'
|
|
|
|
opts['test'] = False
|
|
|
|
opts['grains'] = salt.loader.grains(opts)
|
|
|
|
opts['gpg_keydir'] = GPG_KEYDIR
|
|
|
|
opts['gpg_keydir'] = opts['gpg_keydir']
|
|
|
|
|
|
|
|
self.opts = opts
|
|
|
|
|
|
|
|
self.funcs = salt.loader.minion_mods(self.opts)
|
|
|
|
self.render = salt.loader.render(self.opts, self.funcs)['gpg']
|
2014-05-04 19:57:32 +00:00
|
|
|
|
|
|
|
def render_sls(self, data, sls='', env='base', **kws):
|
2015-01-26 21:12:35 +00:00
|
|
|
return self.render(
|
2014-05-04 19:57:32 +00:00
|
|
|
data, env=env, sls=sls, **kws
|
|
|
|
)
|
|
|
|
|
2014-05-08 22:44:56 +00:00
|
|
|
def make_decryption_mock(self):
|
2014-05-04 19:57:32 +00:00
|
|
|
decrypted_data_mock = Mock()
|
|
|
|
decrypted_data_mock.ok = True
|
|
|
|
decrypted_data_mock.__str__ = lambda x: DECRYPTED_STRING
|
2014-05-08 22:44:56 +00:00
|
|
|
return decrypted_data_mock
|
2014-05-04 19:57:32 +00:00
|
|
|
|
|
|
|
def make_nested_object(self, s):
|
|
|
|
return OrderedDict([
|
2014-05-08 22:44:56 +00:00
|
|
|
('array_key', [1, False, s]),
|
2014-05-09 11:45:07 +00:00
|
|
|
('string_key', 'A Normal String'),
|
2014-05-04 19:57:32 +00:00
|
|
|
('dict_key', {1: None}),
|
|
|
|
])
|
|
|
|
|
|
|
|
@patch('gnupg.GPG')
|
|
|
|
def test_homedir_is_passed_to_gpg(self, gpg_mock):
|
|
|
|
self.render_sls({})
|
2015-01-26 21:12:35 +00:00
|
|
|
gpg_mock.assert_called_with(gnupghome=self.opts['gpg_keydir'])
|
2014-05-04 19:57:32 +00:00
|
|
|
|
|
|
|
def test_normal_string_is_unchanged(self):
|
|
|
|
s = 'I am just another string'
|
|
|
|
new_s = self.render_sls(s)
|
|
|
|
self.assertEqual(s, new_s)
|
|
|
|
|
2014-05-08 22:44:56 +00:00
|
|
|
def test_encrypted_string_is_decrypted(self):
|
|
|
|
with patch('gnupg.GPG.decrypt', return_value=self.make_decryption_mock()):
|
|
|
|
new_s = self.render_sls(ENCRYPTED_STRING)
|
2014-05-04 19:57:32 +00:00
|
|
|
self.assertEqual(new_s, DECRYPTED_STRING)
|
|
|
|
|
2014-05-08 22:44:56 +00:00
|
|
|
def test_encrypted_string_is_unchanged_when_gpg_fails(self):
|
|
|
|
d_mock = self.make_decryption_mock()
|
|
|
|
d_mock.ok = False
|
|
|
|
with patch('gnupg.GPG.decrypt', return_value=d_mock):
|
|
|
|
new_s = self.render_sls(ENCRYPTED_STRING)
|
2014-05-04 19:57:32 +00:00
|
|
|
self.assertEqual(new_s, ENCRYPTED_STRING)
|
|
|
|
|
2014-05-08 22:44:56 +00:00
|
|
|
def test_nested_object_is_decrypted(self):
|
2014-05-04 19:57:32 +00:00
|
|
|
encrypted_o = self.make_nested_object(ENCRYPTED_STRING)
|
|
|
|
decrypted_o = self.make_nested_object(DECRYPTED_STRING)
|
2014-05-08 22:44:56 +00:00
|
|
|
with patch('gnupg.GPG.decrypt', return_value=self.make_decryption_mock()):
|
|
|
|
new_o = self.render_sls(encrypted_o)
|
2014-05-04 19:57:32 +00:00
|
|
|
self.assertEqual(new_o, decrypted_o)
|
2014-05-08 22:44:56 +00:00
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
from integration import run_tests
|
|
|
|
run_tests(GPGTestCase, needs_daemon=False)
|