|
Lines 1-116
Link Here
|
| 1 |
diff --git a/salt/config.py b/salt/config.py |
|
|
| 2 |
index 071e06b..1f83c33 100644 |
| 3 |
--- salt/config.py.orig |
| 4 |
+++ salt/config.py |
| 5 |
@@ -63,7 +63,7 @@ |
| 6 |
|
| 7 |
VALID_OPTS = { |
| 8 |
# The address of the salt master. May be specified as IP address or hostname |
| 9 |
- 'master': str, |
| 10 |
+ 'master': (str, list), |
| 11 |
|
| 12 |
# The TCP/UDP port of the master to connect to in order to listen to publications |
| 13 |
'master_port': int, |
| 14 |
@@ -541,7 +541,7 @@ |
| 15 |
'file_recv': bool, |
| 16 |
'file_recv_max_size': int, |
| 17 |
'file_ignore_regex': list, |
| 18 |
- 'file_ignore_glob': bool, |
| 19 |
+ 'file_ignore_glob': list, |
| 20 |
'fileserver_backend': list, |
| 21 |
'fileserver_followsymlinks': bool, |
| 22 |
'fileserver_ignoresymlinks': bool, |
| 23 |
@@ -833,7 +833,7 @@ |
| 24 |
'file_recv': False, |
| 25 |
'file_recv_max_size': 100, |
| 26 |
'file_ignore_regex': [], |
| 27 |
- 'file_ignore_glob': None, |
| 28 |
+ 'file_ignore_glob': [], |
| 29 |
'fileserver_backend': ['roots'], |
| 30 |
'fileserver_followsymlinks': True, |
| 31 |
'fileserver_ignoresymlinks': False, |
| 32 |
@@ -1348,26 +1348,30 @@ def _validate_opts(opts): |
| 33 |
Check that all of the types of values passed into the config are |
| 34 |
of the right types |
| 35 |
''' |
| 36 |
+ def format_multi_opt(valid_type): |
| 37 |
+ try: |
| 38 |
+ num_types = len(valid_type) |
| 39 |
+ except TypeError: |
| 40 |
+ # Bare type name won't have a length, return the name of the type |
| 41 |
+ # passed. |
| 42 |
+ return valid_type.__name__ |
| 43 |
+ else: |
| 44 |
+ if num_types == 1: |
| 45 |
+ return valid_type.__name__ |
| 46 |
+ elif num_types > 1: |
| 47 |
+ ret = ', '.join(x.__name__ for x in valid_type[:-1]) |
| 48 |
+ ret += ' or ' + valid_type[-1].__name__ |
| 49 |
+ |
| 50 |
errors = [] |
| 51 |
- err = ('Key {0} with value {1} has an invalid type of {2}, a {3} is ' |
| 52 |
+ |
| 53 |
+ err = ('Key \'{0}\' with value {1} has an invalid type of {2}, a {3} is ' |
| 54 |
'required for this value') |
| 55 |
for key, val in six.iteritems(opts): |
| 56 |
if key in VALID_OPTS: |
| 57 |
- if isinstance(VALID_OPTS[key](), list): |
| 58 |
- if isinstance(val, VALID_OPTS[key]): |
| 59 |
- continue |
| 60 |
- else: |
| 61 |
- errors.append( |
| 62 |
- err.format(key, val, type(val).__name__, 'list') |
| 63 |
- ) |
| 64 |
- if isinstance(VALID_OPTS[key](), dict): |
| 65 |
- if isinstance(val, VALID_OPTS[key]): |
| 66 |
- continue |
| 67 |
- else: |
| 68 |
- errors.append( |
| 69 |
- err.format(key, val, type(val).__name__, 'dict') |
| 70 |
- ) |
| 71 |
- else: |
| 72 |
+ if isinstance(val, VALID_OPTS[key]): |
| 73 |
+ continue |
| 74 |
+ |
| 75 |
+ if hasattr(VALID_OPTS[key], '__call__'): |
| 76 |
try: |
| 77 |
VALID_OPTS[key](val) |
| 78 |
if isinstance(val, (list, dict)): |
| 79 |
@@ -1384,14 +1388,21 @@ def _validate_opts(opts): |
| 80 |
VALID_OPTS[key].__name__ |
| 81 |
) |
| 82 |
) |
| 83 |
- except ValueError: |
| 84 |
+ except (TypeError, ValueError): |
| 85 |
errors.append( |
| 86 |
- err.format(key, val, type(val).__name__, VALID_OPTS[key]) |
| 87 |
- ) |
| 88 |
- except TypeError: |
| 89 |
- errors.append( |
| 90 |
- err.format(key, val, type(val).__name__, VALID_OPTS[key]) |
| 91 |
+ err.format(key, |
| 92 |
+ val, |
| 93 |
+ type(val).__name__, |
| 94 |
+ VALID_OPTS[key].__name__) |
| 95 |
) |
| 96 |
+ continue |
| 97 |
+ |
| 98 |
+ errors.append( |
| 99 |
+ err.format(key, |
| 100 |
+ val, |
| 101 |
+ type(val).__name__, |
| 102 |
+ format_multi_opt(VALID_OPTS[key].__name__)) |
| 103 |
+ ) |
| 104 |
|
| 105 |
# RAET on Windows uses 'win32file.CreateMailslot()' for IPC. Due to this, |
| 106 |
# sock_dirs must start with '\\.\mailslot\' and not contain any colons. |
| 107 |
@@ -1404,7 +1415,7 @@ def _validate_opts(opts): |
| 108 |
'\\\\.\\mailslot\\' + opts['sock_dir'].replace(':', '')) |
| 109 |
|
| 110 |
for error in errors: |
| 111 |
- log.warning(error) |
| 112 |
+ log.debug(error) |
| 113 |
if errors: |
| 114 |
return False |
| 115 |
return True |
| 116 |
|