diff --git a/homeassistant/components/splunk/__init__.py b/homeassistant/components/splunk/__init__.py index fed05fe3498..30b4245b8e9 100644 --- a/homeassistant/components/splunk/__init__.py +++ b/homeassistant/components/splunk/__init__.py @@ -11,10 +11,12 @@ from homeassistant.const import ( CONF_PORT, CONF_TOKEN, EVENT_STATE_CHANGED) from homeassistant.helpers import state as state_helper import homeassistant.helpers.config_validation as cv +from homeassistant.helpers.entityfilter import FILTER_SCHEMA from homeassistant.helpers.json import JSONEncoder _LOGGER = logging.getLogger(__name__) +CONF_FILTER = 'filter' DOMAIN = 'splunk' DEFAULT_HOST = 'localhost' @@ -30,10 +32,26 @@ CONFIG_SCHEMA = vol.Schema({ vol.Optional(CONF_SSL, default=False): cv.boolean, vol.Optional(CONF_VERIFY_SSL, default=True): cv.boolean, vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, + vol.Optional(CONF_FILTER, default={}): FILTER_SCHEMA, }), }, extra=vol.ALLOW_EXTRA) +def post_request(event_collector, body, headers, verify_ssl): + """Post request to Splunk.""" + try: + payload = { + "host": event_collector, + "event": body, + } + requests.post(event_collector, + data=json.dumps(payload, cls=JSONEncoder), + headers=headers, timeout=10, verify=verify_ssl) + + except requests.exceptions.RequestException as error: + _LOGGER.exception("Error saving event to Splunk: %s", error) + + def setup(hass, config): """Set up the Splunk component.""" conf = config[DOMAIN] @@ -43,6 +61,7 @@ def setup(hass, config): use_ssl = conf.get(CONF_SSL) verify_ssl = conf.get(CONF_VERIFY_SSL) name = conf.get(CONF_NAME) + entity_filter = conf[CONF_FILTER] if use_ssl: uri_scheme = 'https://' @@ -57,7 +76,7 @@ def setup(hass, config): """Listen for new messages on the bus and sends them to Splunk.""" state = event.data.get('new_state') - if state is None: + if state is None or not entity_filter(state.entity_id): return try: @@ -76,16 +95,7 @@ def setup(hass, config): } ] - try: - payload = { - "host": event_collector, - "event": json_body, - } - requests.post(event_collector, - data=json.dumps(payload, cls=JSONEncoder), - headers=headers, timeout=10, verify=verify_ssl) - except requests.exceptions.RequestException as error: - _LOGGER.exception("Error saving event to Splunk: %s", error) + post_request(event_collector, json_body, headers, verify_ssl) hass.bus.listen(EVENT_STATE_CHANGED, splunk_event_listener) diff --git a/tests/components/splunk/test_init.py b/tests/components/splunk/test_init.py index f3cefb9c2d9..a3496c0df36 100644 --- a/tests/components/splunk/test_init.py +++ b/tests/components/splunk/test_init.py @@ -8,8 +8,12 @@ import homeassistant.components.splunk as splunk from homeassistant.const import STATE_ON, STATE_OFF, EVENT_STATE_CHANGED from homeassistant.helpers import state as state_helper import homeassistant.util.dt as dt_util +from homeassistant.core import State -from tests.common import get_test_home_assistant +from tests.common import ( + get_test_home_assistant, + mock_state_change_event +) class TestSplunk(unittest.TestCase): @@ -33,6 +37,14 @@ class TestSplunk(unittest.TestCase): 'ssl': 'False', 'verify_ssl': 'True', 'name': 'hostname', + 'filter': { + 'exclude_domains': [ + 'fake' + ], + 'exclude_entities': [ + 'fake.entity' + ], + } } } @@ -120,3 +132,54 @@ class TestSplunk(unittest.TestCase): headers={'Authorization': 'Splunk secret'}, timeout=10, verify=True) self.mock_post.reset_mock() + + def _setup_with_filter(self): + """Test the setup.""" + config = { + 'splunk': { + 'host': 'host', + 'token': 'secret', + 'port': 8088, + 'filter': { + 'exclude_domains': [ + 'excluded_domain' + ], + 'exclude_entities': [ + 'other_domain.excluded_entity' + ] + } + } + } + + setup_component(self.hass, splunk.DOMAIN, config) + + @mock.patch.object(splunk, 'post_request') + def test_splunk_entityfilter(self, mock_requests): + """Test event listener.""" + self._setup_with_filter() + + testdata = [ + { + 'entity_id': 'other_domain.other_entity', + 'filter_expected': False + }, + { + 'entity_id': 'other_domain.excluded_entity', + 'filter_expected': True + }, + { + 'entity_id': 'excluded_domain.other_entity', + 'filter_expected': True + } + ] + + for test in testdata: + mock_state_change_event(self.hass, State(test['entity_id'], 'on')) + self.hass.block_till_done() + + if test['filter_expected']: + assert not splunk.post_request.called + else: + assert splunk.post_request.called + + splunk.post_request.reset_mock()