Always print invalid configuration data (#21972)

* Always print invalide configuration data

* Print offending data as yaml

* Revert "Print offending data as yaml"

This reverts commit 01721a21a9ff918ed2c8595151ebfe55eb2f7d36.

* Do not print sensitive data

* Print MQTT topic

* Add line break

* Review comments

* review comments
This commit is contained in:
Erik Montnemery 2019-04-29 22:45:53 +02:00 committed by Paulus Schoutsen
parent 4c4f0e38d4
commit 8d775caaac
2 changed files with 59 additions and 21 deletions

View file

@ -210,6 +210,12 @@ def clear_discovery_hash(hass, discovery_hash):
del hass.data[ALREADY_DISCOVERED][discovery_hash] del hass.data[ALREADY_DISCOVERED][discovery_hash]
class MQTTConfig(dict):
"""Dummy class to allow adding attributes."""
pass
async def async_start(hass: HomeAssistantType, discovery_topic, hass_config, async def async_start(hass: HomeAssistantType, discovery_topic, hass_config,
config_entry=None) -> bool: config_entry=None) -> bool:
"""Initialize of MQTT Discovery.""" """Initialize of MQTT Discovery."""
@ -236,7 +242,7 @@ async def async_start(hass: HomeAssistantType, discovery_topic, hass_config,
object_id, payload) object_id, payload)
return return
payload = dict(payload) payload = MQTTConfig(payload)
for key in list(payload.keys()): for key in list(payload.keys()):
abbreviated_key = key abbreviated_key = key
@ -264,6 +270,10 @@ async def async_start(hass: HomeAssistantType, discovery_topic, hass_config,
discovery_hash = (component, discovery_id) discovery_hash = (component, discovery_id)
if payload: if payload:
# Attach MQTT topic to the payload, used for debug prints
setattr(payload, '__configuration_source__',
"MQTT (topic: '{}')".format(topic))
if CONF_PLATFORM in payload and 'schema' not in payload: if CONF_PLATFORM in payload and 'schema' not in payload:
platform = payload[CONF_PLATFORM] platform = payload[CONF_PLATFORM]
if (component in DEPRECATED_PLATFORM_TO_SCHEMA and if (component in DEPRECATED_PLATFORM_TO_SCHEMA and

View file

@ -1,5 +1,6 @@
"""Helpers for config validation using voluptuous.""" """Helpers for config validation using voluptuous."""
import inspect import inspect
import json
import logging import logging
import os import os
import re import re
@ -15,11 +16,11 @@ from pkg_resources import parse_version
import homeassistant.util.dt as dt_util import homeassistant.util.dt as dt_util
from homeassistant.const import ( from homeassistant.const import (
CONF_PLATFORM, CONF_SCAN_INTERVAL, TEMP_CELSIUS, TEMP_FAHRENHEIT, CONF_ABOVE, CONF_ALIAS, CONF_BELOW, CONF_CONDITION, CONF_ENTITY_ID,
CONF_ALIAS, CONF_ENTITY_ID, CONF_VALUE_TEMPLATE, WEEKDAYS, CONF_ENTITY_NAMESPACE, CONF_NAME, CONF_PLATFORM, CONF_SCAN_INTERVAL,
CONF_CONDITION, CONF_BELOW, CONF_ABOVE, CONF_TIMEOUT, SUN_EVENT_SUNSET, CONF_UNIT_SYSTEM_IMPERIAL, CONF_UNIT_SYSTEM_METRIC, CONF_VALUE_TEMPLATE,
SUN_EVENT_SUNRISE, CONF_UNIT_SYSTEM_IMPERIAL, CONF_UNIT_SYSTEM_METRIC, CONF_TIMEOUT, ENTITY_MATCH_ALL, SUN_EVENT_SUNRISE, SUN_EVENT_SUNSET,
ENTITY_MATCH_ALL, CONF_ENTITY_NAMESPACE, __version__) TEMP_CELSIUS, TEMP_FAHRENHEIT, WEEKDAYS, __version__)
from homeassistant.core import valid_entity_id, split_entity_id from homeassistant.core import valid_entity_id, split_entity_id
from homeassistant.exceptions import TemplateError from homeassistant.exceptions import TemplateError
from homeassistant.helpers import template as template_helper from homeassistant.helpers import template as template_helper
@ -677,26 +678,53 @@ class HASchema(vol.Schema):
self.extra = vol.PREVENT_EXTRA self.extra = vol.PREVENT_EXTRA
# This is a legacy config, print warning # This is a legacy config, print warning
extra_key_errs = [err for err in orig_err.errors extra_key_errs = [err.path[-1] for err in orig_err.errors
if err.error_message == 'extra keys not allowed'] if err.error_message == 'extra keys not allowed']
if extra_key_errs:
msg = "Your configuration contains extra keys " \ if not extra_key_errs:
"that the platform does not support.\n" \
"Please remove "
submsg = ', '.join('[{}]'.format(err.path[-1]) for err in
extra_key_errs)
submsg += '. '
if hasattr(data, '__config_file__'):
submsg += " (See {}, line {}). ".format(
data.__config_file__, data.__line__)
msg += submsg
logging.getLogger(__name__).warning(msg)
INVALID_EXTRA_KEYS_FOUND.append(submsg)
else:
# This should not happen (all errors should be extra key # This should not happen (all errors should be extra key
# errors). Let's raise the original error anyway. # errors). Let's raise the original error anyway.
raise orig_err raise orig_err
WHITELIST = [
re.compile(CONF_NAME),
re.compile(CONF_PLATFORM),
re.compile('.*_topic'),
]
msg = "Your configuration contains extra keys " \
"that the platform does not support.\n" \
"Please remove "
submsg = ', '.join('[{}]'.format(err) for err in
extra_key_errs)
submsg += '. '
# Add file+line information, if available
if hasattr(data, '__config_file__'):
submsg += " (See {}, line {}). ".format(
data.__config_file__, data.__line__)
# Add configuration source information, if available
if hasattr(data, '__configuration_source__'):
submsg += "\nConfiguration source: {}. ".format(
data.__configuration_source__)
redacted_data = {}
# Print configuration causing the error, but filter any potentially
# sensitive data
for k, v in data.items():
if (any(regex.match(k) for regex in WHITELIST) or
k in extra_key_errs):
redacted_data[k] = v
else:
redacted_data[k] = '<redacted>'
submsg += "\nOffending data: {}".format(
json.dumps(redacted_data))
msg += submsg
logging.getLogger(__name__).warning(msg)
INVALID_EXTRA_KEYS_FOUND.append(submsg)
# Return legacy validated config # Return legacy validated config
return validated return validated