mirror of
https://github.com/home-assistant/core.git
synced 2025-07-22 20:57:21 +00:00
Splunk component filter support (#25071)
* Added code to support entity and domain filters in the config for splunk component, and the code to enforce the filter. * * Moved code for posting splunk request to separate function, primarily to more easily write a test case where I can mock the point where the post would occur and validate that filtering is working correctly. * Test cases created for full config check and to test the filtering * Correcting static check errors/issues * Correcting flake8 static check issue (introduced when addressing prior static check issues) * Removing unused parameter to setup function - cleanup from reviewer request.
This commit is contained in:
parent
f7aa1b026f
commit
f705a1e62e
@ -11,10 +11,12 @@ from homeassistant.const import (
|
|||||||
CONF_PORT, CONF_TOKEN, EVENT_STATE_CHANGED)
|
CONF_PORT, CONF_TOKEN, EVENT_STATE_CHANGED)
|
||||||
from homeassistant.helpers import state as state_helper
|
from homeassistant.helpers import state as state_helper
|
||||||
import homeassistant.helpers.config_validation as cv
|
import homeassistant.helpers.config_validation as cv
|
||||||
|
from homeassistant.helpers.entityfilter import FILTER_SCHEMA
|
||||||
from homeassistant.helpers.json import JSONEncoder
|
from homeassistant.helpers.json import JSONEncoder
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
CONF_FILTER = 'filter'
|
||||||
DOMAIN = 'splunk'
|
DOMAIN = 'splunk'
|
||||||
|
|
||||||
DEFAULT_HOST = 'localhost'
|
DEFAULT_HOST = 'localhost'
|
||||||
@ -30,10 +32,26 @@ CONFIG_SCHEMA = vol.Schema({
|
|||||||
vol.Optional(CONF_SSL, default=False): cv.boolean,
|
vol.Optional(CONF_SSL, default=False): cv.boolean,
|
||||||
vol.Optional(CONF_VERIFY_SSL, default=True): cv.boolean,
|
vol.Optional(CONF_VERIFY_SSL, default=True): cv.boolean,
|
||||||
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
|
vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string,
|
||||||
|
vol.Optional(CONF_FILTER, default={}): FILTER_SCHEMA,
|
||||||
}),
|
}),
|
||||||
}, extra=vol.ALLOW_EXTRA)
|
}, 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):
|
def setup(hass, config):
|
||||||
"""Set up the Splunk component."""
|
"""Set up the Splunk component."""
|
||||||
conf = config[DOMAIN]
|
conf = config[DOMAIN]
|
||||||
@ -43,6 +61,7 @@ def setup(hass, config):
|
|||||||
use_ssl = conf.get(CONF_SSL)
|
use_ssl = conf.get(CONF_SSL)
|
||||||
verify_ssl = conf.get(CONF_VERIFY_SSL)
|
verify_ssl = conf.get(CONF_VERIFY_SSL)
|
||||||
name = conf.get(CONF_NAME)
|
name = conf.get(CONF_NAME)
|
||||||
|
entity_filter = conf[CONF_FILTER]
|
||||||
|
|
||||||
if use_ssl:
|
if use_ssl:
|
||||||
uri_scheme = 'https://'
|
uri_scheme = 'https://'
|
||||||
@ -57,7 +76,7 @@ def setup(hass, config):
|
|||||||
"""Listen for new messages on the bus and sends them to Splunk."""
|
"""Listen for new messages on the bus and sends them to Splunk."""
|
||||||
state = event.data.get('new_state')
|
state = event.data.get('new_state')
|
||||||
|
|
||||||
if state is None:
|
if state is None or not entity_filter(state.entity_id):
|
||||||
return
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -76,16 +95,7 @@ def setup(hass, config):
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
try:
|
post_request(event_collector, json_body, headers, verify_ssl)
|
||||||
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)
|
|
||||||
|
|
||||||
hass.bus.listen(EVENT_STATE_CHANGED, splunk_event_listener)
|
hass.bus.listen(EVENT_STATE_CHANGED, splunk_event_listener)
|
||||||
|
|
||||||
|
@ -8,8 +8,12 @@ import homeassistant.components.splunk as splunk
|
|||||||
from homeassistant.const import STATE_ON, STATE_OFF, EVENT_STATE_CHANGED
|
from homeassistant.const import STATE_ON, STATE_OFF, EVENT_STATE_CHANGED
|
||||||
from homeassistant.helpers import state as state_helper
|
from homeassistant.helpers import state as state_helper
|
||||||
import homeassistant.util.dt as dt_util
|
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):
|
class TestSplunk(unittest.TestCase):
|
||||||
@ -33,6 +37,14 @@ class TestSplunk(unittest.TestCase):
|
|||||||
'ssl': 'False',
|
'ssl': 'False',
|
||||||
'verify_ssl': 'True',
|
'verify_ssl': 'True',
|
||||||
'name': 'hostname',
|
'name': 'hostname',
|
||||||
|
'filter': {
|
||||||
|
'exclude_domains': [
|
||||||
|
'fake'
|
||||||
|
],
|
||||||
|
'exclude_entities': [
|
||||||
|
'fake.entity'
|
||||||
|
],
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,3 +132,54 @@ class TestSplunk(unittest.TestCase):
|
|||||||
headers={'Authorization': 'Splunk secret'},
|
headers={'Authorization': 'Splunk secret'},
|
||||||
timeout=10, verify=True)
|
timeout=10, verify=True)
|
||||||
self.mock_post.reset_mock()
|
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()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user