diff --git a/changelog/66809.added.md b/changelog/66809.added.md new file mode 100644 index 000000000000..1f4d2cbcb869 --- /dev/null +++ b/changelog/66809.added.md @@ -0,0 +1 @@ +Added support in service Beacon for only fire matching configured running state diff --git a/salt/beacons/service.py b/salt/beacons/service.py index 6f7519e8f953..9454022b3996 100644 --- a/salt/beacons/service.py +++ b/salt/beacons/service.py @@ -76,6 +76,11 @@ def beacon(config): event when the minion is reload. Applicable only when `onchangeonly` is True. The default is True. + `is_running_state`: If `is_running_state` is set to a boolean the beacon will only + fire if the running state matches the given value. If its set to `True`, only + when a service running state is `True` it will be fired, if it's set to `False` + then only the beacon will fire when the running state is `False`. + `uncleanshutdown`: If `uncleanshutdown` is present it should point to the location of a pid file for the service. Most services will not clean up this pid file if they are shutdown uncleanly (e.g. via `kill -9`) or if they @@ -141,6 +146,15 @@ def beacon(config): ret_dict[service]["uncleanshutdown"] = ( True if os.path.exists(filename) else False ) + + # If is_running_state does not match the current running state, skip it + if ( + "is_running_state" in service_config + and isinstance(service_config["is_running_state"], bool) + and service_config["is_running_state"] != ret_dict[service]["running"] + ): + continue + if "onchangeonly" in service_config and service_config["onchangeonly"] is True: if service not in LAST_STATUS: LAST_STATUS[service] = ret_dict[service] diff --git a/tests/pytests/unit/beacons/test_service.py b/tests/pytests/unit/beacons/test_service.py index c066ee62d919..de0bd3bf828b 100644 --- a/tests/pytests/unit/beacons/test_service.py +++ b/tests/pytests/unit/beacons/test_service.py @@ -195,3 +195,37 @@ def test_service_not_running(): "salt-master": {"running": False}, } ] + + +def test_service_matching_is_running_state(): + with patch.dict( + service_beacon.__salt__, {"service.status": MagicMock(return_value=False)} + ): + config = [{"services": {"salt-master": {"is_running_state": True}}}] + + ret = service_beacon.validate(config) + + assert ret == (True, "Valid beacon configuration") + + ret = service_beacon.beacon(config) + + assert ret == [] + + config = [ + { + "services": { + "salt-master": {"is_running_state": False}, + "salt-minion": {"is_running_state": True}, + } + } + ] + + ret = service_beacon.beacon(config) + + assert ret == [ + { + "service_name": "salt-master", + "tag": "salt-master", + "salt-master": {"running": False}, + } + ]