Merge pull request #39932 from rallytime/cp-beacon-fixes

Cherry-pick the beacon fixes made in #39930 to 2016.11
This commit is contained in:
Mike Place 2017-03-09 17:21:08 -07:00 committed by GitHub
commit 899e037f0a
4 changed files with 165 additions and 174 deletions

View File

@ -60,18 +60,19 @@ def beacon(config):
if _name not in procs:
procs.append(_name)
for process in config:
ret_dict = {}
if config[process] == 'running':
if process not in procs:
ret_dict[process] = 'Stopped'
ret.append(ret_dict)
elif config[process] == 'stopped':
if process in procs:
ret_dict[process] = 'Running'
ret.append(ret_dict)
else:
if process not in procs:
ret_dict[process] = False
ret.append(ret_dict)
for entry in config:
for process in entry:
ret_dict = {}
if entry[process] == 'running':
if process not in procs:
ret_dict[process] = 'Stopped'
ret.append(ret_dict)
elif entry[process] == 'stopped':
if process in procs:
ret_dict[process] = 'Running'
ret.append(ret_dict)
else:
if process not in procs:
ret_dict[process] = False
ret.append(ret_dict)
return ret

View File

@ -117,34 +117,43 @@ def beacon(config):
ctime = datetime.datetime.utcnow().isoformat()
if len(config) < 1:
config = {
config = [{
'loadavg': ['all'],
'cpustats': ['all'],
'meminfo': ['all'],
'vmstats': ['all'],
'time': ['all'],
}
}]
if not isinstance(config, list):
# To support the old dictionary config format
config = [config]
ret = {}
for func in config:
try:
data = __salt__['status.{0}'.format(func)]()
except salt.exceptions.CommandExecutionError as exc:
log.debug('Status beacon attempted to process function {0} \
but encountered error: {1}'.format(func, exc))
continue
ret[func] = {}
for item in config[func]:
if item == 'all':
ret[func] = data
for entry in config:
for func in entry:
ret[func] = {}
try:
data = __salt__['status.{0}'.format(func)]()
except salt.exceptions.CommandExecutionError as exc:
log.debug('Status beacon attempted to process function {0} '
'but encountered error: {1}'.format(func, exc))
continue
if not isinstance(entry[func], list):
func_items = [entry[func]]
else:
try:
func_items = entry[func]
for item in func_items:
if item == 'all':
ret[func] = data
else:
try:
ret[func][item] = data[item]
except TypeError:
ret[func][item] = data[int(item)]
except KeyError as exc:
ret[func] = 'Status beacon is incorrectly configured: {0}'.format(exc)
try:
ret[func][item] = data[item]
except TypeError:
ret[func][item] = data[int(item)]
except KeyError as exc:
ret[func] = 'Status beacon is incorrectly configured: {0}'.format(exc)
return [{
'tag': ctime,

View File

@ -11,43 +11,38 @@ import os
from salt.modules import beacons
from salt.exceptions import CommandExecutionError
import integration
import salt.utils
# Salttesting libs
from salttesting import skipIf
from salttesting.helpers import destructiveTest, ensure_in_syspath
ensure_in_syspath('../../')
beacons.__opts__ = {}
BEACON_CONF_DIR = os.path.join(integration.TMP, 'minion.d')
if not os.path.exists(BEACON_CONF_DIR):
os.makedirs(BEACON_CONF_DIR)
IS_ADMIN = False
if salt.utils.is_windows():
import salt.utils.win_functions
current_user = salt.utils.win_functions.get_current_user()
if current_user == 'SYSTEM':
IS_ADMIN = True
else:
IS_ADMIN = salt.utils.win_functions.is_admin(current_user)
else:
IS_ADMIN = os.geteuid() == 0
@skipIf(not IS_ADMIN, 'You must be root to run these tests')
@destructiveTest
class BeaconsAddDeleteTest(integration.ModuleCase):
'''
Tests the add and delete functions
'''
def setUp(self):
self.minion_conf_d_dir = os.path.join(
self.minion_opts['config_dir'],
os.path.dirname(self.minion_opts['default_include']))
if not os.path.isdir(self.minion_conf_d_dir):
os.makedirs(self.minion_conf_d_dir)
self.beacons_config_file_path = os.path.join(self.minion_conf_d_dir, 'beacons.conf')
def tearDown(self):
if os.path.isfile(self.beacons_config_file_path):
os.unlink(self.beacons_config_file_path)
def test_add_and_delete(self):
'''
Test adding and deleting a beacon
'''
_add = self.run_function('beacons.add', ['ps', {'apache2': 'stopped'}])
_add = self.run_function('beacons.add', ['ps', [{'apache2': 'stopped'}]])
self.assertTrue(_add['result'])
# save added beacon
@ -62,16 +57,29 @@ class BeaconsAddDeleteTest(integration.ModuleCase):
self.run_function('beacons.save')
@skipIf(not IS_ADMIN, 'You must be root to run these tests')
@destructiveTest
class BeaconsTest(integration.ModuleCase):
'''
Tests the beacons execution module
'''
beacons_config_file_path = minion_conf_d_dir = None
@classmethod
def tearDownClass(cls):
if os.path.isfile(cls.beacons_config_file_path):
os.unlink(cls.beacons_config_file_path)
def setUp(self):
if self.minion_conf_d_dir is None:
self.minion_conf_d_dir = os.path.join(
self.minion_opts['config_dir'],
os.path.dirname(self.minion_opts['default_include']))
if not os.path.isdir(self.minion_conf_d_dir):
os.makedirs(self.minion_conf_d_dir)
self.__class__.beacons_config_file_path = os.path.join(self.minion_conf_d_dir, 'beacons.conf')
try:
# Add beacon to disable
self.run_function('beacons.add', ['ps', {'apache2': 'stopped'}])
self.run_function('beacons.add', ['ps', [{'apache2': 'stopped'}]])
self.run_function('beacons.save')
except CommandExecutionError:
self.skipTest('Unable to add beacon')
@ -102,7 +110,10 @@ class BeaconsTest(integration.ModuleCase):
# assert beacon ps is disabled
_list = self.run_function('beacons.list', return_yaml=False)
self.assertFalse(_list['ps']['enabled'])
for bdict in _list['ps']:
if 'enabled' in bdict:
self.assertFalse(bdict['enabled'])
break
def test_enable(self):
'''
@ -140,7 +151,7 @@ class BeaconsTest(integration.ModuleCase):
# list beacons
ret = self.run_function('beacons.list', return_yaml=False)
if 'enabled' in ret:
self.assertEqual(ret, {'ps': {'apache2': 'stopped'}, 'enabled': True})
self.assertEqual(ret, {'ps': [{'apache2': 'stopped'}], 'enabled': True})
else:
self.assertEqual(ret, {'ps': {'apache': 'stopped'}})

View File

@ -11,8 +11,7 @@ from salt.beacons import inotify
# Salt testing libs
from salttesting import skipIf, TestCase
from salttesting.helpers import destructiveTest, ensure_in_syspath
from salttesting.mock import NO_MOCK, NO_MOCK_REASON
from salttesting.helpers import ensure_in_syspath
# Third-party libs
try:
@ -26,20 +25,23 @@ ensure_in_syspath('../../')
@skipIf(not HAS_PYINOTIFY, 'pyinotify is not available')
@skipIf(NO_MOCK, NO_MOCK_REASON)
class INotifyBeaconTestCase(TestCase):
'''
Test case for salt.beacons.inotify
'''
def setUp(self):
inotify.__context__ = {}
self.tmpdir = tempfile.mkdtemp()
def test_empty_config(self, *args, **kwargs):
def tearDown(self):
shutil.rmtree(self.tmpdir, ignore_errors=True)
def test_empty_config(self):
config = {}
ret = inotify.beacon(config)
self.assertEqual(ret, [])
def test_file_open(self, *args, **kwargs):
def test_file_open(self):
path = os.path.realpath(__file__)
config = {path: {'mask': ['open']}}
ret = inotify.beacon(config)
@ -52,122 +54,90 @@ class INotifyBeaconTestCase(TestCase):
self.assertEqual(ret[0]['path'], path)
self.assertEqual(ret[0]['change'], 'IN_OPEN')
@destructiveTest
def test_dir_no_auto_add(self, *args, **kwargs):
tmpdir = None
try:
tmpdir = tempfile.mkdtemp()
config = {tmpdir: {'mask': ['create']}}
ret = inotify.beacon(config)
self.assertEqual(ret, [])
fp = os.path.join(tmpdir, 'tmpfile')
with open(fp, 'w') as f:
pass
ret = inotify.beacon(config)
self.assertEqual(len(ret), 1)
self.assertEqual(ret[0]['path'], fp)
self.assertEqual(ret[0]['change'], 'IN_CREATE')
with open(fp, 'r') as f:
pass
ret = inotify.beacon(config)
self.assertEqual(ret, [])
def test_dir_no_auto_add(self):
config = {self.tmpdir: {'mask': ['create']}}
ret = inotify.beacon(config)
self.assertEqual(ret, [])
fp = os.path.join(self.tmpdir, 'tmpfile')
with open(fp, 'w') as f:
pass
ret = inotify.beacon(config)
self.assertEqual(len(ret), 1)
self.assertEqual(ret[0]['path'], fp)
self.assertEqual(ret[0]['change'], 'IN_CREATE')
with open(fp, 'r') as f:
pass
ret = inotify.beacon(config)
self.assertEqual(ret, [])
finally:
if tmpdir:
shutil.rmtree(tmpdir)
def test_dir_auto_add(self):
config = {self.tmpdir: {'mask': ['create', 'open'], 'auto_add': True}}
ret = inotify.beacon(config)
self.assertEqual(ret, [])
fp = os.path.join(self.tmpdir, 'tmpfile')
with open(fp, 'w') as f:
pass
ret = inotify.beacon(config)
self.assertEqual(len(ret), 2)
self.assertEqual(ret[0]['path'], fp)
self.assertEqual(ret[0]['change'], 'IN_CREATE')
self.assertEqual(ret[1]['path'], fp)
self.assertEqual(ret[1]['change'], 'IN_OPEN')
with open(fp, 'r') as f:
pass
ret = inotify.beacon(config)
self.assertEqual(len(ret), 1)
self.assertEqual(ret[0]['path'], fp)
self.assertEqual(ret[0]['change'], 'IN_OPEN')
@destructiveTest
def test_dir_auto_add(self, *args, **kwargs):
tmpdir = None
try:
tmpdir = tempfile.mkdtemp()
config = {tmpdir: {'mask': ['create', 'open'], 'auto_add': True}}
ret = inotify.beacon(config)
self.assertEqual(ret, [])
fp = os.path.join(tmpdir, 'tmpfile')
with open(fp, 'w') as f:
pass
ret = inotify.beacon(config)
self.assertEqual(len(ret), 2)
self.assertEqual(ret[0]['path'], fp)
self.assertEqual(ret[0]['change'], 'IN_CREATE')
self.assertEqual(ret[1]['path'], fp)
self.assertEqual(ret[1]['change'], 'IN_OPEN')
with open(fp, 'r') as f:
pass
ret = inotify.beacon(config)
self.assertEqual(len(ret), 1)
self.assertEqual(ret[0]['path'], fp)
self.assertEqual(ret[0]['change'], 'IN_OPEN')
def test_dir_recurse(self):
dp1 = os.path.join(self.tmpdir, 'subdir1')
os.mkdir(dp1)
dp2 = os.path.join(dp1, 'subdir2')
os.mkdir(dp2)
fp = os.path.join(dp2, 'tmpfile')
with open(fp, 'w') as f:
pass
config = {self.tmpdir: {'mask': ['open'], 'recurse': True}}
ret = inotify.beacon(config)
self.assertEqual(ret, [])
with open(fp) as f:
pass
ret = inotify.beacon(config)
self.assertEqual(len(ret), 3)
self.assertEqual(ret[0]['path'], dp1)
self.assertEqual(ret[0]['change'], 'IN_OPEN|IN_ISDIR')
self.assertEqual(ret[1]['path'], dp2)
self.assertEqual(ret[1]['change'], 'IN_OPEN|IN_ISDIR')
self.assertEqual(ret[2]['path'], fp)
self.assertEqual(ret[2]['change'], 'IN_OPEN')
finally:
if tmpdir:
shutil.rmtree(tmpdir)
@destructiveTest
def test_dir_recurse(self, *args, **kwargs):
tmpdir = None
try:
tmpdir = tempfile.mkdtemp()
dp1 = os.path.join(tmpdir, 'subdir1')
os.mkdir(dp1)
dp2 = os.path.join(dp1, 'subdir2')
os.mkdir(dp2)
fp = os.path.join(dp2, 'tmpfile')
with open(fp, 'w') as f:
pass
config = {tmpdir: {'mask': ['open'], 'recurse': True}}
ret = inotify.beacon(config)
self.assertEqual(ret, [])
with open(fp) as f:
pass
ret = inotify.beacon(config)
self.assertEqual(len(ret), 3)
self.assertEqual(ret[0]['path'], dp1)
self.assertEqual(ret[0]['change'], 'IN_OPEN|IN_ISDIR')
self.assertEqual(ret[1]['path'], dp2)
self.assertEqual(ret[1]['change'], 'IN_OPEN|IN_ISDIR')
self.assertEqual(ret[2]['path'], fp)
self.assertEqual(ret[2]['change'], 'IN_OPEN')
finally:
if tmpdir:
shutil.rmtree(tmpdir)
@destructiveTest
def test_dir_recurse_auto_add(self, *args, **kwargs):
tmpdir = None
try:
tmpdir = tempfile.mkdtemp()
dp1 = os.path.join(tmpdir, 'subdir1')
os.mkdir(dp1)
config = {tmpdir: {'mask': ['create', 'delete'],
'recurse': True,
'auto_add': True}}
ret = inotify.beacon(config)
self.assertEqual(ret, [])
dp2 = os.path.join(dp1, 'subdir2')
os.mkdir(dp2)
ret = inotify.beacon(config)
self.assertEqual(len(ret), 1)
self.assertEqual(ret[0]['path'], dp2)
self.assertEqual(ret[0]['change'], 'IN_CREATE|IN_ISDIR')
fp = os.path.join(dp2, 'tmpfile')
with open(fp, 'w') as f:
pass
ret = inotify.beacon(config)
self.assertEqual(len(ret), 1)
self.assertEqual(ret[0]['path'], fp)
self.assertEqual(ret[0]['change'], 'IN_CREATE')
os.remove(fp)
ret = inotify.beacon(config)
self.assertEqual(len(ret), 1)
self.assertEqual(ret[0]['path'], fp)
self.assertEqual(ret[0]['change'], 'IN_DELETE')
finally:
if tmpdir:
shutil.rmtree(tmpdir)
def test_dir_recurse_auto_add(self):
dp1 = os.path.join(self.tmpdir, 'subdir1')
os.mkdir(dp1)
config = {self.tmpdir: {'mask': ['create', 'delete'],
'recurse': True,
'auto_add': True}}
ret = inotify.beacon(config)
self.assertEqual(ret, [])
dp2 = os.path.join(dp1, 'subdir2')
os.mkdir(dp2)
ret = inotify.beacon(config)
self.assertEqual(len(ret), 1)
self.assertEqual(ret[0]['path'], dp2)
self.assertEqual(ret[0]['change'], 'IN_CREATE|IN_ISDIR')
fp = os.path.join(dp2, 'tmpfile')
with open(fp, 'w') as f:
pass
ret = inotify.beacon(config)
self.assertEqual(len(ret), 1)
self.assertEqual(ret[0]['path'], fp)
self.assertEqual(ret[0]['change'], 'IN_CREATE')
os.remove(fp)
ret = inotify.beacon(config)
self.assertEqual(len(ret), 1)
self.assertEqual(ret[0]['path'], fp)
self.assertEqual(ret[0]['change'], 'IN_DELETE')
if __name__ == '__main__':