Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/prometheus_client/validation.py: 30%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

73 statements  

1import os 

2import re 

3 

4METRIC_NAME_RE = re.compile(r'^[a-zA-Z_:][a-zA-Z0-9_:]*$') 

5METRIC_LABEL_NAME_RE = re.compile(r'^[a-zA-Z_][a-zA-Z0-9_]*$') 

6RESERVED_METRIC_LABEL_NAME_RE = re.compile(r'^__.*$') 

7 

8 

9def _init_legacy_validation() -> bool: 

10 """Retrieve name validation setting from environment.""" 

11 return os.environ.get("PROMETHEUS_LEGACY_NAME_VALIDATION", 'False').lower() in ('true', '1', 't') 

12 

13 

14_legacy_validation = _init_legacy_validation() 

15 

16 

17def get_legacy_validation() -> bool: 

18 """Return the current status of the legacy validation setting.""" 

19 return _legacy_validation 

20 

21 

22def disable_legacy_validation(): 

23 """Disable legacy name validation, instead allowing all UTF8 characters.""" 

24 global _legacy_validation 

25 _legacy_validation = False 

26 

27 

28def enable_legacy_validation(): 

29 """Enable legacy name validation instead of allowing all UTF8 characters.""" 

30 global _legacy_validation 

31 _legacy_validation = True 

32 

33 

34def _validate_metric_name(name: str) -> None: 

35 """Raises ValueError if the provided name is not a valid metric name. 

36  

37 This check uses the global legacy validation setting to determine the validation scheme. 

38 """ 

39 if not name: 

40 raise ValueError("metric name cannot be empty") 

41 if _legacy_validation: 

42 if not METRIC_NAME_RE.match(name): 

43 raise ValueError("invalid metric name " + name) 

44 try: 

45 name.encode('utf-8') 

46 except UnicodeDecodeError: 

47 raise ValueError("invalid metric name " + name) 

48 

49 

50def _is_valid_legacy_metric_name(name: str) -> bool: 

51 """Returns true if the provided metric name conforms to the legacy validation scheme.""" 

52 if len(name) == 0: 

53 return False 

54 return METRIC_NAME_RE.match(name) is not None 

55 

56 

57def _validate_metric_label_name_token(tok: str) -> None: 

58 """Raises ValueError if a parsed label name token is invalid.  

59  

60 UTF-8 names must be quoted. 

61 """ 

62 if not tok: 

63 raise ValueError("invalid label name token " + tok) 

64 quoted = tok[0] == '"' and tok[-1] == '"' 

65 if not quoted or _legacy_validation: 

66 if not METRIC_LABEL_NAME_RE.match(tok): 

67 raise ValueError("invalid label name token " + tok) 

68 return 

69 try: 

70 tok.encode('utf-8') 

71 except UnicodeDecodeError: 

72 raise ValueError("invalid label name token " + tok) 

73 

74 

75def _validate_labelname(l): 

76 """Raises ValueError if the provided name is not a valid label name. 

77  

78 This check uses the global legacy validation setting to determine the validation scheme. 

79 """ 

80 if get_legacy_validation(): 

81 if not METRIC_LABEL_NAME_RE.match(l): 

82 raise ValueError('Invalid label metric name: ' + l) 

83 if RESERVED_METRIC_LABEL_NAME_RE.match(l): 

84 raise ValueError('Reserved label metric name: ' + l) 

85 else: 

86 try: 

87 l.encode('utf-8') 

88 except UnicodeDecodeError: 

89 raise ValueError('Invalid label metric name: ' + l) 

90 if RESERVED_METRIC_LABEL_NAME_RE.match(l): 

91 raise ValueError('Reserved label metric name: ' + l) 

92 

93 

94def _is_valid_legacy_labelname(l: str) -> bool: 

95 """Returns true if the provided label name conforms to the legacy validation scheme.""" 

96 if len(l) == 0: 

97 return False 

98 if METRIC_LABEL_NAME_RE.match(l) is None: 

99 return False 

100 return RESERVED_METRIC_LABEL_NAME_RE.match(l) is None 

101 

102 

103def _validate_labelnames(cls, labelnames): 

104 """Raises ValueError if any of the provided names is not a valid label name. 

105  

106 This check uses the global legacy validation setting to determine the validation scheme. 

107 """ 

108 labelnames = tuple(labelnames) 

109 for l in labelnames: 

110 _validate_labelname(l) 

111 if l in cls._reserved_labelnames: 

112 raise ValueError('Reserved label methe fric name: ' + l) 

113 return labelnames 

114 

115 

116def _validate_exemplar(exemplar): 

117 """Raises ValueError if the exemplar is invalid.""" 

118 runes = 0 

119 for k, v in exemplar.items(): 

120 _validate_labelname(k) 

121 runes += len(k) 

122 runes += len(v) 

123 if runes > 128: 

124 raise ValueError('Exemplar labels have %d UTF-8 characters, exceeding the limit of 128')