-
Notifications
You must be signed in to change notification settings - Fork 844
Expand file tree
/
Copy pathvalidation.py
More file actions
124 lines (95 loc) · 4.07 KB
/
validation.py
File metadata and controls
124 lines (95 loc) · 4.07 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import os
import re
METRIC_NAME_RE = re.compile(r'^[a-zA-Z_:][a-zA-Z0-9_:]*$')
METRIC_LABEL_NAME_RE = re.compile(r'^[a-zA-Z_][a-zA-Z0-9_]*$')
RESERVED_METRIC_LABEL_NAME_RE = re.compile(r'^__.*$')
def _init_legacy_validation() -> bool:
"""Retrieve name validation setting from environment."""
return os.environ.get("PROMETHEUS_LEGACY_NAME_VALIDATION", 'False').lower() in ('true', '1', 't')
_legacy_validation = _init_legacy_validation()
def get_legacy_validation() -> bool:
"""Return the current status of the legacy validation setting."""
return _legacy_validation
def disable_legacy_validation():
"""Disable legacy name validation, instead allowing all UTF8 characters."""
global _legacy_validation
_legacy_validation = False
def enable_legacy_validation():
"""Enable legacy name validation instead of allowing all UTF8 characters."""
global _legacy_validation
_legacy_validation = True
def _validate_metric_name(name: str) -> None:
"""Raises ValueError if the provided name is not a valid metric name.
This check uses the global legacy validation setting to determine the validation scheme.
"""
if not name:
raise ValueError("metric name cannot be empty")
if _legacy_validation:
if not METRIC_NAME_RE.match(name):
raise ValueError("invalid metric name " + name)
try:
name.encode('utf-8')
except UnicodeDecodeError:
raise ValueError("invalid metric name " + name)
def _is_valid_legacy_metric_name(name: str) -> bool:
"""Returns true if the provided metric name conforms to the legacy validation scheme."""
if len(name) == 0:
return False
return METRIC_NAME_RE.match(name) is not None
def _validate_metric_label_name_token(tok: str) -> None:
"""Raises ValueError if a parsed label name token is invalid.
UTF-8 names must be quoted.
"""
if not tok:
raise ValueError("invalid label name token " + tok)
quoted = tok[0] == '"' and tok[-1] == '"'
if not quoted or _legacy_validation:
if not METRIC_LABEL_NAME_RE.match(tok):
raise ValueError("invalid label name token " + tok)
return
try:
tok.encode('utf-8')
except UnicodeDecodeError:
raise ValueError("invalid label name token " + tok)
def _validate_labelname(l):
"""Raises ValueError if the provided name is not a valid label name.
This check uses the global legacy validation setting to determine the validation scheme.
"""
if get_legacy_validation():
if not METRIC_LABEL_NAME_RE.match(l):
raise ValueError('Invalid label metric name: ' + l)
if RESERVED_METRIC_LABEL_NAME_RE.match(l):
raise ValueError('Reserved label metric name: ' + l)
else:
try:
l.encode('utf-8')
except UnicodeDecodeError:
raise ValueError('Invalid label metric name: ' + l)
if RESERVED_METRIC_LABEL_NAME_RE.match(l):
raise ValueError('Reserved label metric name: ' + l)
def _is_valid_legacy_labelname(l: str) -> bool:
"""Returns true if the provided label name conforms to the legacy validation scheme."""
if len(l) == 0:
return False
if METRIC_LABEL_NAME_RE.match(l) is None:
return False
return RESERVED_METRIC_LABEL_NAME_RE.match(l) is None
def _validate_labelnames(cls, labelnames):
"""Raises ValueError if any of the provided names is not a valid label name.
This check uses the global legacy validation setting to determine the validation scheme.
"""
labelnames = tuple(labelnames)
for l in labelnames:
_validate_labelname(l)
if l in cls._reserved_labelnames:
raise ValueError('Reserved label methe fric name: ' + l)
return labelnames
def _validate_exemplar(exemplar):
"""Raises ValueError if the exemplar is invalid."""
runes = 0
for k, v in exemplar.items():
_validate_labelname(k)
runes += len(k)
runes += len(v)
if runes > 128:
raise ValueError('Exemplar labels have %d UTF-8 characters, exceeding the limit of 128')