test_linux_acl.py 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  1. # -*- coding: utf-8 -*-
  2. '''
  3. :codeauthor: Jayesh Kariya <jayeshk@saltstack.com>
  4. '''
  5. # Import Python libs
  6. from __future__ import absolute_import, unicode_literals, print_function
  7. import sys
  8. # Import Salt Testing Libs
  9. from tests.support.mixins import LoaderModuleMockMixin
  10. from tests.support.unit import skipIf, TestCase
  11. from tests.support.mock import (
  12. MagicMock,
  13. patch)
  14. # Import Salt Libs
  15. import salt.states.linux_acl as linux_acl
  16. from salt.exceptions import CommandExecutionError
  17. @skipIf(not sys.platform.startswith('linux'), 'Test for Linux only')
  18. class LinuxAclTestCase(TestCase, LoaderModuleMockMixin):
  19. '''
  20. Test cases for salt.states.linux_acl
  21. '''
  22. def setup_loader_modules(self):
  23. return {linux_acl: {}}
  24. # 'present' function tests: 1
  25. def test_present(self):
  26. '''
  27. Test to ensure a Linux ACL is present
  28. '''
  29. self.maxDiff = None
  30. name = '/root'
  31. acl_type = 'users'
  32. acl_name = 'damian'
  33. perms = 'rwx'
  34. mock = MagicMock(side_effect=[{name: {acl_type: [{acl_name:
  35. {'octal': 5}}]}},
  36. {name: {acl_type: [{acl_name:
  37. {'octal': 5}}]}},
  38. {name: {acl_type: [{acl_name:
  39. {'octal': 5}}]}},
  40. {name: {acl_type: [{}]}},
  41. {name: {acl_type: [{}]}},
  42. {name: {acl_type: [{}]}},
  43. {
  44. name: {acl_type: [{acl_name: {'octal': 7}}]},
  45. name+"/foo": {acl_type: [{acl_name: {'octal': 5}}]}
  46. },
  47. {
  48. name: {acl_type: [{acl_name: {'octal': 7}}]},
  49. name+"/foo": {acl_type: [{acl_name: {'octal': 7}}]}
  50. },
  51. {name: {acl_type: ''}}])
  52. mock_modfacl = MagicMock(return_value=True)
  53. with patch.dict(linux_acl.__salt__, {'acl.getfacl': mock}):
  54. # Update - test=True
  55. with patch.dict(linux_acl.__opts__, {'test': True}):
  56. comt = ('Updated permissions will be applied for {0}: r-x -> {1}'
  57. ''.format(acl_name, perms))
  58. ret = {'name': name,
  59. 'comment': comt,
  60. 'changes': {'new': {'acl_name': acl_name,
  61. 'acl_type': acl_type,
  62. 'perms': perms},
  63. 'old': {'acl_name': acl_name,
  64. 'acl_type': acl_type,
  65. 'perms': 'r-x'}},
  66. 'result': None}
  67. self.assertDictEqual(linux_acl.present(name, acl_type, acl_name,
  68. perms), ret)
  69. # Update - test=False
  70. with patch.dict(linux_acl.__salt__, {'acl.modfacl': mock_modfacl}):
  71. with patch.dict(linux_acl.__opts__, {'test': False}):
  72. comt = ('Updated permissions for {0}'.format(acl_name))
  73. ret = {'name': name,
  74. 'comment': comt,
  75. 'changes': {'new': {'acl_name': acl_name,
  76. 'acl_type': acl_type,
  77. 'perms': perms},
  78. 'old': {'acl_name': acl_name,
  79. 'acl_type': acl_type,
  80. 'perms': 'r-x'}},
  81. 'result': True}
  82. self.assertDictEqual(linux_acl.present(name, acl_type,
  83. acl_name, perms),
  84. ret)
  85. # Update - modfacl error
  86. with patch.dict(linux_acl.__salt__, {'acl.modfacl': MagicMock(
  87. side_effect=CommandExecutionError('Custom err'))}):
  88. with patch.dict(linux_acl.__opts__, {'test': False}):
  89. comt = ('Error updating permissions for {0}: Custom err'
  90. ''.format(acl_name))
  91. ret = {'name': name,
  92. 'comment': comt,
  93. 'changes': {},
  94. 'result': False}
  95. self.assertDictEqual(linux_acl.present(name, acl_type,
  96. acl_name, perms),
  97. ret)
  98. # New - test=True
  99. with patch.dict(linux_acl.__salt__, {'acl.modfacl': mock_modfacl}):
  100. with patch.dict(linux_acl.__opts__, {'test': True}):
  101. comt = ('New permissions will be applied '
  102. 'for {0}: {1}'.format(acl_name, perms))
  103. ret = {'name': name,
  104. 'comment': comt,
  105. 'changes': {'new': {'acl_name': acl_name,
  106. 'acl_type': acl_type,
  107. 'perms': perms}},
  108. 'result': None}
  109. self.assertDictEqual(linux_acl.present(name, acl_type,
  110. acl_name, perms),
  111. ret)
  112. # New - test=False
  113. with patch.dict(linux_acl.__salt__, {'acl.modfacl': mock_modfacl}):
  114. with patch.dict(linux_acl.__opts__, {'test': False}):
  115. comt = ('Applied new permissions for {0}'.format(acl_name))
  116. ret = {'name': name,
  117. 'comment': comt,
  118. 'changes': {'new': {'acl_name': acl_name,
  119. 'acl_type': acl_type,
  120. 'perms': perms}},
  121. 'result': True}
  122. self.assertDictEqual(linux_acl.present(name, acl_type,
  123. acl_name, perms),
  124. ret)
  125. # New - modfacl error
  126. with patch.dict(linux_acl.__salt__, {'acl.modfacl': MagicMock(
  127. side_effect=CommandExecutionError('Custom err'))}):
  128. with patch.dict(linux_acl.__opts__, {'test': False}):
  129. comt = ('Error updating permissions for {0}: Custom err'
  130. ''.format(acl_name))
  131. ret = {'name': name,
  132. 'comment': comt,
  133. 'changes': {},
  134. 'result': False}
  135. self.assertDictEqual(linux_acl.present(name, acl_type,
  136. acl_name, perms),
  137. ret)
  138. # New - recurse true
  139. with patch.dict(linux_acl.__salt__, {'acl.getfacl': mock}):
  140. # Update - test=True
  141. with patch.dict(linux_acl.__opts__, {'test': True}):
  142. comt = ('Updated permissions will be applied for {0}: rwx -> {1}'
  143. ''.format(acl_name, perms))
  144. ret = {'name': name,
  145. 'comment': comt,
  146. 'changes': {'new': {'acl_name': acl_name,
  147. 'acl_type': acl_type,
  148. 'perms': perms},
  149. 'old': {'acl_name': acl_name,
  150. 'acl_type': acl_type,
  151. 'perms': 'rwx'}},
  152. 'result': None}
  153. self.assertDictEqual(linux_acl.present(name, acl_type, acl_name,
  154. perms, recurse=False), ret)
  155. # New - recurse true - nothing to do
  156. with patch.dict(linux_acl.__salt__, {'acl.getfacl': mock}):
  157. # Update - test=True
  158. with patch.dict(linux_acl.__opts__, {'test': True}):
  159. comt = ('Permissions are in the desired state')
  160. ret = {'name': name,
  161. 'comment': comt,
  162. 'changes': {},
  163. 'result': True}
  164. self.assertDictEqual(linux_acl.present(name, acl_type, acl_name,
  165. perms, recurse=True), ret)
  166. # No acl type
  167. comt = ('ACL Type does not exist')
  168. ret = {'name': name, 'comment': comt, 'result': False, 'changes': {}}
  169. self.assertDictEqual(linux_acl.present(name, acl_type, acl_name,
  170. perms), ret)
  171. # 'absent' function tests: 2
  172. def test_absent(self):
  173. '''
  174. Test to ensure a Linux ACL does not exist
  175. '''
  176. name = '/root'
  177. acl_type = 'users'
  178. acl_name = 'damian'
  179. perms = 'rwx'
  180. ret = {'name': name,
  181. 'result': None,
  182. 'comment': '',
  183. 'changes': {}}
  184. mock = MagicMock(side_effect=[{name: {acl_type: [{acl_name: {'octal': 'A'}}]}},
  185. {name: {acl_type: ''}}])
  186. with patch.dict(linux_acl.__salt__, {'acl.getfacl': mock}):
  187. with patch.dict(linux_acl.__opts__, {'test': True}):
  188. comt = ('Removing permissions')
  189. ret.update({'comment': comt})
  190. self.assertDictEqual(linux_acl.absent(name, acl_type, acl_name, perms), ret)
  191. comt = ('ACL Type does not exist')
  192. ret.update({'comment': comt, 'result': False})
  193. self.assertDictEqual(linux_acl.absent(name, acl_type, acl_name, perms), ret)
  194. # 'list_present' function tests: 1
  195. def test_list_present(self):
  196. '''
  197. Test to ensure a Linux ACL is present
  198. '''
  199. self.maxDiff = None
  200. name = '/root'
  201. acl_type = 'user'
  202. acl_names = ['root', 'damian', 'homer']
  203. acl_comment = {u'owner': u'root',
  204. u'group': u'root',
  205. u'file': u'/root'}
  206. perms = 'rwx'
  207. mock = MagicMock(side_effect=[{name: {acl_type: [{acl_names[0]:
  208. {'octal': 'A'}},
  209. {acl_names[1]:
  210. {'octal': 'A'}},
  211. {acl_names[2]:
  212. {'octal': 'A'}}],
  213. 'comment': acl_comment}},
  214. {name: {acl_type: [{acl_names[0]:
  215. {'octal': 'A'}},
  216. {acl_names[1]:
  217. {'octal': 'A'}}],
  218. 'comment': acl_comment}},
  219. {name: {acl_type: [{acl_names[0]:
  220. {'octal': 'A'}},
  221. {acl_names[1]:
  222. {'octal': 'A'}}]}},
  223. {name: {acl_type: [{}]}},
  224. {name: {acl_type: [{}]}},
  225. {name: {acl_type: [{}]}},
  226. {name: {acl_type: ''}}])
  227. mock_modfacl = MagicMock(return_value=True)
  228. with patch.dict(linux_acl.__salt__, {'acl.getfacl': mock}):
  229. # Update - test=True
  230. with patch.dict(linux_acl.__opts__, {'test': True}):
  231. comt = ('Updated permissions will be applied for {0}: A -> {1}'
  232. ''.format(acl_names, perms))
  233. expected = {'name': name,
  234. 'comment': comt,
  235. 'changes': {},
  236. 'pchanges': {'new': {'acl_name': ', '.join(acl_names),
  237. 'acl_type': acl_type,
  238. 'perms': 7},
  239. 'old': {'acl_name': ', '.join(acl_names),
  240. 'acl_type': acl_type,
  241. 'perms': 'A'}},
  242. 'result': None}
  243. ret = linux_acl.list_present(name, acl_type, acl_names, perms)
  244. self.assertDictEqual(ret, expected)
  245. # Update - test=False
  246. with patch.dict(linux_acl.__salt__, {'acl.modfacl': mock_modfacl}):
  247. with patch.dict(linux_acl.__opts__, {'test': False}):
  248. comt = ('Applied new permissions for {0}'.format(', '.join(acl_names)))
  249. expected = {'name': name,
  250. 'comment': comt,
  251. 'changes': {'new': {'acl_name': ', '.join(acl_names),
  252. 'acl_type': acl_type,
  253. 'perms': 'rwx'}},
  254. 'pchanges': {},
  255. 'result': True}
  256. ret = linux_acl.list_present(name, acl_type, acl_names, perms)
  257. self.assertDictEqual(expected, ret)
  258. # Update - modfacl error
  259. with patch.dict(linux_acl.__salt__, {'acl.modfacl': MagicMock(
  260. side_effect=CommandExecutionError('Custom err'))}):
  261. with patch.dict(linux_acl.__opts__, {'test': False}):
  262. comt = ('Error updating permissions for {0}: Custom err'
  263. ''.format(acl_names))
  264. expected = {'name': name,
  265. 'comment': comt,
  266. 'changes': {},
  267. 'pchanges': {},
  268. 'result': False}
  269. ret = linux_acl.list_present(name, acl_type, acl_names, perms)
  270. self.assertDictEqual(expected, ret)
  271. # New - test=True
  272. with patch.dict(linux_acl.__salt__, {'acl.modfacl': mock_modfacl}):
  273. with patch.dict(linux_acl.__opts__, {'test': True}):
  274. comt = ('New permissions will be applied '
  275. 'for {0}: {1}'.format(acl_names, perms))
  276. expected = {'name': name,
  277. 'comment': comt,
  278. 'changes': {},
  279. 'pchanges': {'new': {'acl_name': ', '.join(acl_names),
  280. 'acl_type': acl_type,
  281. 'perms': perms}},
  282. 'result': None}
  283. ret = linux_acl.list_present(name, acl_type, acl_names, perms)
  284. self.assertDictEqual(expected, ret)
  285. # New - test=False
  286. with patch.dict(linux_acl.__salt__, {'acl.modfacl': mock_modfacl}):
  287. with patch.dict(linux_acl.__opts__, {'test': False}):
  288. comt = ('Applied new permissions for {0}'.format(', '.join(acl_names)))
  289. expected = {'name': name,
  290. 'comment': comt,
  291. 'changes': {'new': {'acl_name': ', '.join(acl_names),
  292. 'acl_type': acl_type,
  293. 'perms': perms}},
  294. 'pchanges': {},
  295. 'result': True}
  296. ret = linux_acl.list_present(name, acl_type, acl_names, perms)
  297. self.assertDictEqual(expected, ret)
  298. # New - modfacl error
  299. with patch.dict(linux_acl.__salt__, {'acl.modfacl': MagicMock(
  300. side_effect=CommandExecutionError('Custom err'))}):
  301. with patch.dict(linux_acl.__opts__, {'test': False}):
  302. comt = ('Error updating permissions for {0}: Custom err'
  303. ''.format(acl_names))
  304. expected = {'name': name,
  305. 'comment': comt,
  306. 'changes': {},
  307. 'pchanges': {},
  308. 'result': False}
  309. ret = linux_acl.list_present(name, acl_type, acl_names, perms)
  310. self.assertDictEqual(expected, ret)
  311. # No acl type
  312. comt = ('ACL Type does not exist')
  313. expected = {'name': name, 'comment': comt, 'result': False,
  314. 'changes': {}, 'pchanges': {}}
  315. ret = linux_acl.list_present(name, acl_type, acl_names, perms)
  316. self.assertDictEqual(expected, ret)
  317. # 'list_absent' function tests: 2
  318. def test_list_absent(self):
  319. '''
  320. Test to ensure a Linux ACL does not exist
  321. '''
  322. name = '/root'
  323. acl_type = 'users'
  324. acl_names = ['damian', 'homer']
  325. perms = 'rwx'
  326. ret = {'name': name,
  327. 'result': None,
  328. 'comment': '',
  329. 'changes': {}}
  330. mock = MagicMock(side_effect=[{name: {acl_type: [{acl_names[0]: {'octal': 'A'},
  331. acl_names[1]: {'octal': 'A'}}]}},
  332. {name: {acl_type: ''}}])
  333. with patch.dict(linux_acl.__salt__, {'acl.getfacl': mock}):
  334. with patch.dict(linux_acl.__opts__, {'test': True}):
  335. comt = ('Removing permissions')
  336. ret.update({'comment': comt})
  337. self.assertDictEqual(linux_acl.list_absent(name, acl_type, acl_names, perms), ret)
  338. comt = ('ACL Type does not exist')
  339. ret.update({'comment': comt, 'result': False})
  340. self.assertDictEqual(linux_acl.list_absent(name, acl_type, acl_names), ret)
  341. def test_absent_recursive(self):
  342. '''
  343. Test to ensure a Linux ACL does not exist
  344. '''
  345. name = '/root'
  346. acl_type = 'users'
  347. acl_name = 'damian'
  348. perms = 'rwx'
  349. ret = {'name': name,
  350. 'result': None,
  351. 'comment': '',
  352. 'changes': {}}
  353. mock = MagicMock(side_effect=[
  354. {name: {acl_type: [{acl_name: {'octal': 7}}]}, name+"/foo": {acl_type: [{acl_name: {'octal': 'A'}}]}}
  355. ])
  356. with patch.dict(linux_acl.__salt__, {'acl.getfacl': mock}):
  357. with patch.dict(linux_acl.__opts__, {'test': True}):
  358. comt = ('Removing permissions')
  359. ret.update({'comment': comt})
  360. self.assertDictEqual(linux_acl.absent(name, acl_type, acl_name, perms, recurse=True), ret)